# dshp
**Hand your whole dsh setup to someone as one file — and they get the exact same tree.**
English | [中文](README.zh.md)
```sh
npx github:asdf17128/dshp ls
```
Shows every profile on your machine in one line each. Read-only, zero dependencies.
---
## What it gives you
**See what you actually have.** `dshp ls` and `dshp show` answer "what is
installed, in what order, and did I patch it" without opening a single file.
**Copy before you break it.** `dshp clone web web-test` duplicates a working
setup in under a second, `node_modules` and all. Experiment on the copy; `rm`
it when done.
**Share a setup that reproduces exactly.** `dshp export` writes bundle order,
plugin versions and your patch into one short file. `dshp import` rebuilds it —
verified: a 132-entry profile reproduced into a fresh `$DSH_HOME` composes an
identical tree, patch included.
dsh itself can boot a profile and forward installs to pnpm, but it cannot create
an empty one, list what you have, or copy a working setup before you experiment
on it. That is all manual work under `~/.dsh/profiles` today.
## Share a setup
```sh
dshp export web -o my-setup.dshp
```
```yaml
# dsh profile — reproduce with: dshp import
dshp: 1
name: web
bundles:
- @deepseek-ai/dsh-base
- @deepseek-ai/dsh-web-app
- dsh-cloudflare-browser-run
plugins:
dsh-cloudflare-browser-run: "^0.1.1"
patch: |
- id: session-title
config:
fallbackMaxWords: 12
```
Short enough to paste into a forum post. On the other machine:
```sh
dshp import my-setup.dshp
```
That writes the profile, installs the plugins through dsh's own pnpm, and you boot it with `dsh --profile web`. Verified end-to-end: a fresh `$DSH_HOME` reproduced a 132-entry tree identical to the original, patch included.
## Experiment safely
```sh
dshp clone web web-试验田 # instant, keeps node_modules
dsh plugin --profile web-试验田 add some-experimental-plugin
dshp diff web web-试验田
```
```
web -> web-试验田
plugins
+ some-experimental-plugin@^0.2.0
```
If it goes wrong, `dshp rm web-试验田 --yes`. Your working profile was never touched.
## Commands
| | |
|---|---|
| `dshp ls` | profiles, with bundle/plugin counts and disk size |
| `dshp show ` | bundles in load order, plugins, patch |
| `dshp new [--web\|--headless]` | create a profile — dsh itself cannot make an empty one |
| `dshp clone ` | copy a working setup, `node_modules` and all |
| `dshp export [-o FILE]` | portable file (stdout by default) |
| `dshp import [--as NAME] [--no-install]` | recreate a profile |
| `dshp diff ` | what differs |
| `dshp rm --yes` | delete |
## What a profile actually is
Under `$DSH_HOME/profiles/`:
- `package.json` — `dependencies` are the plugins, `dsh.profile.bundles` is the ordered layer stack
- `cordis.patch.yml` — your own id-targeted overrides
- `cordis.yml`, `pnpm-workspace.yaml` — boilerplate, regenerated
So three things reproduce a setup: plugin versions, bundle order, and the patch. That is exactly what the portable file carries.
Bundle **order** is part of the format: it decides which layer patches which, so a reordering is reported by `diff` as a real difference.
The patch block is copied byte-for-byte rather than re-serialised, because it may hold `!!js` expressions (`root: !!js dshHomePath('sessions')`) that a YAML round-trip would mangle or evaluate. Nothing here ever evaluates your config.
## Install and uninstall
As a CLI: `npx dshp ls` — nothing to install.
As a plugin:
```sh
dsh plugin --profile web add github:asdf17128/dshp # install
dsh plugin --profile web remove dshp # uninstall
```
Removing it drops the `list_profiles` and `export_profile` tools. Your profiles
are untouched — the plugin only reads.
## Compatibility
Verified against `@deepseek-ai/dsh` **0.1.0-rc.5**. The profile layout it reads
(`package.json` with `dsh.profile.bundles`, `cordis.patch.yml`) is dsh's own; a
change there is what would break it first.
## Requirements
Node 18+. `import` needs a working `dsh` (local `node_modules/.bin/dsh` preferred, otherwise on `PATH`) because it installs through dsh's own pnpm; every other command is pure filesystem work.
## See also
[dsh-doctor](https://github.com/asdf17128/dsh-doctor) — checks a profile for patches that silently stopped applying.
## License
MIT