DeepSeek Harness: Bundle and Profile

Last updated: 2026-08-31

A DSH project may need multiple run configurations — one for Web UI development, one for headless deployment, one for CI testing. A Profile is a named assembly scheme; a Bundle is a distributable configuration + code package. Together, they make DSH deployment as simple as switching channels.

💡 Tip: A profile is "which plugins to select"; a bundle is "how to configure them." Profile selects the combination; bundle configures the details. Understand this layering and you've mastered DSH's configuration architecture.

📋 Prerequisites: Completed 12-local-plugin.md, understand cordis.yml configuration

1. What You'll Learn


Bundle Profile

2. profile: Named Assembly

(1) profile Concept

A profile is a preset plugin combination scheme, identified by name:

TEXT 📖 Display only
web profile:       → Includes Web UI plugins, interactive tools
headless profile:  → No UI, pure API + script execution
ci profile:        → Minimal plugin set, only what tests need

(2) Configuring a profile

Declare profiles in package.json:

JSON
{
  "name": "my-dsh-project",
  "dsh": {
    "profiles": {
      "web": {
        "description": "Web UI mode for interactive development",
        "plugins": [
          "@deepseek-ai/dsh-web-app",
          "@deepseek-ai/dsh-plugin-tools-interactive"
        ]
      },
      "headless": {
        "description": "Headless mode for automation",
        "plugins": [
          "@deepseek-ai/dsh-headless",
          "@deepseek-ai/dsh-plugin-tools-basic"
        ]
      }
    }
  }
}

(3) ▶ Example 3

BASH
# Use web profile
pnpm dsh web --profile web

# Use headless profile
pnpm dsh headless --profile headless

(4) profile Composition

Component Description
Plugin list Which plugins to include
Description Profile's purpose
Default config Default parameters for plugins

3. bundle: Configuration + Code Distribution Format

(1) bundle Concept

A bundle is a profile + configuration + code packaging format, distributable like an npm package:

TEXT 📖 Display only
profile:  Which plugins to select
bundle:   Plugins + config + version lock → distributable package

(2) ▶ Example 2

TEXT 📖 Display only
dsh-bundle-my-team/
├── package.json        ← dsh.bundle field
├── cordis.yml          ← Default configuration
├── plugins/
│   ├── team-tools/     ← Built-in plugin
│   └── team-lint/      ← Built-in plugin
└── profiles/
    ├── web.yml         ← web profile config
    └── headless.yml    ← headless profile config

(3) ▶ Example 3

JSON
{
  "name": "@my-team/dsh-bundle",
  "version": "1.0.0",
  "dsh": {
    "bundle": true,
    "profiles": {
      "web": "./profiles/web.yml",
      "headless": "./profiles/headless.yml"
    },
    "baseConfig": "./cordis.yml",
    "plugins": [
      "./plugins/team-tools",
      "./plugins/team-lint"
    ]
  }
}

(4) Installing a bundle

BASH
# Install from npm
pnpm add @my-team/dsh-bundle

# Start using the bundle's profile
pnpm dsh web --bundle @my-team/dsh-bundle --profile web

4. dsh-base / dsh-web-app / dsh-headless

(1) Built-in Bundles

DSH provides three built-in bundles:

Bundle Description Core Plugins Included
dsh-base Minimal base set core, llm, sessions, trajectory
dsh-web-app Web UI full version dsh-base + web-ui, interactive-tools
dsh-headless No UI version dsh-base + headless-runner, basic-tools

(2) Dependency Relationships

100%
graph TB
    BASE[dsh-base<br/>core + llm + sessions] --> WEB[dsh-web-app<br/>+ Web UI + interactive tools]
    BASE --> HEADLESS[dsh-headless<br/>+ Headless runner + basic tools]

(3) Default Behavior

Without the --bundle parameter, DSH defaults to dsh-web-app:

BASH
# Equivalent to pnpm dsh web --bundle dsh-web-app
pnpm dsh web

(4) Choosing a Base Bundle

BASH
# Minimal bundle (core only)
pnpm dsh web --bundle dsh-base

# Web UI bundle (default)
pnpm dsh web --bundle dsh-web-app

# Headless bundle
pnpm dsh headless --bundle dsh-headless

5. Configuration Layer Composition Order

(1) Multi-Layer Configuration Overlay

DSH's final configuration is composed from multiple layers, with increasing priority from bottom to top:

