Skip to content
dsh.fish
Bundle

@royenheart/dsh-plugin-skills-manager

dsh plugin: manage skill enable/disable across global/workspace/session scopes

Source
royenheart
License
MIT
Updated
Updated 2 days ago

Readme

# `@royenheart/dsh-plugin-skills-manager`

[![dsh](https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2Froyenheart%2Fdsh-plugin-skills-manager%2Frefs%2Fheads%2Fdsh-migrate%2Fstate%2Fbadge.json)](https://github.com/royenheart/dsh-plugin-skills-manager/tree/dsh-migrate/state)

dsh plugin: enable or disable skills in **session > workspace > global** scopes (then `default(enabled)`). A disable applies to both the model skill catalog and user `/skill` invocation.

---

<center> <img style="width:95%;border-radius: 0.3125em; box-shadow: 0 2px 4px 0 rgba(34,36,38,.12),0 2px 10px 0 rgba(34,36,38,.08);" src="./assets/global-skill-manage.png"> <br> <div style="color:orange; border-bottom: 1px solid #d9d9d9; display: inline-block; color: #999; padding: 2px;margin-bottom:1em">Global skill settings</div> </center>

<center> <img style="width:95%;border-radius: 0.3125em; box-shadow: 0 2px 4px 0 rgba(34,36,38,.12),0 2px 10px 0 rgba(34,36,38,.08);" src="./assets/session-skill-manage.png"> <br> <div style="color:orange; border-bottom: 1px solid #d9d9d9; display: inline-block; color: #999; padding: 2px;margin-bottom:1em">Session skill settings</div> </center>

---

## Required dsh patches (UX only)

Baseline: **dsh 0.1.2-alpha.2** (`master`). Enforcement no longer needs a harness merge-rule or `skill.list` wire patch. Two general-purpose UI seams are still missing upstream; apply them before a full UX match:

| Gap | Patch |
|---|---|
| Workspace overflow has no per-entry list slot, so the plugin cannot add "Manage skills" | `patches/0001` ([Discussion #1413](https://github.com/deepseek-ai/deepseek-harness/discussions/1413)) |
| Host `skills/change` is not forwarded; the `/` picker cache stays stale after a toggle | `patches/0003` |

```bash
cd /path/to/deepseek-harness          # clean 0.1.2-alpha.2 / master
git am /path/to/dsh-plugin-skills-manager/patches/0001-feat-add-sidebar-workspaces.entry.patch
git am /path/to/dsh-plugin-skills-manager/patches/0003-fix-forward-skills-change-to-web-clients.patch
pnpm install
pnpm run build
```

- `0001`: declares the generic `sidebar.workspaces.entry` list slot (`id/label/order/icon`) and projects those rows between Rename and Delete in the workspace overflow menu.
- `0003`: adds `{ event: 'skills/change', mode: 'emit' }` to `API_REMOTE_FORWARDED_EVENTS` and has `ui-skill` clear every session catalog cache.

Dropped versus earlier releases (do **not** apply the old files):

- **deny-wins / `skill.list` `source`+`cwd` (old 0002)** — the plugin registers enforcement on each preset **standing layer** (same layer as `skill-filesystem`, rank 50) and lists skills through plugin HTTP (`GET /plugins/@royenheart/dsh-plugin-skills-manager/skills`).
- **lookup `sessionId` (old 0004)** — a live agent lookup already uses the Agent as `scope` (`scope.id` is the session id). A blank session's `/` menu may still list a session-disabled name until the first step; the model catalog does not.

Settings namespaces are exposed to the Web plane on 0.1.2 by registration; no expose patch is required.

Without 0001 the settings-page workspace tab still works. Without 0003, disable still hides the skill from the **model** catalog; the `/` menu and `/name` chips update only after a preset switch or reconnect.

## Features

1. **Global skill settings** — settings page; overrides go to the `skills-manager` namespace in `settings.yaml`.
2. **Workspace overrides** — overflow "Manage skills" (patch 0001) and the settings workspace tab. Discovery uses host `ctx.skills.list({ cwd })` via the plugin HTTP route.
3. **Session overrides** — conversation "Skills" tab; Shift range-select / Ctrl toggle, then batch enable/disable.

## Managed sources

Only `.agents` and dsh skill roots:

| source | path | meaning |
|---|---|---|
| `project-dsh` | `<project>/.dsh/skills` | dsh project dir |
| `project-agents` | `<project>/.agents/skills` | shared `.agents` |
| `user-dsh` | `$DSH_HOME/skills` | dsh user dir |
| `user-agents` | `~/.agents/skills` | user `.agents` |

Other agent trees (`.claude/skills`, `.codex/skills`, …) and `bundled`/`runtime`/`custom` are ignored. See `src/core/skill-filter.ts`.

## Install

The package is a **dsh profile bundle**. `dsh plugin add` reconciles `dsh.profile.bundles`.

```bash
cd dsh-plugin-skills-manager
python3 install.py install     # build + link into the profile
python3 install.py uninstall
```

`DSH_PROFILE` (default `web`), `DSH_HOME` (default `~/.dsh`).

## How disable reaches the model

The three-layer store is plugin settings, not a dsh patch. On start (and when the preset roster or a standing key changes) the host:

1. `agentPresets.list()` / `standingKeyFor(id)` for every mountable preset
2. `createScope(ctx, key)` using that **same key object**
3. `registerProvider` on that scoped context (rank 50)

A remount mints a new key object; the plugin drops the old bind and registers again. Override rows in settings are unchanged.

The model catalog (`tool-skill`'s `<available_skills>`) keeps only `modelInvocable === true` entries. After the standing bind wins, a disabled name is absent from that catalog — the model never sees `foo`.

## Compatibility

| Probe | When the seam is missing | Notice |
|---|---|---|
| `sidebar.workspaces.entry` undeclared | `slots.inject` never fires; settings workspace tab remains | Silent |
| Settings namespace unavailable | Panel is read-only | Toast + banner |
| List rows have no `source` | No `.agents`/dsh filter; every discovered name is shown | Toast + banner |
| Plugin HTTP and `{ cwd }` list both fail | Workspace tab falls back to a same-cwd session, then manual names | Toast + banner |
| Standing enforcement did not win | Panel still stores overrides; banner warns the model may still see the skill | Toast + banner |

## Tests

```bash
npm test            # node --test tests/*.test.ts
npm run build       # tsdown host + client
```

Install

dsh plugin --profile web add github:royenheart/dsh-plugin-skills-manager

Profile: web

  • This package builds from source on install. pnpm will ask you to allow its build script — that is permission to run the package’s code on your machine, outside the agent sandbox. Only allow sources you trust.
  • This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.
Source