Skip to main content

Bundle manifest vs profile: two layers, two jobs

What dsh.bundle and ~/.dsh/profiles/*.json each control, how to isolate web/tui/headless workspaces, and where the profile-switching boundaries actually live.

7 min read

What you'll learn

  • How DSH's two-manifest model (bundle + profile) coordinates plugin loading
  • What happens when the same plugin is active in multiple profiles
  • Use dsh --profile X plugin add to isolate plugin sets per workspace

Version

Compatible with: dsh 0.1.1-rc.2 (compiled from official apps/cli/README + docs/user/develop/basic/)

What each manifest controls

DSH uses two manifests: one describes how a plugin loads, the other describes which plugins a workspace uses:

FileLocationContentRead by
dsh.bundlerepo rootplugin metadata (name / version / entry / services / patches)CLI, once at install time
~/.dsh/profiles/<name>.jsonuser workspacewhich bundles to enable + load order + boot flagsWeb/CLI, every start

They don't replace each other: bundle says "this repo is a DSH plugin", profile says "today I want this combo of plugins". The same bundle can be in multiple profiles — each profile loads its own independent instance (via Cordis dispose), no cross-contamination.

Three common profile recipes

  • web (default): runs Web GUI, enables everything browser-friendly (vision, context dashboard, skins, pets)
  • tui: runs terminal UI (dsh-tianshu-tui / dsh-TUI), TUI-specific plugins + tools that don't need GUI
  • headless: pure CLI, no UI; only essentials (search, memory, context)

Switch profiles:

dsh --profile web plugin add @liustack/modlens
dsh --profile tui plugin add @omdsh-dev/dsh-mnemon

Each profile maintains its own plugin list, no interference.

Isolation boundaries

  • shared: model API keys, license cache, GitHub API token (global config)
  • isolated: plugin list, enable/disable state, profile-level config (e.g. cordis.services)
  • not shared: temporary caches (web's IndexedDB / tui's PTY history), preserved per profile across switches

Troubleshooting

  • "installed a plugin but profile doesn't show it": probably installed to a different profile; check with dsh --profile X plugin ls
  • "profile boot fails": dsh --profile X --dump-config prints the actual load list
  • "two profiles cross-pollinate data": check ~/.dsh/profiles/ for same-name profile collisions; profile names should be kebab-case with no spaces

FAQ

Can I edit a profile file directly?

Yes, at ~/.dsh/profiles/<name>.json. CLI also writes there, but manual edits get overwritten the next time CLI mutates that profile — back up first.

Can a bundle force itself into one specific profile only?

No. Bundles are profile-agnostic; either use CLI flags to pick the profile at install time, or check ctx.config.profile inside the plugin's apply(ctx).