100%
graph TB
    L1[Layer 1: Bundle default config<br/>cordis.yml] --> L2[Layer 2: Profile config<br/>profiles/web.yml]
    L2 --> L3[Layer 3: Project config<br/>project cordis.yml]
    L3 --> L4[Layer 4: Patch config<br/>cordis.patch.yml]
    L4 --> L5[Layer 5: CLI parameters<br/>--patch, --config]

(2) Overlay Rules

TEXT 📖 Display only
Bundle default: { plugins: [core, llm], port: 5173 }
Profile:       { plugins: [+web-ui], debug: true }
Project config: { plugins: [+my-tool], port: 8080 }
Patch:         { plugins: [+debug-tool] }

Final:         { plugins: [core, llm, web-ui, my-tool, debug-tool],
                port: 8080, debug: true }

(3) Plugin List Merging

Operation Effect
New plugin Appended directly
Same-name plugin Later layer overrides earlier
$insert Appended to end of list
$replace Replaces same-name plugin

(4) Configuration Value Merging

TEXT 📖 Display only
Lower: { a: 1, b: { x: 1, y: 2 } }
Higher: { b: { y: 3, z: 4 }, c: 5 }

Result: { a: 1, b: { x: 1, y: 3, z: 4 }, c: 5 }

Nested objects deep-merge; scalar values override directly.


6. patch Overlay Mechanism

(1) cordis.patch.yml

The patch file is the highest-priority configuration override, suitable for temporary adjustments during development:

YAML
# cordis.patch.yml
plugins:
  debug-tools:
    $insert: ./dev-plugins/debug-tools
  llm:
    config:
      debug: true
      logRequests: true

(2) --patch Parameter

BASH
# Apply patch layer
pnpm dsh web --patch

# Don't apply patch
pnpm dsh web

(3) Multi-Environment Patches

TEXT 📖 Display only
config/
├── cordis.yml              ← Base configuration
├── cordis.patch.dev.yml    ← Development patch
├── cordis.patch.staging.yml ← Staging patch
└── cordis.patch.prod.yml   ← Production patch

Switching environments:

BASH
# Development
cp config/cordis.patch.dev.yml cordis.patch.yml
pnpm dsh web --patch

# Production
cp config/cordis.patch.prod.yml cordis.patch.yml
pnpm dsh web --patch

(4) CLI Direct Override

The highest-priority configuration method:

BASH
# Override port directly
pnpm dsh web --config.port=8080

# Override LLM model directly
pnpm dsh web --config.plugins.llm.config.model=deepseek-reasoner

❓ FAQ

Q What's the relationship between profile and bundle?
A A bundle contains profiles. One bundle can define multiple profiles (web/headless/ci etc.); you select one at startup.
Q Can I use DSH without writing dsh fields?
A Yes. DSH defaults to the dsh-web-app bundle with default configuration. dsh fields are only needed for customization.
Q What's the difference between a bundle and an npm package?
A A bundle is a superset of an npm package — it's an npm package with additional dsh.bundle fields telling DSH how to load configuration and plugins.
Q How to troubleshoot configuration layer conflicts?
A Use --dump-config to view the final configuration: bash pnpm dsh web --patch --dump-config This shows the result of all layers merged, making it easy to locate conflict sources.
Q Can I use DSH without any built-in bundle?
A Yes, use --bundle dsh-base to load only the minimal core set, then assemble your own via cordis.yml.
Q Should patch files be committed to git?
A Development patches can be committed (for team sharing); production patches shouldn't be (contain sensitive configs). Recommend .gitignore excluding cordis.patch.prod.yml.

📖 Summary


📝 Exercises

1. ⭐ Basic: Add dsh.profiles fields to your project's package.json, defining web and headless profiles. Start DSH with each profile and compare the loaded plugin lists.

2. ⭐⭐ Intermediate: Create a cordis.patch.dev.yml that loads the debug-tools plugin and enables LLM request logging in dev mode. Start with --patch and use --dump-config to verify the patch layer's override effect.

3. ⭐⭐⭐ Challenge: Create a complete bundle package with a custom profile, two built-in plugins, and a default configuration. Publish to a local npm registry (or use the file: protocol), install from another project, and start using this bundle.

Web-Tutorial.com

Web-Tutorial Tech Team

A team of developers maintaining programming tutorials. Each tutorial is written and reviewed by developers with expertise in that field. We work to keep our content accurate and reliable — if you spot an issue, please let us know.

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