dsh-plugin-tool-management 0.9.1 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README_EN.md CHANGED
@@ -1,199 +1,206 @@
1
- # dsh-plugin-tool-management
2
-
3
- [![npm version](https://img.shields.io/npm/v/dsh-plugin-tool-management?logo=npm&color=cb3837)](https://www.npmjs.com/package/dsh-plugin-tool-management)
4
- [![License](https://img.shields.io/badge/license-MIT-blue)](LICENSE)
5
- [![Node](https://img.shields.io/badge/node-%3E%3D18-339933?logo=node.js)](package.json)
6
- [![GitHub](https://img.shields.io/badge/GitHub-ouli--1242%2Fdsh--plugin--tool--management-181717?logo=github)](https://github.com/ouli-1242/dsh-plugin-tool-management)
7
-
8
- [![DSH Market](https://raw.githubusercontent.com/2BingLing/dsh-market/master/assets/readme/badge-listed-en.svg)](https://dsh.market/)
9
- [![awesome-dsh-plugin](https://img.shields.io/badge/awesome--dsh--plugin-listed-3fb950)](https://awesome-dsh-plugin.com)
10
- [![dshfind](https://dshfind.com/api/badge/ouli-1242/dsh-plugin-tool-management?lang=en)](https://dshfind.com/zh/plugins/ouli-1242/dsh-plugin-tool-management)
11
-
12
- [简体中文](README.md) · **English** · [Changelog](CHANGELOG.md) · [Release overview](docs/update.md)
13
-
14
- - An **MCP, skills, scenes, memories, subagents, prompts & archived sessions** manager for DeepSeek Harness.
15
- - Eight tabs: **Scenes**, **MCP**, **Skills**, **Subagents**, **Prompts**, **Memories**, **Sessions**, **Host**.
16
-
17
- ```sh
18
- dsh plugin --profile web add dsh-plugin-tool-management@latest
19
- ```
20
-
21
- Hard-refresh the browser (Cmd/Ctrl+Shift-R) afterwards — a **Tools** panel in Settings means it worked. No hand-editing of `cordis.patch.yml`, no skill source files touched, configuration survives restarts and upgrades.
22
-
23
- ---
24
-
25
- ## Screenshots
26
-
27
- | | |
28
- |:---------------------------------:|:----------------------------------:|
29
- | ![Scenes](docs/images/1-EN.png) | ![MCP](docs/images/2-EN.png) |
30
- | **Scenes** | **MCP** |
31
- | ![Skills](docs/images/3-EN.png) | ![Subagents](docs/images/4-EN.png) |
32
- | **Skills** | **Subagents** |
33
- | ![Prompts](docs/images/5-EN.png) | ![Memories](docs/images/6-EN.png) |
34
- | **Prompts** | **Memories** |
35
- | ![Sessions](docs/images/7-EN.png) | ![Host](docs/images/8-EN.png) |
36
- | **Sessions** | **Host** |
37
-
38
- ## Highlights
39
-
40
- In one line: **set up a scene for each kind of work — "day job / writing / coding" — and switch the whole stack with one click. Everything the plugin manages, the model can actually see.**
41
-
42
- | Highlight | What it means |
43
- | ------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
44
- | One-click scene switch | Each scene carries its own set: which MCP servers, which skills, which personas, which memories; flip it on and the whole stack follows, turn it off and everything comes back |
45
- | Memories reach the model on their own | Write a few `.md` files under a scene and they become its knowledge base — injected automatically, no copy-pasting every session |
46
- | Notes for MCP servers | Write "if A is down, fall back to B" as a note — the model sees it and acts on it |
47
- | Disable a single tool | Keep a server but mute one tool: invisible and uncallable; "Restart" only reconnects and never flips switches |
48
- | Skills at a glance | Which copy is in effect, which is shadowed by a same-name skill, which is preferred — all marked in the list |
49
- | Subagent = one file, one role | Write a role file and delegate; only the result comes back and it never clutters your History; which roles are available can follow the scene |
50
- | Several prompt presets | Keep multiple AGENTS.md baselines (terse mode, teaching tone, …), switch with one click; a scene can bind its own |
51
- | Sessions no longer lost | Archive grouped by project, searchable, batch-restorable; import transcripts from Claude Code / Cursor / Codex |
52
- | The model always sees it | Everything the plugin manages (memories / MCP / skills / subagents / prompts) is announced to the model — one message per domain, republished only on change; under Minimal nothing is injected by default (follows the preset), force any domain on in the Host tab |
53
- | Lock it and relax | Lock a scene to make all five domains read-only; unlock first to change anything |
54
- | Deleted is not gone | Deletes land in a recycle bin and can be restored; skills / memories / personas / presets zip out and back in |
55
- | Safe by default | Secrets masked, plaintext needs a token; only the plugin's own files are written, skill sources stay untouched, and your config survives restarts and upgrades |
56
-
57
- ## Quick start
58
-
59
- Prerequisites: DSH installed (`dsh web` runs), Node.js ≥ 18.
60
-
61
- ```sh
62
- dsh plugin --profile web add dsh-plugin-tool-management@latest # install / update
63
- dsh plugin --profile web remove dsh-plugin-tool-management # uninstall
64
- ```
65
-
66
- Hard-refresh the browser — a **Tools** panel with eight tabs means it worked. Client changes hot-reload; host-side changes need `dsh web` restarted.
67
-
68
- You can also ask the model:
69
-
70
- ```text
71
- Install the dsh-plugin-tool-management plugin:
72
- dsh plugin --profile web add dsh-plugin-tool-management@latest
73
- Then remind me to hard-refresh the browser.
74
- ```
75
-
76
- The model can manage everything above via 14 tools (`mcp_manager_*` / `skill_manager_*` / `prompt_manager_*` / `memory_manager_*` / `subagent_manager_*`); scripts use `POST /dsh-plugin-tool-management/api` (`{op, args}` protocol).
77
-
78
- ---
79
-
80
- ## Features
81
-
82
- ### Scenes & memories
83
-
84
- - **A scene = a group, a memory = a `.md` file**. `memories/<scene>/<name>.md`, the whole body is injected, file names can be non-ASCII.
85
- - **Single-choice toggle**: only one scene at a time (others greyed out); turning all off = only `global` and `_shared` inject. New scenes start off.
86
- - **Scene-bound prompt**: switching scenes rewrites `~/.dsh/AGENTS.md` (5-gen backup, auto-restore on exit).
87
- - **Scene profile**: every scene combines MCP tools / skills / subagents / memories (any mix); opening a scene applies and narrows injection, closing restores verbatim (the toggle is the only entry). Checked means on, unchecked means off, and **a missing section means nothing is checked — so that whole domain is off** (a scene with no MCP section therefore stops every MCP server, and exit starts them again). While a scene is active those switches (MCP, skills, subagents, prompts) still work — changes are written into that scene's profile too (they take effect immediately and are kept for the next visit); only locking freezes them. The memory domain has a single source of truth and never goes through the profile.
88
- - **Import**: `.md` / `.zip` (dir name = scene, bundles carry attachments), same names skipped never overwritten, over-limit items reported.
89
- - **Export**: pick memories and zip them, keeping the `scene/name` layout; bundle memories bring their attachments along. Sources are read-only.
90
- - **Injection budget**: default 64 KiB, oversized memories skipped with a list. Deletes go to recycle bin.
91
- - **Scene lock**: once locked, MCP / skills / subagents / memories / prompts are read-only — UI disabled plus a server-side guard; a scene must be running to lock, and a locked scene can't be closed until unlocked.
92
- - **Deleting a scene deletes its memories too**: the scene record, profile and every memory go into one recycle-bin entry, restored as a whole; a running scene refuses deletion. Scene names are renameable (dir and profile follow, memory bodies untouched).
93
-
94
- ### Subagents
95
-
96
- - **One file per persona**: `agents/<persona>.md`, frontmatter entirely optional.
97
- - **Tool limits per Agent preset**: each preset gets its own allow/deny list (mutually exclusive), effective at runtime by the current preset — fixes the old "union of all presets" list that broke subagents after a preset switch.
98
- - **Run and discard**: `subagent_manager_run` runs with the persona, returns only the result, never enters History, inherits scene memories. Scenes can bind which personas are available.
99
- - **On/off toggles**: a disabled persona is not injected and invisible to the model (file untouched); newly created / imported / restored personas start enabled. Entering a scene applies the profile's persona list exactly (checked on, everything else off; no section = all off) and exit restores the pre-scene switches. Inside a scene these toggles still work and are synced into the scene profile (only locking freezes them); leaving the scene restores the pre-scene state.
100
- - **Persona catalog enters the system prompt**: names + descriptions only, so the model knows what it can delegate to; personas are renameable, scene bindings follow.
101
-
102
- ### MCP servers
103
-
104
- - **CRUD + immediate effect**: writes to `cordis.patch.yml`, HMR picks it up.
105
- - **Per-tool switches**: disable individual tools (invisible to the model, blocked at call), whole-server batch.
106
- - **Stopped servers still show their tools**: a server that is not running keeps the tool names and descriptions last seen (marked "as of last run"); one that has never run can be probed with "start server to read tools".
107
- - **Secret masking**: defaults to `••••••`, "Reveal" needs a token.
108
- - **Migrate & back up**: cross-project/global migration rolls back on failure; JSON export/import.
109
- - **Status & notes enter the system prompt**: only currently usable servers are listed, and your notes travel along as decision hints; levels are "global / app", new servers default to global. Note: a persona-complete preset such as minimal suppresses that section — there the model reads server names, enablement, tool counts and notes with `mcp_manager_list`.
110
-
111
- ### Skills
112
-
113
- - **Sources at a glance**: project / DSH / Agents / Codex / Claude / custom dirs, grouped by source.
114
- - **Opposite permissions**: default sources must be read but skills can be deleted; external dirs can be disabled/removed but skills are read-only.
115
- - **Remove ≠ disable**: remove = directory not scanned at all (files untouched, restorable); disable = still listed but not callable.
116
- - **Same-name skills: see which copy is in effect**: the winning copy is marked "preferred", shadowed ones name the source that wins, and enabling a shadowed copy says so instead of pretending it worked.
117
- - **Custom dirs / ZIP import & export / recycle bin**.
118
-
119
- ### Prompt presets
120
-
121
- - Multiple `~/.dsh/AGENTS.md` baselines, one-click apply (the host re-reads that file every turn, so it takes effect on the next turn), 5-gen backup.
122
- - **Remembers the preset applied last**: even after you hand-edit `AGENTS.md`, the model can still answer "which preset is this from" (flagged "changed since").
123
- - **Description**: one line saying what a preset is for — shown in this panel only. It lives in a sibling `meta.json`, never in AGENTS.md, so it is never injected into prompts.
124
- - Create with body inline, edit can change id (= dir rename, scene bindings follow). A referenced preset cannot be deleted (bound by a scene, currently in AGENTS.md, or the baseline to restore on scene exit); deletes go to recycle bin.
125
- - **While a scene drives the baseline, Apply only works for that scene's bound preset** (applying another one would bypass the binding — that is exactly how "shows A, injects B" happened); rebind it on the Scenes page or exit the scene first.
126
-
127
- ### Archived sessions
128
-
129
- - Grouped by project, search, batch restore / delete, retention auto-cleanup.
130
- - Workspace registration deleted → group rebuilt from session dirs, one-click re-register.
131
- - Import Claude Code / Cursor / Codex / any text; export Markdown / JSONL.
132
-
133
- ### Host compatibility
134
-
135
- The plugin uses the host's own `@deepseek-ai/*` libraries at runtime — they must be the same physical modules, or every "adapt to host" decision degrades into guesswork.
136
-
137
- - **Host tab**: host version, usable capability count, per-action routing (native/adapter/unavailable), degradations & reasons. Read-only.
138
- - **Command line**: `node scripts/doctor.mjs` (check), `node scripts/host-deps.mjs --fix` (align deps), `npm run sync:profile` (mirror the build into the profile's local install — a `file:` install is a hard-linked copy, so files ADDED by a build never show up there on their own).
139
- - Under a **suppressing preset** such as `minimal` (persona `complete` / runtime context off) this plugin's injection is **off by default** (following the preset's intent), and the prompt and the skills are missing because their official rows are not mounted — the Host tab marks this per column, and its "Injection" block can force any domain back on.
140
-
141
- ---
142
-
143
- ## Where data lives
144
-
145
- | Content | Location |
146
- | --------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
147
- | MCP definitions | `~/.dsh/cordis.patch.yml` (written by the plugin; pre-write copies land in the hub's `backups/`) |
148
- | Skill policy / custom dirs | `~/.dsh/tool-management/skills-state.json` |
149
- | Skills / memories / personas / presets | `~/.dsh/tool-management/{skills,memories,subagents,prompts}/` |
150
- | Subagent toggles | `~/.dsh/tool-management/subagents-index.json` |
151
- | Recycle bin | `~/.dsh/tool-management/trash/{skills,subagents,prompts,scenes}-trash/` |
152
- | Archive ledger / retention | `~/.dsh/tool-management/history-*.json` |
153
- | Memory index / scenes / profiles | `~/.dsh/tool-management/memories-index.json` |
154
- | MCP sidecars (disabled tools / known tools / notes / settings) | `~/.dsh/tool-management/mcp-*.json` |
155
- | Injection settings (five domain switches / suppressing-preset policy) | `~/.dsh/tool-management/inject-settings.json` |
156
- | Runtime log / patch backups | `~/.dsh/tool-management/tool-management.log` · `backups/` |
157
-
158
- **No user data is stored inside the plugin's install directory** (`dsh plugin update` replaces it wholesale).
159
-
160
- ## Configuration & security
161
-
162
- | Field | Description |
163
- | -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
164
- | `token` | Access token. When set, **all writes + plaintext secrets** require `x-dsh-token`; **unset = plaintext endpoints closed**. Also the escape hatch for curl / LAN. |
165
- | `maxBodyBytes` | Request body cap, default 88 MiB. |
166
-
167
- - **Browser**: reads/writes via cookie, no token needed; but **plaintext secrets** (Reveal / export) need a token.
168
- - **curl / scripts**: send `x-dsh-token`, or carry the browser cookie.
169
- - **Port forwarded to public**: configure a token — prevents strangers injecting MCP commands (≈ remote code execution) and stealing secrets.
170
-
171
- ## FAQ
172
-
173
- | Symptom | Fix |
174
- | ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
175
- | Pages missing after install | Hard refresh; restart DSH if that fails. |
176
- | Duplicate MCP tabs | Remove the stale loader row from `cordis.patch.yml`, restart. |
177
- | Broken config, DSH won't boot | Restore the newest `.bak-<timestamp>`. |
178
- | Action stopped after DSH upgrade | Settings → Tools → **Host** for the reason; `doctor.mjs` → `host-deps.mjs --fix`. |
179
- | Still asked to confirm in `approval=never`? | No card appears — straight through with a log line; switch back to "workspace write" to get asked again. |
180
- | `subagent_manager_run` reports spawn unavailable | Host has no spawn provider; mount `@deepseek-ai/dsh-subagent-spawn-in-process` and restart. |
181
- | Scene binds persona A, but official `subagent` ran something else | Two channels: this plugin only governs `subagent_manager_run`; official `subagent` / `subagent_fork` have no gate and don't know about personas. |
182
-
183
- ---
184
-
185
- ## Development
186
-
187
- ```bash
188
- npm install
189
- npm run build # tsc + sync client
190
- npm test # build + i18n + smoke tests (mount & render)
191
- npm run check:i18n # dictionary self-check
192
- npm run doctor # host compatibility check
193
- ```
194
-
195
- `lib/` is not tracked — run `npm run build` after cloning. Changes need `dsh web` restarted. Runtime dep is only `fflate`; `@deepseek-ai/*` all come from the host.
196
-
197
- ## License
198
-
199
- MIT
1
+ # dsh-plugin-tool-management
2
+
3
+ [![npm version](https://img.shields.io/npm/v/dsh-plugin-tool-management?logo=npm&color=cb3837)](https://www.npmjs.com/package/dsh-plugin-tool-management)
4
+ [![License](https://img.shields.io/badge/license-MIT-blue)](LICENSE)
5
+ [![Node](https://img.shields.io/badge/node-%3E%3D18-339933?logo=node.js)](package.json)
6
+ [![GitHub](https://img.shields.io/badge/GitHub-ouli--1242%2Fdsh--plugin--tool--management-181717?logo=github)](https://github.com/ouli-1242/dsh-plugin-tool-management)
7
+
8
+ [![DSH Market](https://raw.githubusercontent.com/2BingLing/dsh-market/master/assets/readme/badge-listed-en.svg)](https://dsh.market/)
9
+ [![awesome-dsh-plugin](https://img.shields.io/badge/awesome--dsh--plugin-listed-3fb950)](https://awesome-dsh-plugin.com)
10
+ [![dshfind](https://dshfind.com/api/badge/ouli-1242/dsh-plugin-tool-management?lang=en)](https://dshfind.com/zh/plugins/ouli-1242/dsh-plugin-tool-management)
11
+
12
+ [简体中文](README.md) · **English** · [Changelog](CHANGELOG.md) · [Release overview](docs/update.md)
13
+
14
+ - An **MCP, skills, scenes, memories, subagents, prompts & archived sessions** manager for DeepSeek Harness.
15
+ - Eight tabs: **Scenes**, **MCP**, **Skills**, **Subagents**, **Prompts**, **Memories**, **Sessions**, **Host**.
16
+
17
+ ```sh
18
+ dsh plugin --profile web add dsh-plugin-tool-management@latest
19
+ ```
20
+
21
+ Hard-refresh the browser (Cmd/Ctrl+Shift-R) afterwards — a **Tools** panel in Settings means it worked. No hand-editing of `cordis.patch.yml`, no skill source files touched, configuration survives restarts and upgrades.
22
+
23
+ ---
24
+
25
+ ## Screenshots
26
+
27
+ | | |
28
+ |:---------------------------------:|:----------------------------------:|
29
+ | ![Scenes](docs/images/1-EN.png) | ![MCP](docs/images/2-EN.png) |
30
+ | **Scenes** | **MCP** |
31
+ | ![Skills](docs/images/3-EN.png) | ![Subagents](docs/images/4-EN.png) |
32
+ | **Skills** | **Subagents** |
33
+ | ![Prompts](docs/images/5-EN.png) | ![Memories](docs/images/6-EN.png) |
34
+ | **Prompts** | **Memories** |
35
+ | ![Sessions](docs/images/7-EN.png) | ![Host](docs/images/8-EN.png) |
36
+ | **Sessions** | **Host** |
37
+
38
+ ## Highlights
39
+
40
+ In one line: **set up a scene for each kind of work — "day job / writing / coding" — and switch the whole stack with one click. Everything the plugin manages, the model can actually see.**
41
+
42
+ | Highlight | What it means |
43
+ | ------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
44
+ | One-click scene switch | Each scene carries its own set: which MCP servers, which skills, which personas, which memories; flip it on and the whole stack follows, turn it off and everything comes back |
45
+ | Memories reach the model on their own | Write a few `.md` files under a scene and they become its knowledge base — injected automatically, no copy-pasting every session |
46
+ | Notes for MCP servers | Write "if A is down, fall back to B" as a note — the model sees it and acts on it |
47
+ | Disable a single tool | Keep a server but mute one tool: invisible and uncallable; "Restart" only reconnects and never flips switches |
48
+ | Skills at a glance | Which copy is in effect, which is shadowed by a same-name skill, which is preferred — all marked in the list |
49
+ | Subagent = one file, one role | Write a role file and delegate; only the result comes back and it never clutters your History; which roles are available can follow the scene |
50
+ | Several prompt presets | Keep multiple AGENTS.md baselines (terse mode, teaching tone, …), switch with one click; a scene can bind its own |
51
+ | Sessions no longer lost | Archive grouped by project, searchable, batch-restorable; import transcripts from Claude Code / Cursor / Codex |
52
+ | The model always sees it | Everything the plugin manages (memories / MCP / skills / subagents / prompts) is announced to the model — one message per domain, republished only on change; under Minimal nothing is injected by default (follows the preset), force any domain on in the Host tab |
53
+ | Lock it and relax | Lock a scene to make all five domains read-only; unlock first to change anything |
54
+ | Deleted is not gone | Deletes land in a recycle bin and can be restored; skills / memories / personas / presets zip out and back in |
55
+ | Safe by default | Secrets masked, plaintext needs a token; only the plugin's own files are written, skill sources stay untouched, and your config survives restarts and upgrades |
56
+
57
+ ## Quick start
58
+
59
+ Prerequisites: DSH installed (`dsh web` runs), Node.js ≥ 18.
60
+
61
+ ```sh
62
+ dsh plugin --profile web add dsh-plugin-tool-management@latest # install / update
63
+ dsh plugin --profile web remove dsh-plugin-tool-management # uninstall
64
+ ```
65
+
66
+ Hard-refresh the browser — a **Tools** panel with eight tabs means it worked. Client changes hot-reload; host-side changes need `dsh web` restarted.
67
+
68
+ You can also ask the model:
69
+
70
+ ```text
71
+ Install the dsh-plugin-tool-management plugin:
72
+ dsh plugin --profile web add dsh-plugin-tool-management@latest
73
+ Then remind me to hard-refresh the browser.
74
+ ```
75
+
76
+ The model can manage everything above via 14 tools (`mcp_manager_*` / `skill_manager_*` / `prompt_manager_*` / `memory_manager_*` / `subagent_manager_*`); scripts use `POST /dsh-plugin-tool-management/api` (`{op, args}` protocol).
77
+
78
+ ---
79
+
80
+ ## Features
81
+
82
+ ### Scenes & memories
83
+
84
+ - **A scene = a group, a memory = a `.md` file**. `memories/<scene>/<name>.md`, the whole body is injected, file names can be non-ASCII.
85
+ - **Single-choice toggle**: only one scene at a time (others greyed out); turning all off = only `global` and `_shared` inject. New scenes start off.
86
+ - **Scene-bound prompt**: switching scenes rewrites `~/.dsh/AGENTS.md` (5-gen backup, auto-restore on exit).
87
+ - **Scene profile**: every scene combines MCP tools / skills / subagents / memories (any mix); opening a scene applies and narrows injection, closing restores verbatim (the toggle is the only entry). Checked means on, unchecked means off, and **a missing section means nothing is checked — so that whole domain is off** (a scene with no MCP section therefore stops every MCP server, and exit starts them again). While a scene is active those switches (MCP, skills, subagents) still work — changes are written into that scene's profile too (they take effect immediately and are kept for the next visit); only locking freezes them. The memory domain has a single source of truth and never goes through the profile.
88
+ - **Import**: `.md` / `.zip` (dir name = scene, bundles carry attachments), same names skipped never overwritten, over-limit items reported.
89
+ - **Export**: pick memories and zip them, keeping the `scene/name` layout; bundle memories bring their attachments along. Sources are read-only.
90
+ - **Injection budget**: default 64 KiB, oversized memories skipped with a list. Deletes go to recycle bin.
91
+ - **Subagent sessions do not receive memories**: memories are injected into the **top-level session only** — they are the parent's situation, not the facts a child needs; a child's context stays "persona + task", it can read memories on demand with `memory_manager_list/read`, and relevant facts belong in the `task`. Other domains are unaffected (MCP / skills / prompts still inject; the persona catalog follows each persona's `catalogDepth`).
92
+ - **Scene lock**: once locked, MCP / skills / subagents / memories / prompts are read-only — UI disabled plus a server-side guard; a scene must be running to lock, and a locked scene can't be closed until unlocked.
93
+ - **Deleting a scene deletes its memories too**: the scene record, profile and every memory go into one recycle-bin entry, restored as a whole; a running scene refuses deletion. Scene names are renameable (dir and profile follow, memory bodies untouched).
94
+
95
+ ### Subagents
96
+
97
+ - **One file per persona**: `agents/<persona>.md`, frontmatter entirely optional.
98
+ - **A persona reaches the subagent's system prompt inside a role frame**: the body is used verbatim, wrapped in a `# Persona: <name>` heading, one authorizing line ("specified by the caller; where it conflicts with your default inclinations, it wins; the task states what to achieve, and this persona governs how") and one boundary line (it governs *how* you work, not *what* you may do), with the body fenced under `## Persona`. The frame follows the body's language. This makes the model read it as "I have been assigned a role" rather than as two stray sentences following the identity line — **the persona file itself needs no change**. The frame does not include `description`: that field exists so the *caller* can pick a persona; an introduction meant for the child belongs in the body.
99
+ - **Tool limits per Agent preset**: each preset gets its own allow/deny list (mutually exclusive), effective at runtime by the current preset — fixes the old "union of all presets" list that broke subagents after a preset switch.
100
+ - **`output:` hard output contract**: frontmatter may carry multiple `output:` lines (**one requirement per line**); the role frame renders them as a separate `## Output requirements (hard)` section after the persona definition. Use the prompt for how the role thinks (prose) and `output:` for what the deliverable must look like (format, severities, required markers, bans) — a persona with only an abstract requirement produces output nobody can check, and only checkable requirements actually get followed. The editor has an "Output requirements (hard)" box, and you can write the lines into the file directly.
101
+ - **Run and discard**: `subagent_manager_run` runs with the persona, returns only the result, never enters History. A child's context is **persona + task** only: memories are not injected (the child can read them with `memory_manager_*`, and relevant facts belong in the `task`). Scenes can bind which personas are available.
102
+ - **Two context modes**: by default the child starts fresh (it cannot see this conversation, so the task must be complete); with `inherit` the child is seeded with this conversation's **finished** turns (the same mechanism as the host's `subagent_fork`) and the task only states what is new. Only finished turns are inherited — a delegation made during the current turn cannot pass that turn's content (measured: a parent that delegated while still reading left the child to start from scratch), so treat `task` as self-contained in that case. The boundary against the host's two delegation tools (`subagent` / `subagent_fork`) is written into the context by this plugin: **work that matches a persona goes here**, and the host tools are for when no persona fits or a background job is needed.
103
+ - **On/off toggles**: a disabled persona is not injected and invisible to the model (file untouched); newly created / imported / restored personas start **disabled** (since v0.8.5, the same rule as skills / MCP) — switch them on before delegating. Entering a scene applies the profile's persona list exactly (checked on, everything else off; no section = all off) and exit restores the pre-scene switches. Inside a scene these toggles still work and are synced into the scene profile (only locking freezes them); leaving the scene restores the pre-scene state.
104
+ - **Persona catalog enters the system prompt**: names + descriptions only, so the model knows what it can delegate to; personas are renameable, scene bindings follow.
105
+ - **Catalog injection (`catalogDepth`)**: which sessions the standing persona catalog is injected into — default `1` = top level only; `2` also reaches subagent sessions; `3` goes two levels down; the UI's “No nesting limit” writes `99`, which reaches every session depth. **It does not limit nesting**: subagents can always delegate further, which the host decides (`dsh-tool-subagent` defaults to `maxDepth: 3`), and this plugin no longer passes `maxDepth` at all. When the standing catalog is not injected, `subagent_manager_list` still returns every persona. One rule drives all three places (catalog filter, domain declaration, live panel), so the UI and the actual injection cannot disagree.
106
+
107
+ ### MCP servers
108
+
109
+ - **CRUD + immediate effect**: writes to `cordis.patch.yml`, HMR picks it up.
110
+ - **Per-tool switches**: disable individual tools (invisible to the model, blocked at call), whole-server batch.
111
+ - **Stopped servers still show their tools**: a server that is not running keeps the tool names and descriptions last seen (marked "as of last run"); one that has never run can be probed with "start server to read tools".
112
+ - **Secret masking**: keeps the first 4 characters and masks the rest as `****` (values of 4 chars or fewer become all `****`); "Reveal" needs a token.
113
+ - **Migrate & back up**: cross-project/global migration rolls back on failure; JSON export/import.
114
+ - **Status & notes enter the system prompt**: currently usable servers are listed; **one that has connected before but cannot right now is also listed and labelled** (`(当前未连上;上次连上时 N 个工具)`) — so the model says "it is not connected, check it" instead of reading "configured but unreachable" as "not configured here" and suggesting you install one. Servers that have never connected are omitted. Your notes travel along as decision hints; levels are "global / app", new servers default to global. Note: a persona-complete preset such as minimal suppresses that section — there the model reads server names, enablement, tool counts and notes with `mcp_manager_list`.
115
+
116
+ ### Skills
117
+
118
+ - **Sources at a glance**: project / DSH / Agents / Codex / Claude / custom dirs, grouped by source.
119
+ - **Opposite permissions**: default sources must be read but skills can be deleted; external dirs can be disabled/removed but skills are read-only.
120
+ - **Remove ≠ disable**: remove = directory not scanned at all (files untouched, restorable); disable = still listed but not callable.
121
+ - **Same-name skills: see which copy is in effect**: the winning copy is marked "preferred", shadowed ones name the source that wins, and enabling a shadowed copy says so instead of pretending it worked.
122
+ - **Custom dirs / ZIP import & export / recycle bin**.
123
+
124
+ ### Prompt presets
125
+
126
+ - Multiple `~/.dsh/AGENTS.md` baselines, one-click apply (the host re-reads that file every turn, so it takes effect on the next turn), 5-gen backup.
127
+ - **Remembers the preset applied last**: even after you hand-edit `AGENTS.md`, the model can still answer "which preset is this from" (flagged "changed since").
128
+ - **Description**: one line saying what a preset is for — shown in this panel only. It lives in a sibling `meta.json`, never in AGENTS.md, so it is never injected into prompts.
129
+ - Create with body inline, edit can change id (= dir rename, scene bindings follow). A referenced preset cannot be deleted (bound by a scene, currently in AGENTS.md, or the baseline to restore on scene exit); deletes go to recycle bin.
130
+ - **While a scene drives the baseline, Apply rebinds the scene to that preset** (written into the scene profile, and the binding realigns immediately; allowed while unlocked — v0.9 reversed the old "other presets are refused" behavior); **only locking refuses**. The global baseline is restored from the snapshot on scene exit.
131
+
132
+ ### Archived sessions
133
+
134
+ - Grouped by project, search, batch restore / delete, retention auto-cleanup.
135
+ - Workspace registration deleted → group rebuilt from session dirs, one-click re-register.
136
+ - Import Claude Code / Cursor / Codex / any text; export Markdown / JSONL.
137
+
138
+ ### Host compatibility
139
+
140
+ The plugin uses the host's own `@deepseek-ai/*` libraries at runtime — they must be the same physical modules, or every "adapt to host" decision degrades into guesswork.
141
+
142
+ - **Host tab**: host version, usable capability count, per-action routing (native/adapter/unavailable), degradations & reasons. Read-only.
143
+ - **Command line**: `node scripts/doctor.mjs` (check), `node scripts/host-deps.mjs --fix` (align deps), `npm run sync:profile` (mirror the build into the profile's local install — a `file:` install is a hard-linked copy, so files ADDED by a build never show up there on their own).
144
+ - Under a **suppressing preset** such as `minimal` (persona `complete` / runtime context off) this plugin's injection is **off by default** (following the preset's intent), and the prompt and the skills are missing because their official rows are not mounted — the Host tab marks this per column, and its "Injection" block can force any domain back on.
145
+ - **Unchecking "Skills" or "Prompt" really stops them**: under standard presets the host delivers those two itself (the plugin steps aside), so unchecking now also stops the host's copy — the `skill-catalog` / `agent-instructions` messages are no longer let through on that step. The other three domains (memory / MCP / subagents) are only ever sent by this plugin, so their toggles were already complete.
146
+ - **What an injection looks like**: one `<system-reminder>` per domain — a `##` title, a **bold one-line action** (the decision point at which to recall it), the tool name / trigger, then the body; any `</system-reminder>` inside the body is escaped (your own text cannot close the frame early). Each message ends with "this copy replaces the earlier one in this session" — injections are only re-sent when the content changes, so the older copy is still in context and the model must know which to trust. The wording follows Claude Code's and Codex CLI's official injections item by item.
147
+
148
+ ---
149
+
150
+ ## Where data lives
151
+
152
+ | Content | Location |
153
+ | --------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
154
+ | MCP definitions | `~/.dsh/cordis.patch.yml` (written by the plugin; pre-write copies land in the hub's `backups/`) |
155
+ | Skill policy / custom dirs | `~/.dsh/tool-management/skills-state.json` |
156
+ | Skills / memories / personas / presets | `~/.dsh/tool-management/{skills,memories,subagents,prompts}/` |
157
+ | Subagent toggles | `~/.dsh/tool-management/subagents-index.json` |
158
+ | Recycle bin | `~/.dsh/tool-management/trash/{skills,subagents,prompts,scenes}-trash/` |
159
+ | Archive ledger / retention | `~/.dsh/tool-management/history-*.json` |
160
+ | Memory index / scenes / profiles | `~/.dsh/tool-management/memories-index.json` |
161
+ | MCP sidecars (disabled tools / known tools / notes / settings) | `~/.dsh/tool-management/mcp-*.json` |
162
+ | Injection settings (five domain switches / suppressing-preset policy) | `~/.dsh/tool-management/inject-settings.json` |
163
+ | Runtime log / patch backups | `~/.dsh/tool-management/tool-management.log` · `backups/` |
164
+
165
+ **No user data is stored inside the plugin's install directory** (`dsh plugin update` replaces it wholesale).
166
+
167
+ ## Configuration & security
168
+
169
+ | Field | Description |
170
+ | -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
171
+ | `token` | Access token. When set, **all writes + plaintext secrets** require `x-dsh-token`; **unset = plaintext endpoints closed**. Also the escape hatch for curl / LAN. |
172
+ | `maxBodyBytes` | Request body cap, default 88 MiB. |
173
+
174
+ - **Browser**: reads/writes via cookie, no token needed; but **plaintext secrets** (Reveal / export) need a token.
175
+ - **curl / scripts**: send `x-dsh-token`, or carry the browser cookie.
176
+ - **Port forwarded to public**: configure a token — prevents strangers injecting MCP commands (≈ remote code execution) and stealing secrets.
177
+
178
+ ## FAQ
179
+
180
+ | Symptom | Fix |
181
+ | ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
182
+ | Pages missing after install | Hard refresh; restart DSH if that fails. |
183
+ | Duplicate MCP tabs | Remove the stale loader row from `cordis.patch.yml`, restart. |
184
+ | Broken config, DSH won't boot | Restore the newest `.bak-<timestamp>`. |
185
+ | Action stopped after DSH upgrade | Settings → Tools → **Host** for the reason; `doctor.mjs` → `host-deps.mjs --fix`. |
186
+ | Still asked to confirm in `approval=never`? | No card appears — straight through with a log line; switch back to "workspace write" to get asked again. |
187
+ | `subagent_manager_run` reports provider unavailable | The provider isn't registered: `spawn` (default) / `fork` (`inherit`) come from `@deepseek-ai/dsh-subagent-spawn-in-process` / `-fork-in-process` — mount and restart. |
188
+ | Scene binds persona A, but official `subagent` ran something else | Those two are host tools and this plugin cannot hide them; it writes the boundary into the context instead (work matching a persona goes to `subagent_manager_run`; host tools only when no persona fits or a background job is needed), and `inherit` now matches fork's context inheritance. |
189
+
190
+ ---
191
+
192
+ ## Development
193
+
194
+ ```bash
195
+ npm install
196
+ npm run build # tsc + sync client
197
+ npm test # build + i18n + smoke tests (mount & render)
198
+ npm run check:i18n # dictionary self-check
199
+ npm run doctor # host compatibility check
200
+ ```
201
+
202
+ `lib/` is not tracked — run `npm run build` after cloning. Changes need `dsh web` restarted. Runtime dep is only `fflate`; `@deepseek-ai/*` all come from the host.
203
+
204
+ ## License
205
+
206
+ MIT
Binary file
package/docs/images/1.png CHANGED
Binary file
Binary file
package/docs/images/2.png CHANGED
Binary file
Binary file
package/docs/images/3.png CHANGED
Binary file
Binary file
package/docs/images/4.png CHANGED
Binary file
Binary file
package/docs/images/5.png CHANGED
Binary file
Binary file
package/docs/images/6.png CHANGED
Binary file
Binary file
package/docs/images/7.png CHANGED
Binary file
Binary file
package/docs/images/8.png CHANGED
Binary file
package/docs/update.md CHANGED
@@ -4,6 +4,7 @@
4
4
 
5
5
  | 版本 | 发布 | 主题 |
6
6
  |---|---|---|
7
+ | [0.10.0](#0100---2026-09-18) | 2026-09-18 | 注入框架改 markdown(动作句加粗前置)+ 注入采纳统计 + 人设角色框 / inherit / catalogDepth + 场景锁定补齐模型侧 + 记忆删除全走回收站 + 错误码全量双语 |
7
8
  | [0.9.1](#091---2026-09-17) | 2026-09-17 | 注入实况 + 场景内开关同步档案 + 全选统一 + 退出场景卡死修复 |
8
9
  | [0.9.0](#090---2026-09-16) | 2026-09-16 | 注入改走上下文通道(极简可注入)+ 五域各自注入 + 场景接管一致性修复 |
9
10
  | [0.8.5](#085---2026-09-16) | 2026-09-16 | 历史页标签统一 + 目录存在即可重新登记 + 场景 MCP 备注 + 新增三域默认不启动 |
@@ -16,10 +17,48 @@
16
17
 
17
18
  ---
18
19
 
20
+ ## 0.10.0 - 2026-09-18
21
+
22
+ - **「注入实况」显示每个域的采纳统计**:「注入 N 次 · 调用 M 次 · 采纳 K 次」,勾了开关但模型从没伸手一眼可见;节头并标注本进程观测到的工具调用数,区分「模型没用」与「统计没接上」。
23
+ - **人设可配「目录注入」(`catalogDepth`)**:控制常驻人设目录注入到哪一层会话(默认只在顶层),不限制子代理继续嵌套。
24
+ - **人设子代理支持 `inherit`**:继承本次会话**已完成**的轮次(本轮内委派仍要写全任务);贴合人设的任务从此一律走 `subagent_manager_run`,官方 `subagent` / `subagent_fork` 只在没人设贴合或需要后台任务时用。
25
+ - **人设新增「输出要求」字段(`output:`)**:一行一条硬要求,单独成节写进子代理系统提示词,并约束父代理的 `task` 只给目标与上下文、不规定做法。
26
+
27
+ - **注入框架重排为 markdown 四级结构**:`##` 标题 + 加粗动作句前置 + 补充动作行 + 取代声明,五域同一副骨架;场景记忆与子智能体引导语同步重写(给判据、给优先级、补触发条件),正文重复标题与「已清空」通知的插件前缀一并去掉。
28
+ - **提示词注入不再「裸送」**:与其余四域同款框架且整条包进 `<system-reminder>`(正文里的闭合标记会转义),界面显示来源文件与载入状态,模型侧正文带「来源:」行。
29
+ - **关掉「技能」或「提示词」的勾选,官方那条注入一起停**(此前只停本插件自己);其余三域勾选完全生效。
30
+ - **子代理会话不再注入场景记忆**(只在顶层注入),子代理上下文收敛为「角色 + 任务」,需要时用 `memory_manager_*` 自取。
31
+ - **人设进子代理系统提示词时带角色框**:`# 角色:名` 标题 + 授权/边界一行 + `## 角色定义` 围栏,不含 `description`,人设文件本身不用改。
32
+ - **MCP 列表改为全局在前、同级按名排序**,页面、场景档案勾选器与模型侧清单三处同序。
33
+ - **人设目录的注入判据定为「深度 < `catalogDepth`」**;「注入实况」两档状态改称「已注入 / 不在本会话注入」,无正文行不再画展开箭头。
34
+ - **五个管理工具的描述回指上下文里的注入块**,目录与工具互相指路。
35
+ - **全部服务端错误码补齐双语词条**(此前 15 码无词条,英文界面回退中文原文);目录选择器与技能详情 frontmatter 标签同样改走词典。
36
+ - **README 安全段补充**:栅栏降级面、`dir-list` 暴露面、HTTP 状态码以 `body.ok` 为准、裸 API 退出场景不清启用集。
37
+ - **文档更正**:人设「默认停用」(此前写成自动启用)、场景接管期间「应用 = 改绑该场景」(此前写会被拒绝)、「四域开关同步档案」更正为三域(并更正 0.9.1 条目同句)、密钥打码字形改为与实现一致。
38
+
39
+ - **场景锁定补齐模型侧**:`mcp_manager_add` / `skill_manager_create` / `memory_manager_write` / `prompt_manager_apply` 四个工具此前绕过守卫,锁定期间仍可调用。
40
+ - **记忆怎么删都进回收站**:形态转换与改名此前直接删旧文件(bundle 连附件一起),现在先入回收站再删。
41
+ - **`mcpm-tools-refresh` 要求令牌**:它会临时启停服务器并写两次补丁,此前漏在写操作门清单外。
42
+ - **子代理结果不再混入思考块**;「没有正文」按收尾原因分档说明,不再一律报「无输出」。
43
+ - **人设正文与名字里的 `{{…}}` 不再让子代理启动失败**。
44
+ - **子会话里调委派工具不再被本插件拦下**(不再向官方传 `maxDepth`,人设列表也不再按深度过滤)。
45
+ - **MCP 状态不再把「连不上」报成「可用」**:可用性只认当前真实注册的工具数;曾连上、当前不可用的如实标注。
46
+ - **场景里手动关掉的技能目录 / MCP 服务器,退出场景后正常还原**(快照全量记录进场景前状态)。
47
+ - **覆盖导入失败自动回滚**;编辑 MCP 服务器保留手写的 `toolCallTimeoutMs`;整台停用时「上次运行时」工具行不再标「已启用」。
48
+ - **场景进行中改 MCP serverName 或人设名,退出场景恢复正常还原**;重启等待窗口内的并发启用不再被快照覆盖。
49
+ - **记忆描述含独立 `---` 行不再截断**(此类多行描述改用引号标量序列化)。
50
+ - **提示词页「应用」失败现在会显示错误**;手工编辑 memories-index.json 的场景描述会触发注入重算。
51
+ - **兼容页「注入实况」的说明不再截断、节头不再错位**;技能页页头按钮窄栏自动收档,「全选」不再折行。
52
+ - **访问令牌比较改为常量时间**(双侧 sha256 + timingSafeEqual)。
53
+ - **测试与开发工具**:补 parseModeState 透传契约断言;client-render 夹具对齐现行响应形状;check-i18n 修复行首键漏对账;`preview-memory-note` / `preview-compat` 修到可跑。
54
+ - **六个管理页的启用项排到列表前面**:MCP / 技能 / 子智能体 / 提示词 / 记忆 / 场景,开着的浮在上面、停用后落回原位(两半内部保持原顺序,不是按名重排;提示词页没有开关,按「生效中」排)。拨开关引起的换位有 180ms 过渡,搜索 / 筛选 / 折叠与轮询刷新引起的位移不做动画,「减少动态效果」下直接落位。
55
+
56
+ ---
57
+
19
58
  ## 0.9.1 - 2026-09-17
20
59
 
21
60
  - **兼容页新增「注入实况」**:直接看最近活跃会话里模型**实际收到**的五域文本,并分清「在上下文中 / 未投递 / 官方注入 / 已关闭」——勾了开关却没送到时一眼可见。
22
- - **场景里也能直接开关了**(未锁定时):MCP、技能、子智能体、提示词照常改——**改动会同步写进这个场景的档案**,当下生效、下次进这个场景也照样生效,退出仍按进场景前的状态还原;只有**锁定**才冻结。
61
+ - **场景里也能直接开关了**(未锁定时):MCP、技能、子智能体照常改——**改动会同步写进这个场景的档案**,当下生效、下次进这个场景也照样生效,退出仍按进场景前的状态还原;只有**锁定**才冻结。
23
62
  - **「全选」统一成二合一**:所有全选按钮都是「全选」↔ 点完变「取消全选」,不再并列两个;技能管理页、记忆管理页、记忆的每个场景卡片补上了缺的批量开关。
24
63
  - **技能管理页每个来源(目录)卡片也有批量开关**,点「全选」或卡片上的来源开关都会顺带把这张卡片展开——批量结果就在下面,不然点完只剩按钮改了字。
25
64
  - **人设也严格「退出即还原」**:场景里手动打开的人设,退出时会回到进场景前的状态(场景中新建的不受影响)。