dsh-plugin-tool-management 0.12.1 → 0.14.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/CHANGELOG.md +84 -0
- package/README.md +90 -114
- package/README_EN.md +98 -119
- package/docs/images/1-EN.png +0 -0
- package/docs/images/1.png +0 -0
- package/docs/images/2-EN.png +0 -0
- package/docs/images/2.png +0 -0
- package/docs/images/3-EN.png +0 -0
- package/docs/images/3.png +0 -0
- package/docs/images/4-EN.png +0 -0
- package/docs/images/4.png +0 -0
- package/docs/images/5-EN.png +0 -0
- package/docs/images/5.png +0 -0
- package/docs/images/6-EN.png +0 -0
- package/docs/images/6.png +0 -0
- package/docs/images/7-EN.png +0 -0
- package/docs/images/7.png +0 -0
- package/docs/images/8-EN.png +0 -0
- package/docs/images/8.png +0 -0
- package/docs/update.md +63 -0
- package/lib/client.js +1086 -95
- package/lib/compat/preset-reach.js +6 -3
- package/lib/context-inject.js +183 -59
- package/lib/index.js +501 -49
- package/lib/mcp/manager.js +118 -71
- package/lib/mcp/secret-guard.js +21 -0
- package/lib/mcp/state-section.js +19 -14
- package/lib/memories/archive-engine.js +199 -0
- package/lib/memories/constants.js +72 -8
- package/lib/memories/index-io.js +1 -1
- package/lib/memories/projection.js +67 -31
- package/lib/memories/service.js +17 -2
- package/lib/memories/snapshot.js +123 -22
- package/lib/op-registry.js +279 -0
- package/lib/ops/candidates.js +11 -0
- package/lib/ops/compat.js +23 -2
- package/lib/ops/sessions.js +1 -1
- package/lib/ops/state-doctor.js +115 -0
- package/lib/prompts/service.js +25 -2
- package/lib/request-gate.js +21 -78
- package/lib/scene-settings.js +17 -0
- package/lib/scenes/candidates.js +56 -0
- package/lib/skills/catalog.js +10 -5
- package/lib/skills/core.js +102 -0
- package/lib/skills/service.js +34 -2
- package/lib/subagents/catalog.js +9 -5
- package/lib/subagents/service.js +37 -4
- package/lib/subagents/tools.js +19 -5
- package/lib/tools/deps.js +15 -0
- package/lib/tools/mcp.js +291 -50
- package/lib/tools/memory.js +170 -19
- package/lib/tools/prompt.js +28 -14
- package/lib/tools/scene.js +351 -0
- package/lib/tools/skills.js +168 -14
- package/lib/tools/subagent.js +129 -3
- package/lib/tools/table.js +290 -0
- package/package.json +2 -2
package/README_EN.md
CHANGED
|
@@ -12,14 +12,13 @@
|
|
|
12
12
|
|
|
13
13
|
[简体中文](README.md) · **English** · [Changelog](CHANGELOG.md) · [Release overview](docs/update.md)
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
- Eight tabs: **Scenes**, **MCP**, **Skills**, **Subagents**, **Prompts**, **Memories**, **Sessions**, **Host**.
|
|
15
|
+
An **MCP, skills, scenes, memories, subagents, prompts & archived sessions** manager for DeepSeek Harness. Eight tabs: Scenes / MCP / Skills / Subagents / Prompts / Memories / Sessions / Host.
|
|
17
16
|
|
|
18
17
|
```sh
|
|
19
18
|
dsh plugin --profile web add dsh-plugin-tool-management@latest
|
|
20
19
|
```
|
|
21
20
|
|
|
22
|
-
Hard-refresh the browser (Cmd/Ctrl+Shift
|
|
21
|
+
Hard-refresh the browser (Cmd/Ctrl+Shift+R) afterwards — a **Tools** panel in Settings means it worked. The plugin only writes its own files, never touches skill sources, and your configuration survives restarts and upgrades.
|
|
23
22
|
|
|
24
23
|
---
|
|
25
24
|
|
|
@@ -38,22 +37,22 @@ Hard-refresh the browser (Cmd/Ctrl+Shift-R) afterwards — a **Tools** panel in
|
|
|
38
37
|
|
|
39
38
|
## Highlights
|
|
40
39
|
|
|
41
|
-
In one line: **
|
|
42
|
-
|
|
43
|
-
| Highlight
|
|
44
|
-
|
|
|
45
|
-
| One-click scene switch
|
|
46
|
-
| Memories reach the model
|
|
47
|
-
| Notes for MCP servers
|
|
48
|
-
| Disable a single tool
|
|
49
|
-
| Skills at a glance
|
|
50
|
-
| Subagent = one file, one role
|
|
51
|
-
| Several prompt presets
|
|
52
|
-
| Sessions no longer lost
|
|
53
|
-
| The model always sees it
|
|
54
|
-
| Lock it and relax
|
|
55
|
-
| Deleted is not gone
|
|
56
|
-
| Safe by default
|
|
40
|
+
In one line: **configure "work / writing / coding" each as a scene and switch the whole stack with one click — and the model always sees whatever this plugin manages.**
|
|
41
|
+
|
|
42
|
+
| Highlight | What it means |
|
|
43
|
+
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
44
|
+
| One-click scene switch | Each scene carries its own MCP / skills / personas / memories; entering applies them, leaving restores. The model can switch them for you too |
|
|
45
|
+
| Memories reach the model | A few `.md` files under a scene become its knowledge base — injected automatically, no copy-pasting |
|
|
46
|
+
| Notes for MCP servers | Write "if A is down, fall back to B" as a note; the model sees it every turn 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 your switches |
|
|
48
|
+
| Skills at a glance | The copy in effect is marked *preferred*; shadowed ones name the source that wins |
|
|
49
|
+
| Subagent = one file, one role | Write a role file and delegate to it; only the result comes back, and it never clutters your History |
|
|
50
|
+
| Several prompt presets | Keep multiple `AGENTS.md` baselines and switch with one click; each scene can bind its own |
|
|
51
|
+
| Sessions no longer lost | Archives grouped by project, searchable, batch-restorable; imports Claude Code / Cursor / Codex transcripts |
|
|
52
|
+
| The model always sees it | One context message per domain, republished only when the content changes. Under suppressing presets nothing is injected by default — force any domain on in the Host tab |
|
|
53
|
+
| Lock it and relax | Locking a scene makes create/update/delete across the five domains read-only until you unlock |
|
|
54
|
+
| Deleted is not gone | Skills / memories / personas / presets / scenes land in a recycle bin and can be restored (permanent session deletion is the exception) |
|
|
55
|
+
| Safe by default | Secrets masked, plaintext needs a token, only the plugin's own files are written. Masking is display-only — see Configuration & security |
|
|
57
56
|
|
|
58
57
|
## Quick start
|
|
59
58
|
|
|
@@ -61,7 +60,7 @@ Prerequisites: DSH installed (`dsh web` runs), Node.js ≥ 18.
|
|
|
61
60
|
|
|
62
61
|
```sh
|
|
63
62
|
dsh plugin --profile web add dsh-plugin-tool-management@latest # install / update
|
|
64
|
-
dsh plugin --profile web remove dsh-plugin-tool-management
|
|
63
|
+
dsh plugin --profile web remove dsh-plugin-tool-management # uninstall
|
|
65
64
|
```
|
|
66
65
|
|
|
67
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.
|
|
@@ -74,139 +73,119 @@ dsh plugin --profile web add dsh-plugin-tool-management@latest
|
|
|
74
73
|
Then remind me to hard-refresh the browser.
|
|
75
74
|
```
|
|
76
75
|
|
|
77
|
-
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).
|
|
78
|
-
|
|
79
|
-
---
|
|
80
|
-
|
|
81
76
|
## Features
|
|
82
77
|
|
|
83
78
|
### Scenes & memories
|
|
84
79
|
|
|
85
|
-
- **A scene = a group, a memory = a `.md` file
|
|
86
|
-
- **
|
|
87
|
-
- **Scene
|
|
88
|
-
- **Scene
|
|
89
|
-
- **
|
|
90
|
-
- **Import**: `.md` / `.zip` (
|
|
91
|
-
- **
|
|
92
|
-
- **
|
|
93
|
-
- **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`).
|
|
94
|
-
- **Scene lock**: once locked, create/update/delete across MCP / skills / subagents / memories / prompts is 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. **What freezes is the content, not the scene itself**: creating/deleting/renaming a scene, rebinding its prompt, switching the active set, recycle-bin restore and purge, MCP restart, export, injection settings and token settings are all outside the frozen list (they are not "content of the scene profile"). Switching the active set *is* refused while a locked scene is in effect — clearing it would leave the model-side write guard with nothing to check while the runtime still runs that scene's profile.
|
|
95
|
-
- **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).
|
|
80
|
+
- **A scene = a group, a memory = a `.md` file**: `memories/<scene>/<name>.md`, the whole body is injected; file names may be non-ASCII.
|
|
81
|
+
- **"Enabled" and "entered" are two axes.** Enabled decides which scene the injection follows (single-select; none enabled = only `global` and `_shared` inject). Entering applies the scene's whole MCP / skills / personas set and writes its bound prompt into `~/.dsh/AGENTS.md` (5 generations of backups, restored on exit). Both the UI toggle and `scene_manager_switch` move the two axes together.
|
|
82
|
+
- **Scene profile**: each scene combines MCP tools / skills / subagents / memories. The rule is *ticked = on, unchecked = off*, and a section that was never created means that whole domain is off. Leaving restores the pre-scene state verbatim. While a scene is active, the switches in those three domains still work and are written back into its profile; only locking freezes them.
|
|
83
|
+
- **Scene lock**: once locked, create/update/delete across MCP / skills / subagents / memories / prompts is read-only (UI disabled plus a server-side guard). Creating, renaming, binding a prompt, activating or entering a scene, the recycle bin, MCP restart and exports stay outside the frozen list. A scene must be running to lock, and a locked scene cannot be turned off until you unlock it.
|
|
84
|
+
- **Deleting a scene deletes its memories too**: record, profile and every memory land in one recycle-bin entry and come back as a whole. A running scene refuses deletion; renaming follows through to the directory and profiles.
|
|
85
|
+
- **Import / export**: `.md` / `.zip` (directory name = scene, bundles carry attachments); same names are skipped, never overwritten, and over-limit items are reported. Export packs the memories you tick and only reads source files.
|
|
86
|
+
- **Injection budget**: 128 KiB by default; oversized memories are skipped with a list. Deletes go to the recycle bin.
|
|
87
|
+
- **Subagent sessions do not receive memories**: memories are the parent's situation, not the facts a child needs. A child's context stays "persona + task" — put what it needs into the task. Other domains are unaffected (MCP / skills / prompts still inject; the persona catalog follows each persona's `catalogDepth`).
|
|
96
88
|
|
|
97
89
|
### Subagents
|
|
98
90
|
|
|
99
|
-
- **One file per persona**: `
|
|
100
|
-
- **
|
|
101
|
-
- **
|
|
102
|
-
-
|
|
103
|
-
- **
|
|
104
|
-
- **
|
|
105
|
-
- **
|
|
106
|
-
- **Persona catalog enters the system prompt**: names + descriptions only, so the model knows what it can delegate to; personas are renameable, scene bindings follow.
|
|
107
|
-
- **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.
|
|
91
|
+
- **One file per persona**: `subagents/<persona>.md`, frontmatter entirely optional. `output:` takes one requirement per line — a checkable output contract (format, severities, bans) gets followed where one abstract sentence does not.
|
|
92
|
+
- **The persona reaches the child inside a role frame**: the body is used verbatim under a `# Persona: <name>` heading with an authorization line and a boundary line (it governs *how* it works, not *what* it may do). The persona file itself needs no change.
|
|
93
|
+
- **Delegation**: `subagent_manager_run` runs with the persona, returns only its final result, and never enters History. By default the child starts fresh (so the task must be self-contained); with `inherit: true` it is seeded with this conversation's **finished** turns — not the current one, so a delegation made mid-turn still needs the full story.
|
|
94
|
+
- **On/off and catalog**: a disabled persona is neither injected nor visible to the model (file untouched); new / imported / restored personas start **disabled**. The catalog lists names and descriptions only, so the model knows what it can delegate to; personas are renameable and scene bindings follow.
|
|
95
|
+
- **Catalog injection depth (`catalogDepth`)**: default `1` = top-level sessions only; `2` also reaches subagent sessions; the UI's "No nesting limit" writes `99`. **It does not limit nesting** — how deep delegation may go is the host's decision, and this plugin never passes `maxDepth`.
|
|
96
|
+
- **Tool limits per agent preset**: one allow or deny list per preset (mutually exclusive). Two behaviours worth knowing: **an allow list is merged back with every currently running `mcp__*` tool**, so ticking only `read` will not stop an MCP server that exposes a shell; and **if none of the listed names exists right now, the result is "no restriction"** (fail-open). Naming the reserved `run_code` is stripped from the list with a note, because the host would throw and the subagent would never start.
|
|
97
|
+
- **Reasoning effort** sits next to *model* in the advanced options, and the available levels are declared by the selected model. After a model change, a level no longer offered is cleared and you are told. Leaving it empty while a model is set falls back to that model's own default — not the main session's level.
|
|
108
98
|
|
|
109
99
|
### MCP servers
|
|
110
100
|
|
|
111
|
-
- **CRUD
|
|
112
|
-
- **Per-tool switches**: disable individual tools (invisible to the model
|
|
113
|
-
- **Stopped servers still show their tools**:
|
|
114
|
-
- **
|
|
115
|
-
- **
|
|
116
|
-
- **Migrate & back up**: cross-
|
|
117
|
-
- **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`.
|
|
101
|
+
- **CRUD with immediate effect**: written into `cordis.patch.yml`, backed up before every change. Levels are global / project, and new servers default to global.
|
|
102
|
+
- **Per-tool switches**: disable individual tools (invisible to the model and blocked at call); whole servers support bulk.
|
|
103
|
+
- **Stopped servers still show their tools**: one that is not running keeps the names and descriptions last seen (marked "as of last run"); one that never ran can be probed with "start server to read tools".
|
|
104
|
+
- **Status and notes enter the context**: currently usable servers are listed, and **one that connected before but cannot right now is listed and labelled too** — so the model says "it is not connected, check it" instead of reading "configured but unreachable" as "not configured" and suggesting you install one. Servers that never connected are omitted; your notes travel along as decision hints.
|
|
105
|
+
- **Secret masking**: a credential is replaced **as a whole** by `••••••`, and only for keys that look sensitive; `$VAR` and `!!js` are indirections and stay readable, and a URL's query string becomes `?<redacted>`. "Reveal" needs a token. A masked value is never written back into the patch file — on save the plugin restores the stored value for any field you left alone, and refuses the whole save when a URL has nothing to restore from (a silently stripped query string would leave an address that connects but fails authentication).
|
|
106
|
+
- **Migrate & back up**: cross-level migration rolls back on failure; JSON export/import.
|
|
118
107
|
|
|
119
108
|
### Skills
|
|
120
109
|
|
|
121
|
-
- **Sources at a glance**: project / DSH / Agents / Codex / Claude / custom
|
|
122
|
-
- **Opposite permissions**: default sources
|
|
123
|
-
- **Remove ≠ disable**:
|
|
124
|
-
- **
|
|
125
|
-
- **Custom
|
|
126
|
-
- **Directories can be injected**: when a preset mounts no official skills-directory line (e.g. Minimal), this plugin's injection domain delivers them as a fallback, governed by the switches on the Host page (name + blurb; the body is still read from disk).
|
|
110
|
+
- **Sources at a glance**: project / DSH / Agents / Codex / Claude / custom directories, grouped by source.
|
|
111
|
+
- **Opposite permissions**: default sources are readable and their skills deletable; external directories can be disabled or removed but their files stay read-only.
|
|
112
|
+
- **Remove ≠ disable**: removing stops scanning the directory at all (nothing is written, restorable); disabling keeps it listed but uncallable.
|
|
113
|
+
- **Who wins a shared name**: the winning copy is marked "preferred", shadowed ones name the source that wins, and enabling a shadowed copy says plainly that it will not take effect.
|
|
114
|
+
- **Custom directories / ZIP import & export / recycle bin.**
|
|
127
115
|
|
|
128
116
|
### Prompt presets
|
|
129
117
|
|
|
130
|
-
- Multiple `~/.dsh/AGENTS.md` baselines, one
|
|
131
|
-
- **
|
|
132
|
-
-
|
|
133
|
-
-
|
|
134
|
-
- **
|
|
135
|
-
- **While a scene drives the baseline, Apply rebinds the scene to that preset** (bound by a scene, currently in AGENTS.md, or the baseline to restore on scene exit); deletes go to recycle bin.
|
|
136
|
-
- **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.
|
|
118
|
+
- Multiple `~/.dsh/AGENTS.md` baselines, applied with one click (the host re-reads that file each turn, so it lands next turn), with 5 generations of backups.
|
|
119
|
+
- **It remembers the last applied preset**: even after you hand-edit `AGENTS.md`, the origin is still reported (flagged "the file changed since").
|
|
120
|
+
- Each preset can carry a one-line description that lives in a sibling `meta.json` — shown in this panel, never injected.
|
|
121
|
+
- **A referenced preset cannot be deleted** (scene binding / current `AGENTS.md` content / the copy to restore on scene exit); deletes go to the recycle bin.
|
|
122
|
+
- **While a scene drives the baseline, Apply rebinds that scene** to the chosen preset (written into the scene profile, realigned immediately); it is refused only while the scene is locked. The global baseline is restored from the snapshot on exit.
|
|
137
123
|
|
|
138
124
|
### Archived sessions
|
|
139
125
|
|
|
140
|
-
- Grouped by project,
|
|
141
|
-
-
|
|
142
|
-
- Import Claude Code / Cursor / Codex / any text; export Markdown / JSONL. **An export is a readable transcript, not a full backup**: only user/assistant text blocks survive — tool calls, images, reasoning and token stats are dropped, and a `## User` line inside a Markdown body will be read as a turn boundary on re-import (the exporter does not escape it). Use archiving if you need the full record.
|
|
126
|
+
- Grouped by project, searchable, batch restore / delete, retention auto-cleanup; a workspace whose registration was deleted is rebuilt from the session directories and can be re-registered in one click.
|
|
127
|
+
- Import Claude Code / Cursor / Codex / any text; export Markdown / JSONL. **An export is a readable transcript, not a full backup**: only user/assistant text blocks survive — tool calls, images, reasoning and token stats are dropped. Use archiving when you need the full record.
|
|
143
128
|
|
|
144
129
|
### Host compatibility
|
|
145
130
|
|
|
146
|
-
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.
|
|
131
|
+
The plugin uses the host's own `@deepseek-ai/*` libraries at runtime — they must be the same physical modules, or every "adapt to the host" decision degrades into guesswork.
|
|
147
132
|
|
|
148
|
-
- **Host tab**: host version, usable capability count, per-action routing (native/adapter/unavailable), degradations
|
|
149
|
-
- **Command line**: `node scripts/doctor.mjs` (check), `node scripts/host-deps.mjs --fix` (align
|
|
150
|
-
- Under a **suppressing preset** such as `minimal
|
|
151
|
-
- **Unchecking "Skills" or "Prompt" really stops them
|
|
152
|
-
- **What an injection looks like**: one `<system-reminder>` per domain — a
|
|
133
|
+
- **Host tab**: host version, usable capability count, per-action routing (native / adapter / unavailable), degradations and reasons. The page has three write entries: **access token** (needs a restart), **injection settings**, **model tool table**.
|
|
134
|
+
- **Command line**: `node scripts/doctor.mjs` (health check), `node scripts/host-deps.mjs --fix` (align dependencies), `npm run sync:profile` (mirror the build into the profile's local install — a `file:` install is a hard-linked copy, so files a build *adds* never show up there on their own).
|
|
135
|
+
- Under a **suppressing preset** such as `minimal`, this plugin's injection is **off by default** (following the preset's intent) and the prompt and skills are absent because their official rows are not mounted — the Host tab marks this per column, and its Injection block can force any domain back on.
|
|
136
|
+
- **Unchecking "Skills" or "Prompt" really stops them** — under standard presets the host delivers those two itself, so unchecking also stops the host's copy. The other three domains are only ever sent by this plugin, so their toggles work as written.
|
|
137
|
+
- **What an injection looks like**: one `<system-reminder>` per domain — a `#` section title, then the body (MCP and subagents add one line each). The frame carries **only what is now**: no "when to recall me" instructions, no explanation of the other sections. Any `</system-reminder>` inside your content is escaped, and each message closes with "this copy replaces earlier copies of the same kind in this session" — injections are re-sent only when the content changes, so the model must be told which copy to trust.
|
|
153
138
|
|
|
154
139
|
---
|
|
155
140
|
|
|
156
141
|
## Where data lives
|
|
157
142
|
|
|
158
|
-
| Content
|
|
159
|
-
|
|
|
160
|
-
| MCP definitions
|
|
161
|
-
| Skill policy / custom dirs
|
|
162
|
-
| Skills / memories / personas / presets
|
|
163
|
-
| Subagent toggles
|
|
164
|
-
| Recycle bin (skills/personas/presets/scenes)
|
|
165
|
-
| Memory recycle bin
|
|
166
|
-
| Archive ledger / retention
|
|
167
|
-
| Memory index / scenes / profiles
|
|
168
|
-
| MCP sidecars (disabled tools / known tools / notes / settings)
|
|
169
|
-
| Injection settings (
|
|
170
|
-
|
|
|
143
|
+
| Content | Location |
|
|
144
|
+
| -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
|
|
145
|
+
| MCP definitions | `~/.dsh/cordis.patch.yml` (written by the plugin; pre-write copies land in the hub's `backups/`) |
|
|
146
|
+
| Skill policy / custom dirs | `~/.dsh/tool-management/skills-state.json` |
|
|
147
|
+
| Skills / memories / personas / presets | `~/.dsh/tool-management/{skills,memories,subagents,prompts}/` |
|
|
148
|
+
| Subagent toggles | `~/.dsh/tool-management/subagents-index.json` |
|
|
149
|
+
| Recycle bin (skills / personas / presets / scenes) | `~/.dsh/tool-management/trash/{skills,subagents,prompts,scenes}-trash/` |
|
|
150
|
+
| Memory recycle bin | `~/.dsh/tool-management/memories-trash/` (a directory at the hub root, not under `trash/`) |
|
|
151
|
+
| Archive ledger / retention | `~/.dsh/tool-management/history-*.json` |
|
|
152
|
+
| Memory index / scenes / profiles | `~/.dsh/tool-management/memories-index.json` |
|
|
153
|
+
| MCP sidecars (disabled tools / known tools / notes / settings) | `~/.dsh/tool-management/mcp-*.json` |
|
|
154
|
+
| Injection settings (six domain switches) | `~/.dsh/tool-management/inject-settings.json` |
|
|
155
|
+
| Model tool table (switched-off tools + saved sets) | `~/.dsh/tool-management/tool-table.json` |
|
|
156
|
+
| Scene page preference (preview card before entering a scene) | `~/.dsh/tool-management/scene-settings.json` |
|
|
157
|
+
| Runtime log / patch backups | `~/.dsh/tool-management/tool-management.log` · `backups/` |
|
|
158
|
+
|
|
159
|
+
**No user data is stored inside the plugin's install directory** (`dsh plugin update` replaces it wholesale). `backups/` keeps **5 copies per patch file** — the global patch and each profile patch count separately — so one bulk action can consume all five slots of a layer.
|
|
171
160
|
|
|
172
|
-
|
|
161
|
+
## Configuration & security
|
|
173
162
|
|
|
174
|
-
|
|
163
|
+
| Field | What it does |
|
|
164
|
+
| --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
165
|
+
| `token` | Access token. Once set, **every write and every plaintext credential** requires `x-dsh-token`; with no token the plaintext endpoints are closed entirely. Prefer not to keep it in the config? Use the `DSH_PLUGIN_TOOL_MANAGEMENT_TOKEN` environment variable. |
|
|
166
|
+
| `tokenDisabled` | `true` = the token stays in the config but is not enforced (this is the line written by "Turn protection off"). Writes no longer need it; revealing plaintext still does. Turning it back on needs no retype. |
|
|
167
|
+
| `maxBodyBytes` | Request body cap, 88 MiB by default. |
|
|
175
168
|
|
|
176
|
-
|
|
169
|
+
**Plaintext on disk (read this)**: masking is **display-only**. MCP `env` / `headers` and the plugin's own `token` stay in cleartext inside `~/.dsh/cordis.patch.yml` (and each profile copy), and every config change copies the **whole file** into `~/.dsh/tool-management/backups/` — unencrypted, never rotated, not even reclaimed on uninstall. One secret can therefore exist as `5 × (patch files holding it) + 1` plaintext copies. The token gate decides *who may read plaintext over HTTP*; it does nothing about *reading the files*, where the only real defence is your filesystem permissions. **To clean up: Settings → Tools → Host → "Clean old backups"** — pick how many to delete per layer and confirm once more in the dialog; only backup files are touched. You can also delete them by hand.
|
|
177
170
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
| `token` | Access token. When set, **all writes + plaintext secrets** require `x-dsh-token`; **unset = plaintext endpoints closed**. Also the escape hatch for curl / LAN. If you would rather not keep the token in the config file, set the `DSH_PLUGIN_TOOL_MANAGEMENT_TOKEN` environment variable instead (when both are present `config.token` wins; `tokenDisabled: true` disables both). |
|
|
181
|
-
| `tokenDisabled` | `true` = the token **stays in the config** but is not in effect (this is the line written by "Turn protection off"). Writes no longer require a token; plain-text reveal still does (the plain text *is* the credential). Switch it back on any time with "Turn protection on" — no need to retype it. |
|
|
182
|
-
| `maxBodyBytes` | Request body cap, default 88 MiB. |
|
|
183
|
-
|
|
184
|
-
- **Browser**: reads/writes via cookie, no token needed; but **plaintext secrets** (Reveal / export) need a token. **The token is managed under Tools → Compatibility → Access token** — a fixed entry point independent of the page. That block is one status pill + one plain sentence + three rows: the row label names the scope, the button names the verb, and the pill only answers "is protection on, is this run unlocked".
|
|
185
|
-
- **This run**: fill once, valid until DSH exits (stored in this browser only). Once accepted, the row turns into a green **Unlocked** chip plus Clear, right where the input was (it used to collapse to a lone Clear button, which read as "what I just typed is gone"); only then does the host accept this token and the two rows below become usable. The row is not shown at all while the host has no token (there is nothing to check it against).
|
|
186
|
-
- **Host config**: written into the profile's `cordis.patch.yml` (only those two lines change — comments and the `!!js` guard stay intact, and the previous file is backed up first); takes effect after a DSH restart. With no host token this row's button is the primary one ("Set token") and asks for the new token **twice** (a typo here means even you cannot match it). Once one is set, "Change token" opens a form with an extra **current token** field — changing it requires proving you know the current one, and being unlocked does **not** count (same rule as turning protection off): you must retype it in the form. The cursor lands in that field when the form opens; the three fields are **stacked** with Save/Clear below them (while the form is open it is the only row shown, and Enter submits), "Save new token" stays disabled until all three are filled, and a rejected token marks that field red.
|
|
187
|
-
- **Protection switch**: clicking "Turn protection off" opens an in-place confirm box (the only row shown while it is open — same rule as "Change token") that asks you to **type the current token again** (yes, even while unlocked — the already-verified credential in the request header does *not* count for turning protection off; otherwise one click right after unlocking would drop the guard). On confirm it only writes `tokenDisabled: true`, so **the token itself stays in the config** and "Turn protection on" brings it back without retyping. While off, writes no longer require a token; **plain-text reveal still requires it** (the plain text *is* the credential). Turning it on keeps the old rule: being unlocked, or having the token in the input box, is enough — otherwise anyone who can open the GUI could switch the protection off.
|
|
188
|
-
- **Delete token** (same row as "Change token"): removes both the `token` and `tokenDisabled` lines from the config, going back to the **never-set-up** state — writes need no token and plain-text secrets become unreadable again. It also opens an in-place confirm box asking for the current token, and the result honestly notes that "old backups still hold plaintext copies" (each backup is a full copy of the config; use "Clean old backups" in the page header to clear those too). Use the protection switch instead when you only want the gate off for now and want to keep the token.
|
|
189
|
-
- **Status pill**: No token yet / Protection off / Protection on · locked / Protection on · unlocked. When the config has been changed but DSH has not restarted, an amber banner below says so (the pill reflects the running process).
|
|
190
|
-
- **No "fill in the token" notice while the token is not in effect**: that notice stays only while something is actually gated (a token is in effect on the host). With the token off or unset it is dropped, and the panel's status pill tells you what is going on instead.
|
|
191
|
-
- **Where the notice appears**: the "missing or wrong access token" sentence (with its "Fill in token" button) exists **exactly once** — inside the dialog while one is open (that is what blocks your action, so it belongs in plain sight), just below the tabs otherwise. It does not depend on which page you are on or how that page renders errors, so no entry point (dialog submits, imports, exports, bulk actions) can lose it.
|
|
171
|
+
- **Browser**: reads and writes go through cookies, no token needed; **plaintext credentials** (reveal / export) do. The token is managed in the **Access token** block on the Host tab — filling it once unlocks the current run, writing it into the config needs a restart.
|
|
172
|
+
- **Every destructive direction asks for the current token again** (turn protection off / change / delete). Being unlocked this run does not count — otherwise anyone who can open the GUI could drop the guard.
|
|
192
173
|
- **curl / scripts**: send `x-dsh-token`, or carry the browser cookie.
|
|
193
|
-
- **HTTP status convention**: except for the fence's 401/403, a missing token or a business failure is **HTTP 200 + `{ ok: false, error }`** — branch on `body.ok`, not on the status code.
|
|
194
|
-
- **
|
|
195
|
-
- **`dir-list`'s exposure**: the "pick a folder" dialog walks directories through it, so any caller past the fence/token can list directories at **any absolute path** (read-only). That is by design, not a hole — but do not expose the port to an untrusted network.
|
|
196
|
-
- **Plaintext on disk (read this)**: masking is a **display-only** measure. MCP `env` / `headers` and the plugin's own `config.token` stay in cleartext inside `~/.dsh/cordis.patch.yml` (and its per-profile copy), and every config change copies the **whole file** into `~/.dsh/tool-management/backups/` (5 copies kept **per patch file**, unencrypted, never rotated, never reclaimed on uninstall) — one secret can end up as `5 × (patch files holding it) + 1` plaintext copies. The token gate decides *who may read plaintext over HTTP*; it does nothing about *reading the files*. Any local process with read access to that directory can take every credential at once. **To clean up: Settings → Tools → Compatibility → "Clean old backups"** (next to Refresh — the button itself shows the current count) — pick how many to delete **per layer** (N deletes that layer's N oldest; the tiers run up to that layer's current count, default 2) — each layer has its own group, so any total is reachable, odd ones included; each row states what would be left, and the dialog asks you to confirm once more, stating the total number of files in that confirmation. Only backup files are touched, never the live config. You can also delete old files under `~/.dsh/tool-management/backups/` by hand.
|
|
197
|
-
- **Port forwarded to public**: configure a token — prevents strangers injecting MCP commands (≈ remote code execution) and stealing secrets.
|
|
174
|
+
- **HTTP status convention**: except for the fence's 401 / 403, a missing token or a business failure is **HTTP 200 + `{ ok: false, error }`** — branch on `body.ok`, not on the status code.
|
|
175
|
+
- **Port forwarding**: when the host has no `connection` service the fence falls back to "loopback Host + same origin", which any local process can imitate with `Host: localhost`. If you forward the port to a LAN or the public internet, **configure a token** — a stranger injecting MCP commands is remote code execution. The `dir-list` call behind the folder picker lists any absolute path (read-only) under the same precondition.
|
|
198
176
|
|
|
199
177
|
## FAQ
|
|
200
178
|
|
|
201
|
-
| Symptom
|
|
202
|
-
|
|
|
203
|
-
| Pages missing after install
|
|
204
|
-
| Duplicate MCP tabs
|
|
205
|
-
| Broken config, DSH won't boot
|
|
206
|
-
| Action stopped after DSH upgrade
|
|
207
|
-
|
|
|
208
|
-
|
|
|
209
|
-
|
|
|
179
|
+
| Symptom | Fix |
|
|
180
|
+
| --------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
181
|
+
| Pages missing after install | Hard refresh; restart DSH if that fails. |
|
|
182
|
+
| Duplicate MCP tabs | Remove the stale loader row from `cordis.patch.yml`, restart. |
|
|
183
|
+
| Broken config, DSH won't boot | Restore the newest `cordis.patch.yml.<level>.bak-<timestamp>` from `~/.dsh/tool-management/backups/` (5 per patch file). |
|
|
184
|
+
| Action stopped working after a DSH upgrade | Settings → Tools → **Host** for the reason; `doctor.mjs` → `host-deps.mjs --fix`. |
|
|
185
|
+
| The model cannot call a tool it should have | Check the **Model tool table** on the Host tab — 15 tools ship switched off. The panel and scripts are unaffected either way. |
|
|
186
|
+
| Still asked to confirm with `approval=never`? | No card appears — straight through with a log line. Switch back to "workspace write" to get the questions again. |
|
|
187
|
+
| `subagent_manager_run` reports provider unavailable | The provider is not 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 the 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. |
|
|
210
189
|
|
|
211
190
|
---
|
|
212
191
|
|
|
@@ -215,14 +194,14 @@ The plugin uses the host's own `@deepseek-ai/*` libraries at runtime — they mu
|
|
|
215
194
|
```bash
|
|
216
195
|
npm install
|
|
217
196
|
npm run build # tsc + sync client
|
|
218
|
-
npm test # build + i18n + contract tests (pure-function invariants & host contracts
|
|
197
|
+
npm test # build + i18n + contract tests (pure-function invariants & host contracts)
|
|
219
198
|
npm run check:i18n # dictionary self-check
|
|
220
199
|
npm run doctor # host compatibility check
|
|
221
200
|
```
|
|
222
201
|
|
|
223
202
|
`lib/` is not tracked — run `npm run build` after cloning. Changes need `dsh web` restarted. Runtime deps: `fflate` (export bundling) and `js-yaml` (parse check before writing host patches, loaded lazily); `@deepseek-ai/*` all come from the host.
|
|
224
203
|
|
|
225
|
-
> **Deployment note**: the profile mirror produced by `npm run build` does **not** include `node_modules`, so a runtime dependency added locally (e.g. `js-yaml`) must either be installed on the profile side or accepted as "patch-write check skipped and reported" — the missing checker only disables that one safety net
|
|
204
|
+
> **Deployment note**: the profile mirror produced by `npm run build` does **not** include `node_modules`, so a runtime dependency added locally (e.g. `js-yaml`) must either be installed on the profile side or accepted as "patch-write check skipped and reported" — the missing checker only disables that one safety net and never blocks writes. Regular `npm install` deployments are unaffected.
|
|
226
205
|
|
|
227
206
|
## License
|
|
228
207
|
|
package/docs/images/1-EN.png
CHANGED
|
Binary file
|
package/docs/images/1.png
CHANGED
|
Binary file
|
package/docs/images/2-EN.png
CHANGED
|
Binary file
|
package/docs/images/2.png
CHANGED
|
Binary file
|
package/docs/images/3-EN.png
CHANGED
|
Binary file
|
package/docs/images/3.png
CHANGED
|
Binary file
|
package/docs/images/4-EN.png
CHANGED
|
Binary file
|
package/docs/images/4.png
CHANGED
|
Binary file
|
package/docs/images/5-EN.png
CHANGED
|
Binary file
|
package/docs/images/5.png
CHANGED
|
Binary file
|
package/docs/images/6-EN.png
CHANGED
|
Binary file
|
package/docs/images/6.png
CHANGED
|
Binary file
|
package/docs/images/7-EN.png
CHANGED
|
Binary file
|
package/docs/images/7.png
CHANGED
|
Binary file
|
package/docs/images/8-EN.png
CHANGED
|
Binary file
|
package/docs/images/8.png
CHANGED
|
Binary file
|
package/docs/update.md
CHANGED
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
| 版本 | 发布 | 主题 |
|
|
6
6
|
| ---------------------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
7
|
+
| [0.14.0](#0140---2026-09-23) | 2026-09-23 | 场景与记忆分家(共 20 条工具)+ 模型能进入 / 退出场景 + 场景档案对模型可见、改档案会报出被挤掉的项 + 注入只写"现在是什么"(省 21.9%)+ 十五条工具出厂默认关(每轮实发 5 条 ≈1,090)+ 工具表可存方案一键换回 + 人设思考强度 + 改 MCP 配置不碰明文凭据 + 提示词「生效中」修好 |
|
|
8
|
+
| [0.13.0](#0130---2026-09-23) | 2026-09-23 | 模型多五个管理工具 + 所有写操作都要用户点头 + 工具表可关(省 token)+ 进场景前先看一眼会改什么 + 悬空引用体检 + 注入实况改为只数当前这段对话 + 技能正文一步读到 + 记忆页显示体积 + 门禁清单合成登记表 + 自定义目录的技能修好
|
|
7
9
|
| [0.12.1](#0121---2026-09-22) | 2026-09-22 | 子智能体列表行:人设名与描述分行 + 客户端类型检查进门禁 + 四个注入上限抬高 |
|
|
8
10
|
| [0.12.0](#0120---2026-09-20) | 2026-09-20 | 兼容页「功能总览」+ 停用工具真的从模型工具表消失 + 补丁写入前做解析校验(拦"写坏 DSH")+ doctor 三项新检查(挂载心跳 / 裸模块名 / 版本栅栏)+ 删除入口先不切换 + 投影缓存屏障与删除前置检查加固 + 关域拦截顺序钉死 |
|
|
9
11
|
| [0.11.0](#0110---2026-09-20) | 2026-09-20 | 访问令牌卡片重构(可设置 / 关闭 / 修改 / 删除)+ 没解锁时锁住输入框 + 令牌安全修复 + 批量启停可撤销 + 兼容页清理旧备份 + 两页可搜索 + 体检改为真调 + 一批凭据与数据损坏修复 + 搜索与列表提速 |
|
|
@@ -20,6 +22,67 @@
|
|
|
20
22
|
|
|
21
23
|
---
|
|
22
24
|
|
|
25
|
+
## 0.14.0 - 2026-09-23
|
|
26
|
+
|
|
27
|
+
- **场景和记忆分家了**:工具上是两族(记忆 4 条、场景 3 条 —— `_list` 查、`_switch` 进入 / 退出、`_save` 建与改),注入上是两段(「场景」讲当前启用的是哪个、它是什么;「记忆」讲各场景下的条目)。好处有两个:能**单独关掉记忆段**而保留场景说明;模型终于能查场景、配场景、进 / 退场景。注意写档案**不会**让场景生效 —— 生效要进入它。
|
|
28
|
+
|
|
29
|
+
- **模型能进入 / 退出场景**(`scene_manager_switch`):以前它看得到场景、却只能说一句"请你到界面上点"。现在你说"切到写作场景",它就能按该场景的档案把 MCP / 技能 / 人设整套拨到位、注入收窄成这个场景的记忆、把绑定的提示词写进 `AGENTS.md`;退出按进场景前的快照还原。它改的是整个运行时环境(和你在界面上点那一下同一条路径),所以**默认要你确认**。
|
|
30
|
+
|
|
31
|
+
- **改场景档案之前,模型能先看到现在勾了什么**:`scene_manager_list` 列出每个场景的档案、绑的预设、锁没锁、几条记忆。保存是**整段替换**,以前它想"再加一台服务器"就会把你原来勾的**静默挤掉**、回执还写着成功;现在回执会列出被挤掉的项(`mcp 4 项 → 2 项(-B、-C)`)。
|
|
32
|
+
|
|
33
|
+
- **注入的套话全削了,只留"现在是什么"**:把四次实际注入摊开量过 —— 四个板块 823 token/轮,**真正的内容只占 46%**,其余是"我是谁、什么时候看我、以我为准"。于是六个板块开头那句加粗的"什么时候该想起我"全删(它们是指令,不是当前情况)、机制解释删、四种措辞的权威声明并成一句。现在 **643 token/轮(省 180,−21.9%)**。层级也理清:板块 `#` / 场景 `##` / 条目 `-`,一眼看得出主次。
|
|
34
|
+
|
|
35
|
+
- **工具改名并合并:还是 20 条,但每族只管一件事**。五个「新建」并成 `_save`(有则改、无则建),六个域的开关统一叫 `_switch`,场景自成一族。**旧名不留别名**(别名要常驻每轮请求)。你以前"关掉了某条工具"的设置会自动搬到新名字上,包括存下的方案。
|
|
36
|
+
|
|
37
|
+
- **十五条工具出厂就是关着的**:每轮真正发出去的只剩 **5 条 ≈1,090** token(整表 ≈3,769)。关的是三个「保存」、提示词两条、三个目录查询、`memory_manager_read`、场景三条与三个启停开关 —— 判据是**这些信息或动作常态下由注入段和面板承担**,平时用不到模型自己伸手。**`mcp_manager_switch` 留着**("这台先给我关了"最常用)。代价摆明:注入的目录只列当前可用的,所以"没开的服务器 / 被同名覆盖的技能 / 没进上下文的记忆正文"在会话里查不到,模型也不再替你拨那三个启停。这条默认**只在你从没动过那一页时生效**,存过的选择不会被更新盖掉;「兼容」页可逐条打开。
|
|
38
|
+
|
|
39
|
+
- **工具表的开关能成批存下来、一键换回**:「模型工具表」合计行右侧多了**「保存方案」/「恢复方案」**。存的时候起个名字,以后点一下就整套换回,不用挨个点二十个框。**名字不能重复**(保存永不覆盖已有那份)。清单第一条永远是**出厂默认**,它不写在文件里、也就删不掉;自己存的方案可以在同一个弹窗里删。每行都写着"开着几条 · 一轮大约多少 token"。
|
|
40
|
+
|
|
41
|
+
- **MCP 与技能补了几处模型侧能力**:改一台已配置的服务器(只改 URL 就只给 URL,其余字段与密钥原样保住)、只停某个工具、顺手写备注;技能能整目录启停、能改本插件自己写的那份。
|
|
42
|
+
|
|
43
|
+
- **人设多了「思考强度」**:在高级选项里与「模型」并排。档位是模型自己声明的,所以换模型要重新选;选了新模型之后旧档位若不在新清单里,会**自动清掉并告诉你**(留着下一次委派会被直接拒)。**指定了模型时留空不会沿用主会话那一档**,而是回落到该模型自己的默认。
|
|
44
|
+
|
|
45
|
+
- **提示词页的「生效中」修好了**:场景接管时,模型拿到的清单以前报"文件里是它"、界面报"场景绑的那份",同一件事两个答案。现在两边同源,清单里还会标出"文件里是它、但基线由场景驱动"这种真实状态。
|
|
46
|
+
|
|
47
|
+
- **几处显示毛病**:记忆正文改成代码块包住(正文里手写的 `#` 以前会渲染成大标题、盖过场景分组);子智能体高级选项折叠后的摘要固定排两行(不再把「高级选项」挤成竖排);提示词预设的描述框补上字数上限。
|
|
48
|
+
|
|
49
|
+
- **给模型的话对齐了事实,指的路都能走通**:应用提示词的回执以前说"下个会话生效",实际**下一轮就生效**(模型会白劝你重开会话);场景保存的参数说明还引用着已被删掉的"注入后模型会照办"那句,改成了如实说明去向;工具描述与回执不再点名出厂默认关掉的工具(改用中性说法,或按开关在不在分叉——只在你真开了那条工具时才点名它);两条清单工具的描述也对齐了各自真实给的东西。新增一条契约测试,把"描述点名被关工具"这类静默毛病挡在构建里。
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## 0.13.0 - 2026-09-23
|
|
53
|
+
|
|
54
|
+
- **模型能管的比以前多了五个**:以前它看得到一份记忆、看得到一个人设,却开关不了也改不了(技能与 MCP 那两域早就能全操作)。现在记忆的启停与修改、人设的启停与新建修改都补上了。提示词按裁定只留「应用」。
|
|
55
|
+
|
|
56
|
+
- **所有会改东西的工具都写明了"要用户开口或先同意"**。以前只有两个工具有这句话,其余靠确认门兜 —— 而那个门是可以关掉的(设置里关掉记忆确认,或会话走「完全权限」预设)。顺带把工具说明删瘦了一圈:这些文字每次请求都要发给模型,八个改过的存量工具加起来从 2,047 → 1,980 字节,**加了上面那句还净降 67**。
|
|
57
|
+
|
|
58
|
+
- **点「进入场景」会先弹一张卡**:说清这次会启用/停用哪几台 MCP 服务器、哪几个工具、哪几个技能目录与技能、哪几个人设,以及记忆范围收窄到哪一场景;末尾再补两行"进入后是什么样"——**启用 N 台 MCP**、**启用 N 条记忆**(含公共基线与全局)。不想看这张卡就点「不再显示」(场景页右上角有「关闭提醒 / 开启提醒」可以随时改回来);卡上只有「确认进入」与「不再显示」两颗按钮,关掉卡片用右上角的「关闭」。只有**真的会变**的才列:没在跑的服务器不会被写成「停用 N 个工具」,技能也只显示名字(不再带 `custom-…` 那串机器名)。
|
|
59
|
+
|
|
60
|
+
- **改名留下的"悬空引用"有地方说了**:档案里存的是服务器名、技能名、人设名,场景记录里存的是预设 id。你把「代码审查」改名「复核员」,档案里那行还是旧名 —— 界面看着还绑着,委派时按新名找不到。现在场景页顶部会有一条黄横幅说清"哪一条指向谁、那个谁不在了"。只数出来、不自动改。
|
|
61
|
+
|
|
62
|
+
- **读技能正文少了一步**:新工具按名字一次给到正文和路径,而且按与目录同一套规则挑副本 —— 同名几份时读到的就是真正生效的那一份,不会读到被覆盖的影子。
|
|
63
|
+
|
|
64
|
+
- **工具说明可以关掉不发**:工具表每一轮请求都随工具发一遍,20 个工具的说明合计约 3,500 token,这一轮用不上也照付。兼容页新增「模型工具表」,逐个勾选(也能按域全关),关掉的**整份不进请求**——这是唯一真省钱的办法,默认一个都不关。关掉之后模型调不到它,**但插件面板一切照旧**(关掉 `mcp_manager_add` 之后 MCP 页照样能加服务器)。
|
|
65
|
+
|
|
66
|
+
- **有一个工具会自动让位**:技能那条「按名字读正文」在会话里已经有官方 `skill` 工具时不再下发——两份干的是同一件事。极简模式没有官方那件,我们的照旧留着。只影响那个会话的工具表,能力不减(管理视角的"读一个被关掉的技能"在面板里做)。
|
|
67
|
+
|
|
68
|
+
- **注入实况那三个数改成只数「最近这一段对话」**:以前是开机以来一路累加,用一下午之后「注入 8 次 · 从未调用」讲的是"今天这台机器",而你打开面板问的是"眼前这段里模型用没用"。现在每段对话各记一本账,换一段重新数。
|
|
69
|
+
|
|
70
|
+
- **记忆页每行显示正文体积**:记忆是唯一直接进上下文、直接吃预算的那一域(每个场景段 128 KiB),以前看不出哪条大。
|
|
71
|
+
|
|
72
|
+
- **场景描述能写到 300 字了**(原来 60),输入框下面那句提示删掉了 —— 卡片上那行本来就用省略号截,60 卡的是"能存多少",给的理由说的却是"显示多少"。四个注入上限也重新校准:记忆段 256 → 128 KiB;技能 / 子智能体 / MCP 三条目录都收到 50;MCP 备注 200 → 300 字。
|
|
73
|
+
|
|
74
|
+
- **界面补了四处小东西**:新增 MCP 服务器的弹窗能顺手写备注了;MCP 备注、人设描述、技能描述、记忆描述五处输入加了「当前 / 总字数」(分母就是模型实际能读到的长度);场景页加了搜索框;`/` 聚焦搜索框、Esc 清空它(只挂在插件自己那块 UI 上,不抢宿主的快捷键)。
|
|
75
|
+
|
|
76
|
+
- **门禁那几份清单合成了一张登记表**:哪些 op 要令牌、哪些在场景锁定时不许动、哪些改完要同步进场景档案……原来是五份各自抄写的名字清单,加一个新 op 得记得挨个补,这事已经漏过四次(后果不是报错,是"没配令牌也能改"或者"锁定的场景还能改")。现在每个 op 只登记一次,那五份清单都从它生成,派生结果与改之前**逐条相同**。启动时还会反查一遍登记表,有 op 没登记、有登记留着但 op 早改名了,都在兼容页挂提示。
|
|
77
|
+
|
|
78
|
+
- **自定义技能目录里的技能能调动了**:以前列表里看得到、也标着"已启用",模型一调却报"没有这个技能"。原因是两处用了不同的来源清单 —— 取正文时只查那五个固定目录,你添加的自定义目录永远落空。
|
|
79
|
+
|
|
80
|
+
- **「采纳」这个数改准了**:以前你把某个域关掉之后模型去调它的工具,照样记一次采纳 —— 因为「××已清空」那条通知也带着域标记,被当成了"正文在眼前",第三列其实是第二列的复印件。现在通知不算正文了,「调用 − 采纳」才有得读。
|
|
81
|
+
|
|
82
|
+
- **README 里有一处说错了,已改**:原文说子智能体那两个工具"依赖宿主挂载 provider 包,缺席时不注册、界面也不提示"。实际是注册不受影响,要到**调用的那一刻**才报"子代理服务未挂载";而真的注册失败时,界面上**是**有提示的。
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
23
86
|
## 0.12.1 - 2026-09-22
|
|
24
87
|
|
|
25
88
|
- **子智能体页的列表行改了版式**:人设名与描述分成两行。以前名字和描述挤在同一横排里、右边还压着开关和两颗按钮,名字只剩两三个字符宽(显示成 `co...`);现在名字独占一行、装不下才按省略号截断(悬停看全名)。
|