fix(cli): plugin UX — anchor relative specs, reconcile by installed state, guide blocked git builds
- Relative path specs (., ../plugin, file:/link: forms) anchor to the invoking directory before forwarding: pnpm's cwd is the profile dir, so a bare 'add .' from a plugin checkout used to self-link the profile (exit 0, nothing installed). Bare paths stay bare and prefixed specs keep their prefix, preserving pnpm's link-vs-copy semantics. - dsh.plugins reconciles against the INSTALLED state on every successful pnpm run, not the dependency diff: an update whose new version gains dsh.patch activates the layer; a version that drops it (or a removal) deactivates it. Template bundles are never touched. - A failed pnpm run now names the profile directory, and a git-spec failure explains pnpm >=10's prepare-script block with a pointer at the profile's pnpm-workspace.yaml allowBuilds (turtle-ui's prepare-based git install is the reference consumer); reference README documents all three.
This commit is contained in:
@@ -25,7 +25,7 @@ dsh --profile web --patch ./extra.yml --dump-config
|
||||
|
||||
## Plugin management
|
||||
|
||||
`dsh plugin --profile <name> <args...>` initializes the profile when missing (shipped template, or `@deepseek-ai/dsh-base` alone for other names), then forwards `<args...>` verbatim to `pnpm` with the profile directory as working directory — `add`, `remove`, `why`, `update`, and every other pnpm verb work unchanged; pnpm must be on PATH. After a successful `add`, a package whose manifest declares `"dsh": { "patch": "./cordis.patch.yml" }` is appended to `dsh.plugins` (last layer); a package without that declaration stays a plain dependency and prints a warning. `remove` drops the package from `dsh.plugins`.
|
||||
`dsh plugin --profile <name> <args...>` initializes the profile when missing (shipped template, or `@deepseek-ai/dsh-base` alone for other names), then forwards `<args...>` to `pnpm` with the profile directory as working directory — `add`, `remove`, `why`, `update`, and every other pnpm verb work unchanged; pnpm must be on PATH. Relative path specs (`.`, `../plugin`, and their `file:`/`link:` forms) are anchored to the invoking directory first, so `add .` from a plugin checkout installs that checkout, not the profile. After every successful run, `dsh.plugins` is reconciled against the installed state: each dependency resolving to a package whose manifest declares `"dsh": { "patch": "./cordis.patch.yml" }` joins the layer stack (so an `update` that gains the declaration activates it), a patch-less dependency stays plain with a one-time warning, and a removed dependency leaves the stack.
|
||||
|
||||
```sh
|
||||
dsh plugin --profile tui add github:deepseek-harness/turtle-ui
|
||||
@@ -33,6 +33,8 @@ dsh plugin --profile tui remove turtle-ui
|
||||
dsh --profile tui
|
||||
```
|
||||
|
||||
Git-hosted plugins that ship sources build during install through their `prepare` script, which pnpm ≥10 blocks until the consumer allows it: the first `add` fails with pnpm's `allowBuilds` hint (and a dsh pointer at the profile's `pnpm-workspace.yaml`); copy the printed key there and re-run. Installing a built tarball or a local checkout needs no allowance.
|
||||
|
||||
## Web alias
|
||||
|
||||
`dsh web` is a hardcoded alias for `--profile web` that additionally accepts the Web flag family. `--host`, `--port`, `--workspace-root`, and repeatable `--trusted-host` values become patches over the composed rows; their owning plugin schemas validate them at boot. `--dev` switches the web-runtime row to development mode and inserts the client-plugin HMR receiver; it expects a separate `pnpm run dev:web` watcher for no-refresh client bundle updates.
|
||||
|
||||
Reference in New Issue
Block a user