# Cross-platform installation and removal The current DSH target is `0.1.5-rc.1`. When moving existing playthroughs from the earlier DSH coordinate format, follow the [upgrade guide](DSH_0.1.5_MIGRATION_en.md) first. This DSH version requires Node `^22.19.0 || >=24.0.0`, regardless of Tavern's standalone Node 20 declaration. [中文](INSTALLATION.md) This guide covers Tavern `2.3.1`; runtime acceptance targets DSH `0.1.5-rc.1`. The default root [README](../README.md) is Chinese. The English landing page is [README_en.md](../README_en.md) (no screenshots). This file is the current lifecycle, verification, and recovery contract. For another version, switch to its tag and read the installation instructions in that tag. The scripts use Node.js as their common entry point and normalize paths for Windows, macOS, and Linux. macOS/Linux execute `dsh` directly. Windows safely locates npm's `dsh.ps1` shim and invokes it through the system PowerShell with an argument array, so paths are not reconstructed as shell command text. Run the scripts from the `dsh-tavern` checkout with Node.js 20 or newer and target DSH `0.1.5-rc.1` on `PATH`; starting its Host requires the Node range above. Only the repository root is installed. `packages/tavern-format`, `packages/preset`, and `packages/tavern-loader` are internal boundaries shipped inside that one plugin; do not try to add them to dsh separately. The format layer can be consumed as a JavaScript library through the root package export, but by itself it intentionally has no agent-loading effect. ## Install 2.3.1 Install `2.3.1` from GitHub into the default `web` profile using its version tag: ```text dsh plugin --profile web add github:Player-MINEPIG/dsh-tavern#v2.3.1 ``` ### Install and validate from source Use a separate test profile/home. Stop its Host before installing. Check out the `v2.3.1` tag, then install from source: ```sh git clone --branch v2.3.1 https://github.com/Player-MINEPIG/dsh-tavern.git cd dsh-tavern npm ci --legacy-peer-deps node scripts/install.mjs --dsh-home /absolute/path/to/test-home --profile web ``` Start DSH `0.1.5-rc.1` with that same `DSH_HOME`, then follow the [developer verification guide](TESTING_en.md). A CLI upgrade alone does not update the plugin installed in a profile. Record `git rev-parse HEAD` for the tested build. ### DSH provides the runtime peers The current `package.json` declares `@deepseek-ai/dsh-util-crypto` at `0.1.2-rc.1 || 0.1.5-rc.1` and `@deepseek-ai/cordis` at `4.0.2` as required `peerDependencies` supplied by the DSH runtime, so the plugin does not install a second copy. Source builds and tests use the `0.1.2-rc.1` crypto package pinned in `devDependencies`. Browser contracts are declared in `dsh.client.inject`, supplied by DSH, and not bundled into Tavern. When a DSH profile uses `nodeLinker: hoisted` and `autoInstallPeers: false`, startup exposes the installation packages through `/profiles/node_modules`, where Node's parent-directory resolution finds them for external plugins. Consequently, `dsh plugin add` or `pnpm peers check` may report these two peers as missing: that static check does not recognize DSH's startup-provided packages. At runtime, both packages must still resolve from the DSH installation. An `ERR_MODULE_NOT_FOUND` after restart is not an ignorable install warning: check that DSH on `PATH` is the target `0.1.5-rc.1`, its installation is complete, and module resolution reaches its packages. Do not mark required peers optional to hide warnings. Exact peer declarations constrain those packages; they are not a startup gate checking the entire DSH version. ### Data and source installation On first start, Tavern automatically creates `/pmp-dsh-tavern/` and does not ask the user to choose an internal storage location. Plain `dsh plugin remove` removes only the package from the profile and retains that directory, but it does not invoke this project's backup logic or create a pre-removal snapshot. Clone the repository and use `npm run plugin:uninstall` below when a snapshot is required. For source development, safe migration from legacy package-local `data/`, or the backup-aware uninstall flow below, clone the repository and install its dependencies once: ```text npm install --cache .npm-cache npm run plugin:install ``` The installer builds `dist/client.js`, calls `dsh plugin ... add` without a shell, and prints a restart reminder. Restart a currently running `dsh web` process before review. Stop the target `dsh web` process before updating an existing installation. Repeated installation does not touch the persistent directory because it sits outside the package. To bridge installations that still use package-local `data/`, the script stages that legacy directory under `/backups/pmp-dsh-tavern/pending-refresh-/` before remove/add and restores it into the new package after add. On the next Host start, if the external directory is empty, Tavern copies the legacy tree through a sibling temporary directory, publishes it atomically at `/pmp-dsh-tavern/`, writes a migration marker, and retains the old copy. A populated external directory is never overwritten and produces a warning. If remove/add fails, the error prints the pending path; the next installer run repairs dependency registration and resumes recovery. Do not delete that directory while recovery is due. The refresh still materializes the worktree's declared `files` entries as independent copies to avoid stale pnpm directory snapshots and mixed hardlink versions. It leaves pnpm-managed nested `node_modules` untouched and validates that the install target stays inside the selected profile. When `--store-dir` is omitted, it reuses the store recorded in `node_modules/.modules.yaml` to avoid `ERR_PNPM_UNEXPECTED_STORE`. Useful options: ```text node scripts/install.mjs --profile web node scripts/install.mjs --skip-build node scripts/install.mjs --dsh-home /absolute/test/home node scripts/install.mjs --store-dir /absolute/pnpm/store node scripts/install.mjs --dry-run ``` Use the direct `node` form when passing options. This avoids npm-version and PowerShell differences in forwarding arguments after `npm run`. Windows paths may be passed normally, for example: ```text node scripts/install.mjs --dsh-home .\test-envs\review ``` ## Release verification Before packaging or installing the current source, run the release verification command (its name remains `verify:2.0`): ```text npm run verify:2.0 ``` The command covers Trace v3 and the real AgentLoop, session-coordinate codecs, history/cursor guards, managed documents and CAS, import claim/lineage, chrome and slot ownership, localization, and installation boundaries. It then builds the tracked browser bundle and performs `npm pack --dry-run`. Set `DSH_TAVERN_COMPAT_ROOT` and `DSH_TAVERN_PROMPT_COMPAT_ROOT` to the target DSH installation dependency root to enable real runtime checks; without them, those checks explicitly skip. Run `npm run check` for the complete suite as well. These commands do not replace [target Host and browser verification](TESTING_en.md). ## Uninstall ```text npm run plugin:uninstall ``` Before calling `dsh plugin ... remove`, the uninstaller copies the default persistent directory to: ```text /backups/pmp-dsh-tavern// ``` The default source is `/pmp-dsh-tavern/`. It holds presets, normalized character cards, PNG cover images under `character-artifacts/` when a card was imported from PNG, standalone world books under `world-books/`, three-field user resources under `users/`, schema 4 Trace metadata/official-history references in `tavern-trace-records.json`, and per-session resource selections. An upgraded directory may also retain read-only legacy `tavern-traces.json` metadata and legacy `tavern-assemblies.json` schema 3 body snapshots; the latter may contain sensitive prompts. Copy the whole directory when backing up; copying only `presets/` loses other resources, audit metadata and bindings. In particular, the same tree holds `state.json`, `character-state.json`, `user-world-book-bindings.json`, `resource-world-book-bindings.json`, `session-templates.json`, `chrome.json`, `play-workspace.json`, `import-context-bindings.json`, `ui-settings.json` (locale, outer UI scale, character-follow RP), `conversation-settings.json` (Mowan RP text and message-action scale), and optional `rp-policy.json`. `play-workspace.json` is only a pointer. The selected DSH RP workspace owns the actual `catalog.json`, per-playthrough `timeline.json`, display regex document, and imported context files, while session bodies and branch history referenced by the timeline remain in the corresponding `DSH_HOME` official session logs. If playthroughs must be recoverable, back up Tavern's persistent directory, the RP workspace, and the corresponding DSH data, including session logs and inherited dependencies. An ST JSONL export preserves only the selected linear chat and known swipes, not the complete Tavern branch topology. Choose another backup directory or deliberately skip backup with: ```text node scripts/uninstall.mjs --backup-dir /absolute/backup/path node scripts/uninstall.mjs --storage-dir /absolute/custom/storage node scripts/uninstall.mjs --no-backup ``` `--storage-dir` snapshots an explicitly configured custom storage directory. `--no-backup` skips only this snapshot. Ordinary removal still retains the default or custom persistent directory and does not delete an external ST file used for import. If the user explicitly wants to purge data, delete the persistent directory separately after confirming a backup; package removal does not implicitly erase user content. All common options work for uninstall too: `--profile`, `--dsh-home`, `--store-dir`, `--storage-dir`, and `--dry-run`. Use `--help` for the complete command summary.