dsh-agent-plugins-market 0.9.1 → 0.9.2

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.md CHANGED
@@ -1,242 +1,140 @@
1
- <img src="assets/dsh-agent-plugins.png" alt="Agent Plugins" width="64" height="64" />
1
+ <img src="https://raw.githubusercontent.com/Sivan757/dsh-agent-plugins-market/main/assets/dsh-agent-plugins.png" alt="Agent Plugins" width="64" height="64" />
2
2
 
3
3
  # Agent Plugins
4
4
 
5
5
  `dsh-agent-plugins-market`
6
6
 
7
- **A one-stop skills, subagent, MCP and LSP manager inside [DeepSeek Harness (DSH)](https://github.com/deepseek-ai/deepseek-harness), compatible with Claude Code, Codex, Cursor, Kimi and other agent plugin layouts.**
7
+ **A one-stop skills, subagent, MCP and LSP manager inside [DeepSeek Harness (DSH)](https://github.com/deepseek-ai/deepseek-harness).**
8
8
 
9
- Reuse supported content from Claude Code, Codex, Cursor, Kimi and other recognized layouts, and manage your own skills, commands, agent personas, MCP services and LSP servers in the DSH Web GUI.
9
+ Run Claude Code, Codex, Cursor, Kimi and agent-plugins suites inside DSH. The plugin reads each layout in place, so you convert no manifest and copy no file. Install it from the DSH Web GUI, then manage skills, commands, agent personas, MCP services and LSP servers in one workspace.
10
10
 
11
11
  If this plugin is useful to you, a ⭐ on [GitHub](https://github.com/Sivan757/dsh-agent-plugins-market) is appreciated.
12
12
 
13
13
  English | [简体中文](README.zh.md) | [Documentation](https://sivan757.github.io/dsh-agent-plugins-market/) | [npm](https://www.npmjs.com/package/dsh-agent-plugins-market)
14
14
 
15
- [![npm version](https://img.shields.io/npm/v/dsh-agent-plugins-market)](https://www.npmjs.com/package/dsh-agent-plugins-market) [![License](https://img.shields.io/github/license/Sivan757/dsh-agent-plugins-market)](LICENSE)
15
+ [![npm version](https://img.shields.io/npm/v/dsh-agent-plugins-market)](https://www.npmjs.com/package/dsh-agent-plugins-market) [![License](https://img.shields.io/github/license/Sivan757/dsh-agent-plugins-market)](https://github.com/Sivan757/dsh-agent-plugins-market/blob/main/LICENSE)
16
16
 
17
- [Quick start](#quick-start) · [Everyday use](#everyday-use) · [Compatibility](#compatibility-and-boundaries) · [FAQ](#faq)
17
+ [Quick start](#quick-start) · [Highlights](#highlights) · [Everyday use](#everyday-use) · [Compatibility](#compatibility) · [FAQ](#faq)
18
18
 
19
19
  ## Pages
20
20
 
21
21
  <table>
22
22
  <tr>
23
23
  <td align="center" width="33%">
24
- <img src="docs/screenshots/market.png" alt="Market" width="100%" /><br />
24
+ <img src="https://raw.githubusercontent.com/Sivan757/dsh-agent-plugins-market/main/docs/screenshots/market.png" alt="Market" width="100%" /><br />
25
25
  <b>Market</b><br />Add sources, preview suites, install and enable.
26
26
  </td>
27
27
  <td align="center" width="33%">
28
- <img src="docs/screenshots/skills.png" alt="Skills" width="100%" /><br />
28
+ <img src="https://raw.githubusercontent.com/Sivan757/dsh-agent-plugins-market/main/docs/screenshots/skills.png" alt="Skills" width="100%" /><br />
29
29
  <b>Skills</b><br />Browse skills and author your own.
30
30
  </td>
31
31
  <td align="center" width="33%">
32
- <img src="docs/screenshots/commands.png" alt="Commands" width="100%" /><br />
32
+ <img src="https://raw.githubusercontent.com/Sivan757/dsh-agent-plugins-market/main/docs/screenshots/commands.png" alt="Commands" width="100%" /><br />
33
33
  <b>Commands</b><br />Manage prompt templates invoked as /name.
34
34
  </td>
35
35
  </tr>
36
36
  <tr>
37
37
  <td align="center" width="33%">
38
- <img src="docs/screenshots/personas.png" alt="Agent personas" width="100%" /><br />
38
+ <img src="https://raw.githubusercontent.com/Sivan757/dsh-agent-plugins-market/main/docs/screenshots/personas.png" alt="Agent personas" width="100%" /><br />
39
39
  <b>Agent personas</b><br />Roles with an exact provider, model and effort.
40
40
  </td>
41
41
  <td align="center" width="33%">
42
- <img src="docs/screenshots/mcp.png" alt="MCP services" width="100%" /><br />
42
+ <img src="https://raw.githubusercontent.com/Sivan757/dsh-agent-plugins-market/main/docs/screenshots/mcp.png" alt="MCP services" width="100%" /><br />
43
43
  <b>MCP services</b><br />Credentials, authorization and connection status.
44
44
  </td>
45
45
  <td align="center" width="33%">
46
- <img src="docs/screenshots/lsp.png" alt="LSP servers" width="100%" /><br />
46
+ <img src="https://raw.githubusercontent.com/Sivan757/dsh-agent-plugins-market/main/docs/screenshots/lsp.png" alt="LSP servers" width="100%" /><br />
47
47
  <b>LSP servers</b><br />Language server configuration and runtime status.
48
48
  </td>
49
49
  </tr>
50
50
  </table>
51
51
 
52
- ## What you can do
52
+ ## Quick start
53
53
 
54
- - Enable the experimental Agent preset manager in plugin settings to show its composer entry. It is off by default and does not disable the session runtime. Session extension presets select skills, commands, roles, MCP and LSP capabilities through the Agent extension icon button to the right of Permissions. Each workspace owns a preset library and a default for new sessions. Selecting a preset while a session runtime is active takes effect on that session's next user request. Mid-turn steering and tools do not change. Once the selection commits, the open slash skill menu refreshes without another keystroke or page reload. Editing the selected or pending preset in the current session updates that session. Every other session keeps its own detached copy. Copy and paste a preset to another workspace to create an independent copy. Globally managed resources show their actual state without a session switch. Preset details do not change shared credentials or configuration. After a failed session selection, explicit recovery restores readiness and continues queued user input without another Send.
54
+ 1. In the DSH Web GUI, open **Plugins** in the sidebar.
55
+ 2. Press **Add plugin**, type `dsh-agent-plugins-market`, then install it. The same dialog accepts a repository URL or a local directory.
56
+ 3. Restart DSH, then open **Settings → Agent Plugins**.
57
+ 4. The market already lists one first-party source. Press **Refresh** to fetch its suites. To bring in more, add a source such as `https://github.com/anthropics/claude-plugins-official`.
58
+ 5. Open a suite, review its contents, then install it and keep it enabled. Skills appear in the **Skills** tab and in the `/` menu. Answer any credential notice on **MCP services** before you use that suite's tools.
55
59
 
56
- - **Ten suite layouts.** Claude Code, Codex, Cursor, Kimi Code, ZCode, Qoder CLI, GitHub Copilot CLI, Universal `.plugin/`, [agent-plugins](https://agent-plugins.org) and manifest-less skill collections.
57
- - **Sources.** Add a Git repository, a local directory or an archive (`.zip` / `.tar.gz` / `.tgz` / `.tar`); adopt a checkout you cloned yourself; refresh on demand; delete a managed checkout when you remove its source.
58
- - **First-party source.** The plugin presets one source record pointing at its own suite collection, so the market lists that repository on first run with no URL to paste. It is an ordinary Git source from there on — refresh it to fetch, then install and toggle its suites like any other.
59
- - **Downloads that fit your network.** Pick a download region — default `auto` follows the interface language, or choose global / China mainland — and the plugin routes `github.com` clones through the matching mirror. A proxy and per-invocation tuning live in the host config.
60
- - **Runtime surfaces.** Enabled suites inject into sessions: skills into the catalog and slash menu, commands as `/name`, agent personas into the subagent catalog, MCP tools with an `mcp__` prefix, hooks onto host lifecycle events, and language servers through the `lsp` tool.
61
- - **MCP.** A built-in bridge runs stdio, Streamable HTTP with OAuth and legacy SSE without a host MCP client. `${VAR}` references resolve from the host credential store or the launch environment; per-server overrides disable or patch a declaration without editing the source, set the tool-call and startup timeouts, and switch individual tools off; creation and editing share the same service form, including advanced timeout settings and a JSON view; an optional host-client compatibility mode is available. A suite's tools register as `mcp__<suite>__<server>__<tool>`; a server you declare yourself in `~/.agents/mcp.json` mounts under its own key, `mcp__<server>__<tool>`.
62
- - **LSP.** Self-provisioned: installing the plugin is the whole setup, and the `lsp` tool mounts only while a language server is wanted. The server executable itself must be on `PATH`. Upgrading from a release that asked you to expose LSP from your profile? A profile that still carries that hand-added layer reports a seam conflict; the LSP panel names the file and removes the layer for you, keeping a backup.
63
- - **Agent personas and delegation.** Role cards keep their instructions and exact provider/model/effort settings. Without Agent Teams, use `subagent_role`; with Agent Teams, use `spawn_teammate_role` to create a real Team member and manage it through native Team tools.
64
- - **Project dimension.** Skills, agents, commands, MCP servers and hooks are read from the project's own directories with no install step.
65
- - **Your own resources.** Author skills, commands and agent personas as Markdown under `~/.agents/`, then edit them or disable them without deleting the files.
66
- - **Background source updates.** Optionally refresh every configured source on a timer; off by default.
67
- - **Web workspace.** Seven tabs: Market, Skills, Commands, Agent personas, MCP services, LSP servers and Hooks, each with search, filters and a grid/list toggle, plus status panels with diagnostics, credential editing, and an install confirmation that warns before executable third-party content is enabled. The settings page is the canonical layout. Every surface shares one tab row of equal columns that never scrolls sideways, and a label that does not fit ellipsizes. Every surface also shares one card and detail anatomy, and the preset manager follows it.
68
- - **Bilingual interface and feedback.** Workspace strings and injected prompts follow the host language. With feedback enabled, the model can file a `report_market_issue` report through the `gh` CLI or a GitHub token; with neither, it opens a prefilled GitHub issue page and hands you the complete issue text.
69
- - **Translation.** Descriptions and expanded documents can follow the Chinese or English interface. Names stay unchanged. Chinese defaults to on and English to off, but your saved choice takes priority. Documents offer original, translated, and paragraph-by-paragraph bilingual views, with bilingual selected by default. Translation starts on demand, tries Google Translate, Microsoft Translator, then your default model, and keeps the original when none answers. Results stay cached locally until cleared. Turning translation off keeps that cache. See [translation](docs/user/usage.md#translation).
60
+ Terminal alternative: `dsh plugin --profile <name> add dsh-agent-plugins-market`. Requirements, profile configuration and other install options live in the [usage guide](https://github.com/Sivan757/dsh-agent-plugins-market/blob/main/docs/user/usage.md#installation-options).
70
61
 
71
- ## Quick start
62
+ ## Highlights
72
63
 
73
- Install into your profile, replacing `<name>` with its name:
64
+ ### Core
74
65
 
75
- ```sh
76
- dsh plugin --profile <name> add dsh-agent-plugins-market
77
- ```
66
+ - **Any skill repository works.** Add a Git URL whose repository holds `skills/<name>/SKILL.md` and the market discovers it as a suite. No manifest, no conversion, no file copying.
67
+ - **Ten suite layouts.** Claude Code, Codex, Cursor, Kimi Code, ZCode, Qoder CLI, GitHub Copilot CLI, Universal `.plugin/`, [agent-plugins](https://agent-plugins.org) and manifest-less skill collections.
68
+ - **Sources and downloads.** Add a Git repository, a local directory or an archive, adopt a checkout you cloned yourself, and refresh on demand. Pick a global or China mainland mirror, and refresh every source on a 6-hour timer if you want.
69
+ - **Runtime injection.** Enabled suites add skills to the catalog and slash menu, commands as `/name`, agent personas to the subagent catalog, MCP tools as `mcp__*`, hooks to lifecycle events, and language servers to the `lsp` tool. Installing the plugin is the whole LSP setup.
70
+ - **One workspace.** Seven tabs cover the market, the resources you author, and the services that run. Every tab has search, filters and a grid or list view.
78
71
 
79
- 1. Restart DSH and open **Settings → Agent Plugins**.
80
- 2. The market already lists the first-party source; press **Refresh** to fetch its suites. To pull in more, add a source, for example `https://github.com/anthropics/claude-plugins-official`.
81
- 3. Open a suite, review its contents, then install it and ensure it is enabled.
82
- 4. For a suite with skills, check the **Skills** tab and type `/` in chat to find its user-invocable skills. For an MCP suite, check **MCP services** and resolve any credential or connection notice before using its tools.
72
+ ### Advanced
83
73
 
84
- Requirements, profile configuration and alternative installs: [usage guide](docs/user/usage.md#installation-options).
74
+ - **MCP OAuth with nothing to declare.** A remote MCP server that answers `401` starts RFC 9728 discovery, dynamic client registration and PKCE authorization in your browser, and the granted token persists. OAuth is on by default, so a suite needs no declaration for it.
75
+ - **Per-server MCP control.** Override a declaration without editing its source, switch one tool off, and set the tool-call and startup timeouts.
76
+ - **Project and personal resources.** Turn on **Scan project Agent layouts** to read skills, commands, roles, MCP servers and hooks from the project's own directories. Author your own under `~/.agents/` as Markdown, and disable a resource without deleting its file.
77
+ - **Per-workspace control.** Each workspace switches the six mounted surfaces off or on, keeps its own resource filters, and saves a resource-window setup as a favorite that works across projects.
78
+ - **Hooks you can read and try.** A hook row opens a declaration card with its event, matcher and timeout, plus a dry run in your home directory.
79
+ - **Bilingual by default.** The interface and the injected prompts follow the host language. Descriptions and documents show the original, a translation or both, and stay cached until you clear them.
85
80
 
86
81
  ## Everyday use
87
82
 
88
83
  The workspace has seven tabs:
89
84
 
90
- | Tab | Use it to |
91
- | --- | --- |
92
- | Market | Add sources, preview suites, install / uninstall, enable / disable and refresh. |
93
- | Skills | Browse skills and create or edit your own reusable instructions. |
94
- | Commands | Manage prompt templates invoked as `/name`. |
95
- | Agent personas | Save role instructions and model settings; delegate through `subagent_role` or create role-aware Team members with `spawn_teammate_role`. |
96
- | MCP services | Add a service or configure an installed one, its credentials and authorization; inspect status and retry failures. |
97
- | LSP servers | Add and configure language servers and inspect their runtime status. |
98
- | Hooks | Inspect configured command hooks and supported events. Each row opens a declaration card with support, event, matcher and timeout, plus a dry run in your home directory. Installed suite hooks list read-only and follow their suite. |
99
-
100
- A **source** is where content comes from; a **suite** is an installable unit discovered there. Adding a source discovers its suites. Installing and enabling a suite controls its runtime capabilities.
101
-
102
- Everything you author yourself lives in the shared Agent layout root: skills, commands and personas as Markdown under `~/.agents/`, command hooks in `~/.agents/hooks.json` (or `~/.agents/hooks/hooks.json`), and the MCP and LSP services you add in the workspace in `~/.agents/mcp.json` and `~/.agents/lsp.json`. Commands and personas are read at any subdirectory depth, so a file another tool wrote at `~/.agents/commands/git/commit.md` is callable as `/git-commit`. Project-native resources stay in the project. See [storage and discovery](docs/user/usage.md#storage-and-discovery) for paths and precedence.
103
-
104
- All seven tabs share a saved grid/list preference. Add and refresh actions sit at the top right; resource state rails are green when active. A hook row opens its own read-only declaration. The declaration shows the full command, the declared matcher, the declared timeout and the host support verdict, never the whole suite behind it.
105
-
106
- ## Compatibility and boundaries
107
-
108
- Supported **layout dialects** describe how files are organized. The [shared priority table](#layout-detection-precedence) lists suite manifests and Marketplace catalogs together. All ten layout contracts in [`schemas/`](schemas/README.md) have independent reader tests; [the layout audit](docs/user/layout-coverage.md) maps them to pinned repository fixtures.
109
-
110
- Supported **runtime surfaces** describe what DSH can use:
111
-
112
- | Surface | Runtime support and conditions |
113
- | --- | --- |
114
- | Skills | Host skill catalog and user-invocable slash entries; supported root placeholders are expanded. |
115
- | Commands | Slash commands through the host command service. |
116
- | Agents | Dynamic role catalog; `subagent_role` without Agent Teams, `spawn_teammate_role` with it. Team mode also requires session query and system-prompt services. |
117
- | MCP | Built-in bridge by default: stdio, Streamable HTTP with OAuth, and legacy SSE. Optional host-client compatibility mode is also available; it enforces the tool-call timeout but not tool filters or a startup timeout. |
118
- | Hooks | The command-hook subset mapped by `dsh-hooks-claude-code`. |
119
- | LSP | Self-provisioned: installing the plugin is the whole setup, and `lsp` mounts only while a language server is wanted; the server executable must be on `PATH`. |
120
-
121
- Role discovery remains available in either mode. `spawn_teammate_role(agent, name, description, prompt)` applies role instructions and model settings from the first request, returns a native Team `target`, and retains the creation snapshot for resume. Only the Lead creates members, after the user explicitly requests Team work. Native `spawn_teammate` stays available; roles do not add a second management API. A separate Team coordination briefing keeps the Lead on user intent and integration while guiding members through scoped execution and reporting, even without a role catalog. `tools` and `disallowedTools` are preserved but not enforced. See [agent roles](docs/user/agent-roles.md) for routing, prerequisites and limits.
122
-
123
- ### Layout detection precedence
124
-
125
- When multiple manifests exist in the **same suite directory**, the first existing file in this order selects the layout:
126
-
127
- | Priority | Layout | Suite manifest | Marketplace catalog |
128
- | --- | --- | --- | --- |
129
- | 1 | [agent-plugins](https://agent-plugins.org) / root compatibility | `plugin.json` | No dedicated catalog |
130
- | 2 | Universal compatibility | `.plugin/plugin.json` | `.plugin/marketplace.json` |
131
- | 3 | Claude Code | `.claude-plugin/plugin.json` | `.claude-plugin/marketplace.json` |
132
- | 4 | Cursor | `.cursor-plugin/plugin.json` | `.cursor-plugin/marketplace.json` |
133
- | 5 | Kimi Code | `kimi.plugin.json`, then `.kimi-plugin/plugin.json` | `.kimi-plugin/marketplace.json` |
134
- | 6 | Codex | `.codex-plugin/plugin.json` | `.agents/plugins/marketplace.json`, then `.agents/plugins/api_marketplace.json` |
135
- | 7 | ZCode | `.zcode-plugin/plugin.json` | No dedicated catalog |
136
- | 8 | Qoder CLI | `.qoder-plugin/plugin.json` | `.qoder-plugin/marketplace.json` |
137
- | 9 | GitHub Copilot CLI | `.github/plugin/plugin.json` | `.github/plugin/marketplace.json` |
138
- | Fallback | Skill collection / shared catalog | Discover skills when no recognized manifest exists | Root `marketplace.json` |
139
-
140
- - **Manifests are tried in order:** a manifest that cannot be read or validated is reported and the next one is tried, down to the fallback. If every candidate fails, the suite is diagnosed instead of loading half of it.
141
- - **Component fallback:** for a root `plugin.json` that does not declare a recognized agent-plugins `$schema`, missing component declarations can come from `.claude-plugin/plugin.json`; explicit root declarations win, and marketplace entry declarations fill remaining gaps.
142
- - Marketplace catalogs follow the same order: the first catalog that produces suites wins, and invalid or empty catalogs allow the next candidate to be tried.
143
-
144
- The order is defined in [`packages/market-contracts/src/model/layouts.ts`](packages/market-contracts/src/model/layouts.ts); selection and root-manifest fallback are implemented in [`packages/market-catalog/src/scanning/manifests.ts`](packages/market-catalog/src/scanning/manifests.ts).
85
+ | Tab | Use it to |
86
+ | -------------- | ----------------------------------------------------------------------------------- |
87
+ | Market | Add sources, preview suites, install or remove them, and switch them on or off. |
88
+ | Skills | Browse skills and create or edit your own reusable instructions. |
89
+ | Commands | Manage prompt templates invoked as `/name`. |
90
+ | Agent personas | Save role instructions and model settings, then delegate to them. |
91
+ | MCP services | Add a service or configure an installed one, its credentials and its authorization. |
92
+ | LSP servers | Add and configure language servers, and read their runtime status. |
93
+ | Hooks | Read each configured hook with its event, matcher and timeout. |
145
94
 
146
- ### Layout support matrix
95
+ A **source** is where content comes from. A **suite** is an installable unit discovered there. Adding a source discovers its suites. Enabling a suite turns its runtime capabilities on.
147
96
 
148
- The table says per layout whether this plugin reads a given surface at all. **Yes** means the layout's own files are read and injected; **Partial** means only part of the formats is understood, or the upstream layout has no such definition — the notes below say which. Evidence: the [compatibility report](docs/reference/compat-report.md) and [layout audit](docs/user/layout-coverage.md).
97
+ Your own content lives under `~/.agents/`: skills, commands and personas as Markdown, hooks in `hooks.json`, and the MCP and LSP services you add in `mcp.json` and `lsp.json`. Project-native resources stay in the project. See [storage and discovery](https://github.com/Sivan757/dsh-agent-plugins-market/blob/main/docs/user/usage.md#storage-and-discovery).
149
98
 
150
- | Layout | Skills | Agents | Commands | MCP | Hooks | LSP |
151
- | ------------------------------------------------------------------------------------------------------------- | ------ | ------- | -------- | ------- | ------- | ------- |
152
- | [Claude Code](https://code.claude.com/docs/en/plugins-reference) | Yes | Yes | Yes | Yes | Partial | Yes |
153
- | [Codex](https://developers.openai.com/plugins/build/plugins) | Yes | Yes | Yes | Partial | Partial | Yes |
154
- | [Cursor](https://cursor.com/docs/reference/plugins) | Yes | Partial | Partial | Partial | No | Yes |
155
- | Kimi Code | Yes | Yes | Yes | Yes | Partial | Partial |
156
- | [ZCode](https://zcode.z.ai/en/docs/plugin) `.zcode-plugin/` | Yes | Yes | Yes | Yes | Partial | Partial |
157
- | [Qoder CLI](https://docs.qoder.com/cli/plugins-reference) `.qoder-plugin/` | Yes | Yes | Yes | Partial | Partial | Partial |
158
- | [GitHub Copilot CLI](https://docs.github.com/en/copilot/reference/copilot-cli-reference/cli-plugin-reference) | Yes | Yes | Yes | Yes | Partial | Yes |
159
- | Universal compatibility layout `.plugin/` | Yes | Yes | Yes | Yes | Partial | Yes |
160
- | [agent-plugins](https://agent-plugins.org) | Yes | Yes | Yes | Yes | Yes | Yes |
161
- | Manifest-less skill collection | Yes | Yes | Yes | Yes | Partial | Partial |
162
- | Project-native directories | Yes | Yes | Yes | Yes | Partial | No |
99
+ ## Compatibility
163
100
 
164
- - **Skills** are read from the paths a manifest declares and from the conventional `skills/` directory, including flat `<name>.md` files. A path that carries its own `SKILL.md` is one skill: the documents beside it belong to that skill and are not read as skills. A conformant agent-plugins package is the exception: skills come from one level of `skills/` subdirectories, exactly as its specification requires.
165
- - **Agents and commands** are read as Markdown (`agents/*.md`, `commands/*.md`). Cursor plugin commands accept `.md`, `.mdc`, `.markdown` and `.txt`. Codex and Kimi native agent/command formats (TOML, YAML) have no adapter yet.
166
- - **MCP** covers declared files, inline tables and arrays. Cursor's schema-less `mcp.json` and agent-plugins' strict `mcp.json` both work; Kimi Code is inline-only. Codex app connectors stay outside this adapter.
167
- - **Hooks** map the command-style events DSH has an equivalent for; events without one (for example `afterFileEdit`) are reported instead of simulated. Cursor's native events are not read.
168
- - **LSP** accepts declared files, arrays and inline tables plus the conventional `.lsp.json` / `lsp.json` locations. Declarations inside a project are reported but not mounted: the host LSP registry is global. Some layouts only expose LSP directories for preview.
169
- - **agent-plugins** suites read the portable core (`skills/`, `mcp.json`) per the specification, plus this plugin's [`com.deepseek.harness`](schemas/com.deepseek.harness/spec.md) extension namespace for commands, agents, hooks, LSP and per-server MCP policy (OAuth, tool lists, timeouts). Root-level `commands/`, `agents/`, `hooks/` and `.mcp.json` files belong to other layouts and are reported as unread for this dialect; inline manifest component keys are reported and ignored per §5.2. Both recognized releases (1.0.0, 1.1.0) validate against their own vendored schemas.
170
- - **Universal** is a compatibility-layout label used by this plugin; the [OpenHands SDK](https://docs.openhands.dev/sdk/guides/plugins) documents the same `.plugin/plugin.json` location and a [Vercel repository](https://github.com/vercel/vercel-plugin/blob/main/.plugin/plugin.json) uses it, but no cross-vendor specification exists.
101
+ The plugin reads ten layout dialects and maps six runtime surfaces. Per-layout support and the manifest priority order are on the [compatible plugins page](https://sivan757.github.io/dsh-agent-plugins-market/compatible-plugins/). Evidence: the [layout audit](https://github.com/Sivan757/dsh-agent-plugins-market/blob/main/docs/user/layout-coverage.md) and the [compatibility report](https://github.com/Sivan757/dsh-agent-plugins-market/blob/main/docs/reference/compat-report.md).
171
102
 
172
- Sources such as [jeecgboot/skills](https://github.com/jeecgboot/skills) group undeclared, skill-only directories into one plugin card. Marketplace entries and roots with plugin manifests or other runtime surfaces retain their separate identities. The aggregate requires its own installation and does not inherit individual skill installs. See [skill collection rules](schemas/skill-collection/spec.md).
173
-
174
- Reading a layout does not guarantee every behavior of its original platform. Invalid declarations are diagnosed and skipped.
175
-
176
- ### Project layout switch
177
-
178
- The plugin settings card has **Scan project Agent layouts** (`dsh-agent-plugins-market.scanProjectLayouts`, default off). It controls one thing: whether the project you are working in contributes skills, commands, agent roles, MCP servers and hooks from its own directories (`.claude`, `.agents`, `.codex`, `.cursor`, `.kimi`, `.zcode`, `.qoder`, `.github`). Turning it on adds those candidates; turning it off removes them on the next discovery pass. The card applies a switch when you save it, and each setting offers Use default while it carries your own value. Configured sources and installed suites are unaffected.
179
-
180
- [Project layouts](docs/user/usage.md#project-layouts) lists the directories and files read per layout and how they are mounted.
181
-
182
- ### Verified samples
183
-
184
- The README repositories have offline snapshots in [`tests/fixtures/real-layouts/`](tests/fixtures/real-layouts/) with commit IDs, hashes and licenses, and each layout has an isolated reader test. The [compatibility report](docs/reference/compat-report.md) records the sampled repositories, their schema verdicts and the scanner output; [the audit](docs/user/layout-coverage.md) records independent resource checks. These are documentation, source and sample checks — not end-to-end certification for every platform.
185
-
186
- Review third-party suites before enabling them: enabled services and hooks can execute programs. See the [runtime and security details](docs/user/usage.md#runtime-and-security).
103
+ Reading a layout does not guarantee every behavior of its original platform. Invalid declarations are diagnosed and skipped, never half-mounted.
187
104
 
188
105
  ## FAQ
189
106
 
190
107
  **Why is an installed skill or tool missing?**
191
108
 
192
- Check that the suite and the relevant capability are enabled. Skills may restrict manual invocation. MCP / LSP panels show user-service failures. Project resources additionally require the project-scan switch; unsupported native fields and project LSP declarations appear in scan diagnostics.
109
+ Check that the suite and the relevant capability are enabled. The MCP and LSP panels report failures and missing credentials. Project resources also need the project-scan switch.
193
110
 
194
111
  **Where do I configure MCP tokens?**
195
112
 
196
- Open the service in **MCP services**. Missing environment references show `needs-credentials`. Host-managed credentials are write-only; launch-environment credentials require changing the environment and restarting DSH.
197
-
198
- **How do I add a service that no suite declares?**
199
-
200
- Use **Add** in **MCP services** or **LSP servers**. The declaration is validated, stored in `~/.agents/mcp.json` or `~/.agents/lsp.json`, and mounted through the same lifecycle as suite services. Host-observed services remain read-only.
113
+ Open the service in **MCP services**. Missing environment references show `needs-credentials`. Host-managed credentials are write-only.
201
114
 
202
115
  **Do sources refresh automatically?**
203
116
 
204
- Only when **Background source updates** is on: every configured source is then refreshed every 6 hours, starting one interval after you enable it. The switch is off by default, and the refresh button always works.
205
-
206
- **Where do the suites that appear without adding a source come from?**
207
-
208
- The plugin presets one source record pointing at its own suite collection, so the market lists that repository on first run; press **Refresh** to fetch its suites. From there it behaves like any other source — including removal, which the next activation undoes just as it does for a source seeded through configuration.
209
-
210
- **What if a source download fails?**
211
-
212
- Use a local directory, adopt a manual checkout, or configure a proxy / mirror. See [source configuration](docs/user/usage.md#configure-marketplace-sources).
213
-
214
- **When do local edits become visible?**
215
-
216
- There is no file watcher. Local-source discovery caches results for up to 30 seconds; refresh the source to invalidate them immediately. Project discovery has a separate five-second cache. A refresh does not happen automatically on an already-open page.
117
+ Only with **Background source updates** on. It refreshes every configured source every 6 hours, starting one interval after you enable it. The refresh button always works.
217
118
 
218
119
  **Does removing a source delete its files?**
219
120
 
220
- Only when you tick **also delete the managed market directory** in the confirmation. That removes the source's checkout under `~/.dsh/agent-plugins/.sources/<id>` — including one you cloned yourself and adopted. A local-directory source pointing outside `.sources/` is never deleted.
221
-
222
- ## Repository layout
121
+ Only when you tick **also delete the managed market directory** in the confirmation. A local-directory source outside `.sources/` is never deleted.
223
122
 
224
- The published package stays `dsh-agent-plugins-market` and ships one artifact. The code lives in eight private workspace packages under `packages/`: `market-bundle` (composition root and HTTP surface), `market-catalog` (source scanning and catalog use cases), `market-contracts` (stateless shared records), `market-runtime` (session selection and harness effects), `market-mcp`, `market-lsp`, `market-translation`, and `market-ui` (the browser bundle). Ownership, dependency direction and the migration gates are recorded in [the domain workspace refactor](docs/developer/design/domain-workspace-refactor.md); [AGENTS.md](AGENTS.md) holds the layout map maintainers edit.
123
+ More questions: [FAQ](https://sivan757.github.io/dsh-agent-plugins-market/faq/).
225
124
 
226
- ## More documentation
125
+ ## Documentation
227
126
 
228
- - [Usage guide](docs/user/usage.md): installation, source configuration, storage, host requirements, project layouts, MCP / LSP and feedback settings.
229
- - [Plugin specifications](schemas/README.md): per-dialect reference schemas and evidence, the vendored agent-plugins v1 contracts (1.0.0, 1.1.0), and the [`com.deepseek.harness` namespace contract](schemas/com.deepseek.harness/spec.md).
230
- - [Compatibility report](docs/reference/compat-report.md): one real repository per schema, with commits, schema verdicts and scanner output.
231
- - [Contributing](CONTRIBUTING.md): development setup, checks and PR workflow.
232
- - [Security policy](SECURITY.md) · [Release history](CHANGELOG.md) · [MIT license](LICENSE).
233
- - [Domain glossary](CONTEXT.md) · [Architecture](docs/developer/decisions/0001-catalog-centered-modular-refactor.md).
234
- - [Agent roles and storage](docs/user/agent-roles.md): installed-resource switching, model routing and migration.
127
+ - [Install guide](https://sivan757.github.io/dsh-agent-plugins-market/install/): prerequisites and the first suite, step by step.
128
+ - [Usage guide](https://github.com/Sivan757/dsh-agent-plugins-market/blob/main/docs/user/usage.md): source configuration, storage, project layouts, MCP, LSP and settings.
129
+ - [Compatible plugins](https://sivan757.github.io/dsh-agent-plugins-market/compatible-plugins/): layouts, precedence and verified samples.
130
+ - [Plugin specifications](https://github.com/Sivan757/dsh-agent-plugins-market/blob/main/schemas/README.md): per-dialect reference schemas and the [`com.deepseek.harness`](https://github.com/Sivan757/dsh-agent-plugins-market/blob/main/schemas/com.deepseek.harness/spec.md) namespace.
131
+ - [Contributing](https://github.com/Sivan757/dsh-agent-plugins-market/blob/main/CONTRIBUTING.md) · [Security](https://github.com/Sivan757/dsh-agent-plugins-market/blob/main/SECURITY.md) · [Changelog](https://github.com/Sivan757/dsh-agent-plugins-market/blob/main/CHANGELOG.md) · [License](https://github.com/Sivan757/dsh-agent-plugins-market/blob/main/LICENSE).
132
+ - [Domain glossary](https://github.com/Sivan757/dsh-agent-plugins-market/blob/main/CONTEXT.md) · [Agent roles](https://github.com/Sivan757/dsh-agent-plugins-market/blob/main/docs/user/agent-roles.md) · [Release process](https://github.com/Sivan757/dsh-agent-plugins-market/blob/main/docs/developer/release/release-process.md).
235
133
 
236
134
  ## Community
237
135
 
238
136
  Scan the QR code to join the **dsh-agent-plugins-market** WeChat group, where we answer questions and take feature requests.
239
137
 
240
138
  <div align="center">
241
- <img src="docs/screenshots/wechat-group.webp" alt="WeChat group QR code for dsh-agent-plugins-market" width="240" />
139
+ <img src="https://raw.githubusercontent.com/Sivan757/dsh-agent-plugins-market/main/docs/screenshots/wechat-group.webp" alt="WeChat group QR code for dsh-agent-plugins-market" width="240" />
242
140
  </div>
package/README.zh.md CHANGED
@@ -1,242 +1,140 @@
1
- <img src="assets/dsh-agent-plugins.png" alt="Agent 扩展" width="64" height="64" />
1
+ <img src="https://raw.githubusercontent.com/Sivan757/dsh-agent-plugins-market/main/assets/dsh-agent-plugins.png" alt="Agent 扩展" width="64" height="64" />
2
2
 
3
3
  # Agent 扩展
4
4
 
5
5
  `dsh-agent-plugins-market`
6
6
 
7
- **在 [DeepSeek Harness(DSH)](https://github.com/deepseek-ai/deepseek-harness) 之内,一站式管理 skills、subagent、MCP、LSP,兼容 Claude Code、Codex、Cursor、Kimi 等 agent plugins 体系。**
7
+ **DeepSeek Harness(DSH)里一站式的技能、子代理、MCP 与 LSP 管理器。**
8
8
 
9
- 复用 Claude Code、Codex、Cursor、Kimi 等已识别布局中支持的内容,在 DSH Web 界面管理自己的技能、命令、代理角色、MCP 服务和 LSP 服务。
9
+ 在 DSH 中直接运行 Claude Code、Codex、Cursor、Kimi 与 agent-plugins 套件。插件就地读取各种布局,你不必转换清单,也不必复制文件。在 DSH 图形界面里安装本插件,之后在一个工作区里管理技能、命令、代理角色、MCP 服务与 LSP 服务。
10
10
 
11
- 如果这个插件帮到了你,欢迎在 [GitHub](https://github.com/Sivan757/dsh-agent-plugins-market) 点个 Star ⭐。
11
+ 如果这个插件对你有用,欢迎在 [GitHub](https://github.com/Sivan757/dsh-agent-plugins-market) 点一个 ⭐。
12
12
 
13
- [English](README.md) | 简体中文 | [文档站](https://sivan757.github.io/dsh-agent-plugins-market/) | [npm](https://www.npmjs.com/package/dsh-agent-plugins-market)
13
+ [English](README.md) | 简体中文 | [在线文档](https://sivan757.github.io/dsh-agent-plugins-market/) | [npm](https://www.npmjs.com/package/dsh-agent-plugins-market)
14
14
 
15
- [![npm version](https://img.shields.io/npm/v/dsh-agent-plugins-market)](https://www.npmjs.com/package/dsh-agent-plugins-market) [![License](https://img.shields.io/github/license/Sivan757/dsh-agent-plugins-market)](LICENSE)
15
+ [![npm version](https://img.shields.io/npm/v/dsh-agent-plugins-market)](https://www.npmjs.com/package/dsh-agent-plugins-market) [![License](https://img.shields.io/github/license/Sivan757/dsh-agent-plugins-market)](https://github.com/Sivan757/dsh-agent-plugins-market/blob/main/LICENSE)
16
16
 
17
- [快速开始](#快速开始) · [日常使用](#日常使用) · [兼容性](#兼容性与运行边界) · [常见问题](#常见问题)
17
+ [快速开始](#快速开始) · [功能亮点](#功能亮点) · [日常使用](#日常使用) · [兼容性](#兼容性) · [常见问题](#常见问题)
18
18
 
19
19
  ## 页面
20
20
 
21
21
  <table>
22
22
  <tr>
23
23
  <td align="center" width="33%">
24
- <img src="docs/screenshots/market.png" alt="插件市场" width="100%" /><br />
25
- <b>插件市场</b><br />添加来源、预览并安装套件。
24
+ <img src="https://raw.githubusercontent.com/Sivan757/dsh-agent-plugins-market/main/docs/screenshots/market.png" alt="插件市场" width="100%" /><br />
25
+ <b>插件市场</b><br />添加来源、预览套件、安装并启用。
26
26
  </td>
27
27
  <td align="center" width="33%">
28
- <img src="docs/screenshots/skills.png" alt="技能" width="100%" /><br />
29
- <b>技能</b><br />浏览技能,编写自建技能。
28
+ <img src="https://raw.githubusercontent.com/Sivan757/dsh-agent-plugins-market/main/docs/screenshots/skills.png" alt="技能" width="100%" /><br />
29
+ <b>技能</b><br />浏览技能,也可以自己编写。
30
30
  </td>
31
31
  <td align="center" width="33%">
32
- <img src="docs/screenshots/commands.png" alt="命令" width="100%" /><br />
33
- <b>命令</b><br />管理以 /名称 调用的提示词模板。
32
+ <img src="https://raw.githubusercontent.com/Sivan757/dsh-agent-plugins-market/main/docs/screenshots/commands.png" alt="命令" width="100%" /><br />
33
+ <b>命令</b><br />管理通过 /名称 调用的提示词模板。
34
34
  </td>
35
35
  </tr>
36
36
  <tr>
37
37
  <td align="center" width="33%">
38
- <img src="docs/screenshots/personas.png" alt="代理角色" width="100%" /><br />
39
- <b>代理角色</b><br />角色与精确的供应商、模型和思考强度。
38
+ <img src="https://raw.githubusercontent.com/Sivan757/dsh-agent-plugins-market/main/docs/screenshots/personas.png" alt="代理角色" width="100%" /><br />
39
+ <b>代理角色</b><br />为角色指定精确的提供方、模型与推理强度。
40
40
  </td>
41
41
  <td align="center" width="33%">
42
- <img src="docs/screenshots/mcp.png" alt="MCP 服务" width="100%" /><br />
42
+ <img src="https://raw.githubusercontent.com/Sivan757/dsh-agent-plugins-market/main/docs/screenshots/mcp.png" alt="MCP 服务" width="100%" /><br />
43
43
  <b>MCP 服务</b><br />凭据、授权与连接状态。
44
44
  </td>
45
45
  <td align="center" width="33%">
46
- <img src="docs/screenshots/lsp.png" alt="LSP 服务" width="100%" /><br />
46
+ <img src="https://raw.githubusercontent.com/Sivan757/dsh-agent-plugins-market/main/docs/screenshots/lsp.png" alt="LSP 服务" width="100%" /><br />
47
47
  <b>LSP 服务</b><br />语言服务器配置与运行状态。
48
48
  </td>
49
49
  </tr>
50
50
  </table>
51
51
 
52
- ## 你可以用它做什么
53
-
54
- - 在插件设置中开启实验性的 Agent 预设管理器后,输入框才显示入口。该开关默认关闭,只控制入口显示,不停用会话运行时。会话扩展预设通过「权限」右侧的Agent 扩展图标按钮选择技能、命令、角色、MCP 与 LSP 能力。每个工作区拥有自己的预设库和新会话默认值。会话运行时处于活动状态时选择预设,将在该会话的下一次用户请求生效。进行中的中途引导(steer)与工具调用不受影响。选择提交后,已打开的斜杠技能菜单自动刷新,无需再次输入或刷新页面。在当前会话中编辑已选或待选预设会更新该会话,其他会话各自保留独立副本。复制、粘贴预设到另一个工作区会生成独立副本。全局管理的资源显示真实状态,不提供会话开关。预设详情不会修改共享凭据或配置。会话选择失败后,显式恢复会还原就绪状态并继续排队的用户输入,无需再次发送。
55
-
56
- - **十种套件布局。** Claude Code、Codex、Cursor、Kimi Code、ZCode、Qoder CLI、GitHub Copilot CLI、Universal `.plugin/`、[agent-plugins](https://agent-plugins.org) 与无清单技能集合。
57
- - **来源。** 添加 Git 仓库、本地目录或压缩包(`.zip` / `.tar.gz` / `.tgz` / `.tar`);收编自己克隆的目录;按需刷新;删除来源时可一并删除受管目录。
58
- - **第一方来源。** 插件预置一条指向自身套件集合的仓库源记录,所以首次运行市场里就列出该仓库,不需要粘贴任何地址。此后它就是普通 Git 来源——刷新以拉取,再像其他来源一样安装与启停其中的套件。
59
- - **适合你网络的下载方式。** 下载区域设置(默认 `auto` 跟随界面语言,也可显式选择全球或中国大陆)决定 `github.com` 克隆走的镜像前缀;代理与单次调用调优在宿主配置里。
60
- - **运行时能力。** 启用套件会注入会话:技能进入目录与斜杠菜单,命令以 `/名称` 调用,代理角色进入子代理目录,MCP 工具以 `mcp__` 前缀注册,hooks 挂到宿主生命周期事件,语言服务器通过 `lsp` 工具使用。
61
- - **MCP。** 内置桥接无需宿主 MCP 客户端,支持 stdio、带 OAuth 的 Streamable HTTP 和旧式 SSE。`${VAR}` 引用从宿主凭据服务或启动环境解析;按服务覆盖可禁用或修补声明,不必修改源文件,可设置工具调用超时与启动超时,也可逐个关闭工具;新建与编辑共用同一服务表单,均提供高级超时设置与 JSON 视图;还可选用宿主客户端兼容模式。套件的工具名为 `mcp__<套件>__<服务>__<工具>`;你在 `~/.agents/mcp.json` 自建的服务以自己的键挂载,即 `mcp__<服务>__<工具>`。
62
- - **LSP。** 随插件自带:安装插件即完成全部设置,`lsp` 工具只在确有语言服务器需求时挂载;语言服务器可执行文件本身需在 `PATH` 中。从「需要你自己在 profile 里暴露 LSP」的版本升级上来时,若 profile 里还留着那层手工配置,会报接缝冲突;LSP 面板会指出该文件并代为移除这一层,且保留备份。
63
- - **代理角色与委派。** 角色卡保留专业指令及精确的供应商、模型、思考强度配置。未启用 Agent Teams 时使用 `subagent_role`;启用后使用 `spawn_teammate_role` 创建真正的 Team 成员,并通过原生 Team 工具管理。
64
- - **项目维度。** 项目自身的技能、代理、命令、MCP 服务与 hooks 无需安装即被发现。
65
- - **自建资源。** 技能、命令和代理角色以 Markdown 保存在 `~/.agents/` 下,可随时编辑或禁用而不删除文件。
66
- - **后台自动更新来源。** 可选:按定时器刷新全部已配置来源;默认关闭。
67
- - **Web 工作区。** 七个页签:插件市场、技能、命令、代理角色、MCP 服务、LSP 服务和 Hooks。每个页签都有搜索、过滤与网格/列表切换,并提供带诊断的状态面板、凭据编辑,以及可在启用可执行第三方内容前提示风险的安装确认。设置页是版式的准绳:所有页面共用同一条页签行(等宽列、绝不横向滚动,标签过长则省略号截断),并共用同一套卡片与详情结构,预设管理器同样如此。
68
- - **双语界面与反馈。** 工作区文案与注入提示跟随宿主语言;启用反馈后,模型可通过 `gh` 命令或 GitHub token 提交 `report_market_issue` 报告;两者都没有时,会打开预填好的 GitHub 新建 issue 页面并把完整 issue 文本交给你。
69
- - **翻译。** 描述与已展开的文档可翻译成界面所用的中文或英文,名称保持不变。中文默认开启、英文默认关闭,但你保存的选择优先。正文提供原文、译文和逐段双语三种视图,默认双语。翻译按需开始,依次尝试 Google Translate、Microsoft Translator、你的默认模型,都未应答时保留原文。结果缓存在本地直到清空;关闭翻译会保留缓存。详见[翻译](docs/user/usage.zh.md#翻译)。
70
-
71
52
  ## 快速开始
72
53
 
73
- 将 `<name>` 替换为你的 profile 名称后安装:
74
-
75
- ```sh
76
- dsh plugin --profile <name> add dsh-agent-plugins-market
77
- ```
78
-
79
- 1. 重启 DSH,打开 **设置 → Agent 扩展**。
80
- 2. 市场里已经列出第一方来源;点**刷新**即可拉取其中的套件。想补充更多内容时再添加来源,例如 `https://github.com/anthropics/claude-plugins-official`。
81
- 3. 打开套件查看内容,确认后安装,并确保套件已启用。
82
- 4. 如果套件提供技能,先在**技能**页签查看,再在聊天中输入 `/` 查找允许手动调用的技能。如果提供 MCP,前往 **MCP 服务**检查状态,处理凭据或连接提示后再使用工具。
83
-
84
- 环境要求、profile 配置与其他安装方式见[使用指南](docs/user/usage.zh.md#其他安装方式)。
85
-
86
- ## 日常使用
87
-
88
- 工作区包含七个页签:
89
-
90
- | 页签 | 可以做什么 |
91
- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
92
- | 插件市场 | 添加来源、预览套件、安装 / 卸载、启用 / 禁用和刷新。 |
93
- | 技能 | 浏览技能,创建或编辑自己的可复用指令。 |
94
- | 命令 | 管理通过 `/名称` 调用的提示词模板。 |
95
- | 代理角色 | 保存角色指令与模型配置;通过 `subagent_role` 委派,或通过 `spawn_teammate_role` 创建带角色的 Team 成员。 |
96
- | MCP 服务 | 自行新增服务或配置已安装的服务及其凭据与授权,查看连接状态并重试失败的服务。 |
97
- | LSP 服务 | 新增并配置语言服务器,查看运行状态。 |
98
- | Hooks | 查看已配置的命令 hooks 及其支持情况。每行可打开声明卡:支持情况、事件、匹配条件与超时,并可在用户根目录试运行;已安装套件的 hook 只读列出,跟随套件。 |
99
-
100
- **来源(source)**表示内容来自哪里,**套件(suite)**是从中发现的可安装单元。添加来源用于发现套件;安装并启用套件决定其运行时能力是否生效。
101
-
102
- 你自己创作的内容都放在共用的 Agent 布局根目录:技能、命令和角色是 `~/.agents/` 下的 Markdown 文件,命令 hooks 放在 `~/.agents/hooks.json`(或 `~/.agents/hooks/hooks.json`),工作区里新增的 MCP 与 LSP 服务分别保存在 `~/.agents/mcp.json` 与 `~/.agents/lsp.json`。命令与角色按任意子目录深度读取,因此其它工具写在 `~/.agents/commands/git/commit.md` 的文件可用 `/git-commit` 调用。项目原生资源继续保留在项目中。路径和优先级见[存储与发现](docs/user/usage.zh.md#存储与发现)。
103
-
104
- 七个页签共用持久化的卡片/列表偏好。新增、刷新统一位于页头;资源状态条为绿色时表示生效中。hook 行打开的是它自己的只读声明,包含完整命令、声明的匹配条件、声明的超时与宿主支持情况,而不是它所属的整个套件。
105
-
106
- ## 兼容性与运行边界
107
-
108
- 支持的**布局方言(layout dialect)**描述文件如何组织。[统一优先级表](#布局识别优先级)并列列出套件清单与 Marketplace 目录索引。[`schemas/`](schemas/README.md) 中十种布局契约均有独立读取测试;[布局审计](docs/user/layout-coverage.zh.md)把它们对应到固定提交号的仓库快照。
109
-
110
- 支持的**运行时能力(runtime surface)**描述 DSH 能使用什么:
111
-
112
- | 能力 | 支持情况与条件 |
113
- | ----- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
114
- | 技能 | 接入宿主技能目录,允许手动调用的技能出现在斜杠菜单;展开支持的根路径占位符。 |
115
- | 命令 | 通过宿主命令服务注册斜杠命令。 |
116
- | 代理 | 动态角色目录;无 Agent Teams 时用 `subagent_role`,启用后用 `spawn_teammate_role`。Team 模式还需要会话查询和系统提示词服务。 |
117
- | MCP | 默认使用内置桥接,支持 stdio、带 OAuth 的 Streamable HTTP 和旧式 SSE;也可切换宿主客户端兼容模式,该模式执行工具调用超时,但不执行工具过滤与启动超时。 |
118
- | Hooks | 运行 `dsh-hooks-claude-code` 桥接映射支持的 command-hook 子集。 |
119
- | LSP | 随插件自带:安装插件即安装 LSP 支持包,`lsp` 工具只在确有语言服务器需求时挂载;语言服务器可执行文件本身需在 `PATH` 中。 |
54
+ 1. 在 DSH 图形界面中打开侧边栏的**插件**页。
55
+ 2. 点**添加插件**,填入 `dsh-agent-plugins-market`,然后安装。同一个对话框也接受仓库地址或本地目录。
56
+ 3. 重启 DSH,然后打开**设置 → Agent 扩展**。
57
+ 4. 市场里已经列出一个第一方来源。点**刷新**即可拉取其中的套件。想补充更多内容时再添加来源,例如 `https://github.com/anthropics/claude-plugins-official`。
58
+ 5. 打开套件查看内容,确认后安装并保持启用。技能会出现在**技能**页签和聊天中的 `/` 菜单里;如果套件提供 MCP,先在 **MCP 服务**处理凭据提示,再使用它的工具。
120
59
 
121
- 两种模式都保留角色发现。`spawn_teammate_role(agent, name, description, prompt)` 从首个请求起应用角色指令与模型配置,返回原生 Team `target`,并保留创建时快照供恢复。只有 Lead 在用户明确要求 Team 工作后才能创建成员。原生 `spawn_teammate` 仍可用,角色不会新增第二套管理 API。独立的 Team 协调说明让 Lead 负责用户意图与整合,指导成员按范围执行和回报,即使没有角色目录也可用。`tools` 与 `disallowedTools` 保留但不执行。路由、依赖与限制见[代理角色](docs/user/agent-roles.zh.md)。
60
+ 命令行替代方式:`dsh plugin --profile <name> add dsh-agent-plugins-market`。环境要求、profile 配置与其他安装方式见[使用指南](https://github.com/Sivan757/dsh-agent-plugins-market/blob/main/docs/user/usage.zh.md#其他安装方式)。
122
61
 
123
- ### 布局识别优先级
62
+ ## 功能亮点
124
63
 
125
- **同一个套件目录**同时存在多个清单时,按下表顺序选择第一个存在的文件来确定布局:
64
+ ### 核心能力
126
65
 
127
- | 优先级 | 布局 | 套件清单 | Marketplace 目录索引 |
128
- | --- | --- | --- | --- |
129
- | 1 | [agent-plugins](https://agent-plugins.org) / 根兼容清单 | `plugin.json` | 无专属索引 |
130
- | 2 | Universal 兼容布局 | `.plugin/plugin.json` | `.plugin/marketplace.json` |
131
- | 3 | Claude Code | `.claude-plugin/plugin.json` | `.claude-plugin/marketplace.json` |
132
- | 4 | Cursor | `.cursor-plugin/plugin.json` | `.cursor-plugin/marketplace.json` |
133
- | 5 | Kimi Code | `kimi.plugin.json`,其次 `.kimi-plugin/plugin.json` | `.kimi-plugin/marketplace.json` |
134
- | 6 | Codex | `.codex-plugin/plugin.json` | `.agents/plugins/marketplace.json`,其次 `.agents/plugins/api_marketplace.json` |
135
- | 7 | ZCode | `.zcode-plugin/plugin.json` | 无专属索引 |
136
- | 8 | Qoder CLI | `.qoder-plugin/plugin.json` | `.qoder-plugin/marketplace.json` |
137
- | 9 | GitHub Copilot CLI | `.github/plugin/plugin.json` | `.github/plugin/marketplace.json` |
138
- | 回退 | 技能集合 / 共享索引 | 无已知清单时按技能集合约定发现 | 根 `marketplace.json` |
66
+ - **任何技能仓库都能用。** 仓库里只要有 `skills/<名称>/SKILL.md`,把地址加为来源就能发现套件。不需要清单,不需要转换,不需要复制文件。
67
+ - **十种套件布局。** Claude Code、Codex、Cursor、Kimi Code、ZCode、Qoder CLI、GitHub Copilot CLI、通用 `.plugin/`、[agent-plugins](https://agent-plugins.org) 以及无清单的技能集合。
68
+ - **来源与下载。** 添加 Git 仓库、本地目录或压缩包,也可以接管你自己克隆的检出目录并随时刷新。镜像线路可选全球或中国大陆;需要时还可以每 6 小时自动刷新全部来源。
69
+ - **运行时注入。** 启用套件后,技能进入技能目录与斜杠菜单,命令成为 `/名称`,代理角色进入子代理目录,MCP 工具以 `mcp__*` 前缀出现,hooks 挂到宿主生命周期事件,语言服务器接入 `lsp` 工具;LSP 装上插件即完成配置。
70
+ - **一个工作区。** 七个页签覆盖市场、你自己创作的内容与正在运行的服务,都支持搜索、筛选和卡片或列表视图。
139
71
 
140
- - **清单按顺序尝试:** 读不出或校验不通过的清单会给出诊断,然后尝试下一优先级,直到回退项;全部失败时给出诊断,不会加载半个套件。
141
- - **组件补充:** 根 `plugin.json` 未声明受识别的 agent-plugins `$schema` 时,缺失的组件声明可以从 `.claude-plugin/plugin.json` 补齐;根清单中的显式声明优先,marketplace 条目声明补充剩余缺项。
142
- - Marketplace 索引遵循同一顺序:第一个能产出套件的索引胜出,无效或空索引允许继续尝试后续候选。
72
+ ### 进阶能力
143
73
 
144
- 顺序定义见 [`packages/market-contracts/src/model/layouts.ts`](packages/market-contracts/src/model/layouts.ts),选择与根清单补充逻辑见 [`packages/market-catalog/src/scanning/manifests.ts`](packages/market-catalog/src/scanning/manifests.ts)。
74
+ - **MCP OAuth,无需声明。** 远端 MCP 服务返回 `401` 时,自动完成 RFC 9728 发现、动态客户端注册与 PKCE 授权,浏览器授权后令牌持久保存。OAuth 默认开启,套件不需要为此写任何声明。
75
+ - **逐个 MCP 服务精调。** 不改动来源就能覆盖某条声明,单独关闭某个工具,并设置工具调用与启动超时。
76
+ - **项目资源与自己创作的内容。** 打开**扫描项目 Agent 布局**后,无需安装即可读取项目自身目录中的技能、命令、角色、MCP 服务与 hooks。自己的内容放在 `~/.agents/` 下,以 Markdown 编写;停用资源不必删除文件。
77
+ - **按工作区生效的控制。** 每个工作区可以单独开关六类挂载能力,保留自己的资源筛选条件,并把资源窗口配置存为可跨项目使用的收藏。
78
+ - **可读可试的 Hooks。** 每个 hook 行都能打开声明卡,查看事件、匹配条件与超时,并在用户根目录试运行一次。
79
+ - **默认双语。** 界面与注入的提示词跟随宿主语言。描述与文档可显示原文、译文或双语,结果缓存在本地直到你清空缓存。
145
80
 
146
- ### 布局支持矩阵
147
-
148
- 表中说明本插件是否读取该布局的对应能力。**支持**表示读取该布局自己的文件并注入;**部分**表示只理解其中一部分格式,或上游布局本身没有对应定义——具体见下表说明。依据见[兼容性报告](docs/reference/compat-report.md)与[布局审计](docs/user/layout-coverage.zh.md)。
149
-
150
- | 布局 | 技能 | 代理 | 命令 | MCP | Hooks | LSP |
151
- | ------------------------------------------------------------------------------------------------------------- | ---- | ---- | ---- | ---- | ------ | ------ |
152
- | [Claude Code](https://code.claude.com/docs/en/plugins-reference) | 支持 | 支持 | 支持 | 支持 | 部分 | 支持 |
153
- | [Codex](https://developers.openai.com/plugins/build/plugins) | 支持 | 支持 | 支持 | 部分 | 部分 | 支持 |
154
- | [Cursor](https://cursor.com/docs/reference/plugins) | 支持 | 部分 | 部分 | 部分 | 不支持 | 支持 |
155
- | Kimi Code | 支持 | 支持 | 支持 | 支持 | 部分 | 部分 |
156
- | [ZCode](https://zcode.z.ai/en/docs/plugin) `.zcode-plugin/` | 支持 | 支持 | 支持 | 支持 | 部分 | 部分 |
157
- | [Qoder CLI](https://docs.qoder.com/cli/plugins-reference) `.qoder-plugin/` | 支持 | 支持 | 支持 | 部分 | 部分 | 部分 |
158
- | [GitHub Copilot CLI](https://docs.github.com/en/copilot/reference/copilot-cli-reference/cli-plugin-reference) | 支持 | 支持 | 支持 | 支持 | 部分 | 支持 |
159
- | Universal 兼容布局 `.plugin/` | 支持 | 支持 | 支持 | 支持 | 部分 | 支持 |
160
- | [agent-plugins](https://agent-plugins.org) | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 |
161
- | 无清单技能集合 | 支持 | 支持 | 支持 | 支持 | 部分 | 部分 |
162
- | 项目原生目录 | 支持 | 支持 | 支持 | 支持 | 部分 | 不支持 |
163
-
164
- - **技能**读取清单声明的路径与约定的 `skills/` 目录,也支持平铺的 `<name>.md` 文件。自带 `SKILL.md` 的路径就是一个技能:与它并列的文档属于该技能,不作为技能读取。合规的 agent-plugins 套件是例外:技能只来自 `skills/` 一层子目录,与其规范一致。
165
- - **代理与命令**按 Markdown 读取(`agents/*.md`、`commands/*.md`)。Cursor 插件命令接受 `.md`、`.mdc`、`.markdown`、`.txt`;Codex 与 Kimi 的原生代理/命令格式(TOML、YAML)尚未适配。
166
- - **MCP** 支持声明的文件、内联表与数组。Cursor 的无 schema `mcp.json` 与 agent-plugins 的严格 `mcp.json` 都能读取;Kimi Code 只读内联声明。Codex 的 app 连接器不在适配范围内。
167
- - **Hooks** 只映射 DSH 有对应点的命令类事件;没有对应点的事件(例如 `afterFileEdit`)给出诊断而不伪造执行。Cursor 的原生事件不读取。
168
- - **LSP** 支持声明的文件、数组、内联表,以及约定的 `.lsp.json` / `lsp.json` 位置。项目内的 LSP 声明只给诊断、不挂载:宿主 LSP 注册表是全局的。部分布局只提供目录预览。
169
- - **agent-plugins** 套件按规范读取可移植核心(`skills/`、`mcp.json`),另通过本插件的 [`com.deepseek.harness`](schemas/com.deepseek.harness/spec.md) 扩展命名空间承载命令、代理、hooks、LSP 与逐服务器 MCP 策略(OAuth、工具清单、超时)。该布局下根目录的 `commands/`、`agents/`、`hooks/` 与 `.mcp.json` 属于其它布局,给出「未读取」诊断;清单内联组件键按 §5.2 报告后忽略。两个受支持的版本(1.0.0、1.1.0)各自按内置 schema 校验。
170
- - **Universal** 是本插件使用的兼容布局名称:[OpenHands SDK](https://docs.openhands.dev/sdk/guides/plugins)文档同样使用 `.plugin/plugin.json`,[Vercel 仓库](https://github.com/vercel/vercel-plugin/blob/main/.plugin/plugin.json)也在使用,但不存在跨厂商规范。
171
-
172
- [jeecgboot/skills](https://github.com/jeecgboot/skills) 这类源中,未声明插件且只包含技能的目录会聚合为一张插件卡片。市场条目、自带插件清单或其它运行面的目录仍保留独立身份。聚合插件需要单独安装,不继承单个技能的安装状态。详见[技能集合规则](schemas/skill-collection/spec.md)。
81
+ ## 日常使用
173
82
 
174
- 能读取一种布局,并不保证复现原平台的全部行为。无效声明会被诊断并跳过。
83
+ 工作区包含七个页签:
175
84
 
176
- ### 项目布局开关
85
+ | 页签 | 可以做什么 |
86
+ | -------- | ------------------------------------------------ |
87
+ | 插件市场 | 添加来源、预览套件、安装或卸载,以及启用或停用。 |
88
+ | 技能 | 浏览技能,创建或编辑自己的可复用指令。 |
89
+ | 命令 | 管理通过 `/名称` 调用的提示词模板。 |
90
+ | 代理角色 | 保存角色指令与模型配置,然后委派给它们。 |
91
+ | MCP 服务 | 新增服务,或配置已安装的服务及其凭据与授权。 |
92
+ | LSP 服务 | 新增并配置语言服务器,查看运行状态。 |
93
+ | Hooks | 查看已配置的 hook 及其事件、匹配条件与超时。 |
177
94
 
178
- 插件设置卡提供**扫描项目 Agent 布局**(`dsh-agent-plugins-market.scanProjectLayouts`,默认关闭)。它只控制一件事:当前项目是否把自己目录(`.claude`、`.agents`、`.codex`、`.cursor`、`.kimi`、`.zcode`、`.qoder`、`.github`)里的技能、命令、代理角色、MCP 服务与 hooks 贡献到会话里。开启后纳入这些候选,关闭后在下一轮发现时移除。卡片在你保存时生效,设置带着你自己填的值时也提供「恢复默认」。配置源与已安装套件不受影响。
95
+ **来源(source)**表示内容来自哪里,**套件(suite)**是从中发现的可安装单元。添加来源用于发现套件,启用套件决定其运行时能力是否生效。
179
96
 
180
- 每种布局读取哪些目录与文件、如何挂载,见[项目布局](docs/user/usage.zh.md#项目布局)。
97
+ 你自己创作的内容都放在 `~/.agents/` 下:技能、命令和角色是 Markdown 文件,hooks 放在 `hooks.json`,工作区里新增的 MCP 与 LSP 服务分别保存在 `mcp.json` 与 `lsp.json`。项目原生资源继续保留在项目中。路径与优先级见[存储与发现](https://github.com/Sivan757/dsh-agent-plugins-market/blob/main/docs/user/usage.zh.md#存储与发现)。
181
98
 
182
- ### 抽样验证
99
+ ## 兼容性
183
100
 
184
- README 中的仓库在 [`tests/fixtures/real-layouts/`](tests/fixtures/real-layouts/) 保留了离线快照(含提交号、哈希与许可证),且每种布局都有独立的读取测试。[兼容性报告](docs/reference/compat-report.md)记录抽样仓库、schema 结论与扫描器输出,[布局审计](docs/user/layout-coverage.zh.md)记录独立的资源核验。这些是文档、源码与抽样核验,并非每个平台的端到端兼容认证。
101
+ 插件读取十种布局方言,映射六类运行时能力。逐布局的支持情况与清单优先级见[兼容的插件市场](https://sivan757.github.io/dsh-agent-plugins-market/compatible-plugins/)。证据是[布局审计](https://github.com/Sivan757/dsh-agent-plugins-market/blob/main/docs/user/layout-coverage.zh.md)与[兼容性报告](https://github.com/Sivan757/dsh-agent-plugins-market/blob/main/docs/reference/compat-report.md)。
185
102
 
186
- 启用第三方套件前请检查其内容:启用的服务和 hooks 可以执行程序。详见[运行时与安全边界](docs/user/usage.zh.md#运行时与安全边界)。
103
+ 能读取某种布局,不等于它的每个行为都与原平台一致。无效声明会被诊断并跳过,不会只挂载一半。
187
104
 
188
105
  ## 常见问题
189
106
 
190
- **安装后为什么找不到技能或工具?**
191
-
192
- 检查套件及对应能力是否启用。技能可能限制手动调用;MCP / LSP 面板显示用户服务故障。项目资源还需要开启项目扫描;不支持的原生字段与项目 LSP 声明进入扫描诊断。
193
-
194
- **在哪里配置 MCP token?**
195
-
196
- 在 **MCP 服务**中打开对应服务。缺失环境变量引用时显示 `needs-credentials`。宿主管理的凭据只写不读;启动环境中的凭据需要修改环境后重启 DSH。
197
-
198
- **套件没有声明的服务怎么添加?**
199
-
200
- 在 **MCP 服务**或 **LSP 服务**中点击新增并填入声明。声明会先校验,保存到 `~/.agents/mcp.json` 或 `~/.agents/lsp.json`,并与套件服务走同一套挂载生命周期。从宿主配置观察到的服务保持只读。
201
-
202
- **来源会自动更新吗?**
203
-
204
- 只有开启**后台自动更新来源**后才会:开启后每 6 小时刷新一次全部已配置来源,第一次刷新在开启满一个周期之后。该开关默认关闭,刷新按钮始终可用。
205
-
206
- **没有添加任何来源,市场里的套件是从哪来的?**
207
-
208
- 插件预置一条指向自身套件集合的仓库源记录,所以首次运行市场里就列出该仓库;点**刷新**即可拉取其中的套件。此后它与其他来源完全一致——包括删除:和通过配置预置的来源一样,下次激活会重新登记。
107
+ **已安装的技能或工具为什么不见了?**
209
108
 
210
- **来源下载失败怎么办?**
109
+ 先确认套件与对应能力都已启用。MCP 与 LSP 面板会报告失败和缺失的凭据。项目资源还需要打开项目扫描开关。
211
110
 
212
- 可以使用本地目录、收编手动克隆的仓库,或配置代理与镜像,见[配置市场源](docs/user/usage.zh.md#配置市场源)。
111
+ **MCP 的令牌在哪里配置?**
213
112
 
214
- **本地修改什么时候生效?**
113
+ 在 **MCP 服务**中打开该服务。缺失的环境引用会显示 `needs-credentials`。宿主托管的凭据是只写的。
215
114
 
216
- 没有文件监听。本地来源的发现结果最多缓存 30 秒,刷新来源可立即使缓存失效。项目发现有独立的五秒缓存。已经打开的页面不会自动刷新。
115
+ **来源会自动刷新吗?**
217
116
 
218
- **删除来源会删除文件吗?**
117
+ 只有打开**后台更新来源**时才会。它每 6 小时刷新一次全部已配置来源,并在启用后一个周期开始。刷新按钮始终可用。
219
118
 
220
- 只有勾选确认框里的「同时删除市场目录」才会删除。它删除该源在 `~/.dsh/agent-plugins/.sources/<id>` 下的目录——包括你手动克隆后被收编的目录。指向 `.sources/` 之外的本地目录源永不删除。
119
+ **删除来源会删掉文件吗?**
221
120
 
222
- ## 仓库结构
121
+ 只有你在确认框中勾选**同时删除托管的市场目录**时才会。位于 `.sources/` 之外的本地目录来源永远不会被删除。
223
122
 
224
- 发布包仍为 `dsh-agent-plugins-market`,只产出一个构件。代码位于 `packages/` 下的八个私有工作区包:`market-bundle`(组合根与 HTTP 接口)、`market-catalog`(来源扫描与目录用例)、`market-contracts`(无状态共享记录)、`market-runtime`(会话选择与宿主副作用)、`market-mcp`、`market-lsp`、`market-translation` 与 `market-ui`(浏览器 bundle)。归属、依赖方向与迁移门禁记录在[领域工作区重构](docs/developer/design/domain-workspace-refactor.md);维护者维护的布局图见 [AGENTS.md](AGENTS.md)。
123
+ 更多问题见[常见问题](https://sivan757.github.io/dsh-agent-plugins-market/faq/)。
225
124
 
226
- ## 更多文档
125
+ ## 文档
227
126
 
228
- - [使用指南](docs/user/usage.zh.md):安装、来源配置、存储、宿主要求、项目布局、MCP / LSP 和反馈设置。
229
- - [插件规范](schemas/README.md):各布局的参考 schema 与依据、内置的 agent-plugins 契约(1.0.0、1.1.0),以及 [`com.deepseek.harness` 命名空间契约](schemas/com.deepseek.harness/spec.md)。
230
- - [兼容性报告](docs/reference/compat-report.md):每个 schema 一个真实仓库,含提交号、schema 结论与扫描器输出。
231
- - [贡献指南](CONTRIBUTING.md):开发环境、检查命令和 PR 流程。
232
- - [安全政策](SECURITY.md) · [版本记录](CHANGELOG.md) · [MIT 许可](LICENSE)。
233
- - [领域词汇](CONTEXT.md) · [架构设计](docs/developer/decisions/0001-catalog-centered-modular-refactor.md)。
234
- - [代理角色与存储](docs/user/agent-roles.zh.md):已安装资源切换、角色模型路由与目录迁移。
127
+ - [安装指南](https://sivan757.github.io/dsh-agent-plugins-market/install/):从环境要求到第一个套件,逐步说明。
128
+ - [使用指南](https://github.com/Sivan757/dsh-agent-plugins-market/blob/main/docs/user/usage.zh.md):来源配置、存储、项目布局、MCP、LSP 与各项设置。
129
+ - [兼容的插件市场](https://sivan757.github.io/dsh-agent-plugins-market/compatible-plugins/):布局、优先级与抽样验证。
130
+ - [插件规范](https://github.com/Sivan757/dsh-agent-plugins-market/blob/main/schemas/README.md):各布局的参考 schema,以及 [`com.deepseek.harness`](https://github.com/Sivan757/dsh-agent-plugins-market/blob/main/schemas/com.deepseek.harness/spec.md) 扩展命名空间。
131
+ - [贡献指南](https://github.com/Sivan757/dsh-agent-plugins-market/blob/main/CONTRIBUTING.md) · [安全策略](https://github.com/Sivan757/dsh-agent-plugins-market/blob/main/SECURITY.md) · [更新日志](https://github.com/Sivan757/dsh-agent-plugins-market/blob/main/CHANGELOG.md) · [MIT 许可](https://github.com/Sivan757/dsh-agent-plugins-market/blob/main/LICENSE)。
132
+ - [领域词汇表](https://github.com/Sivan757/dsh-agent-plugins-market/blob/main/CONTEXT.md) · [代理角色](https://github.com/Sivan757/dsh-agent-plugins-market/blob/main/docs/user/agent-roles.zh.md) · [发布流程](https://github.com/Sivan757/dsh-agent-plugins-market/blob/main/docs/developer/release/release-process.md)。
235
133
 
236
134
  ## 交流群
237
135
 
238
- 扫描下方二维码加入 **dsh-agent-plugins-market** 微信群,提问与提需求都可以在群里说。
136
+ 扫描二维码加入 **dsh-agent-plugins-market** 微信群,我们在这里答疑并收集功能建议。
239
137
 
240
138
  <div align="center">
241
- <img src="docs/screenshots/wechat-group.webp" alt="dsh-agent-plugins-market 微信群二维码" width="240" />
139
+ <img src="https://raw.githubusercontent.com/Sivan757/dsh-agent-plugins-market/main/docs/screenshots/wechat-group.webp" alt="dsh-agent-plugins-market 微信群二维码" width="240" />
242
140
  </div>
@@ -69,7 +69,10 @@ export function createSessionExtensions({ ctx, dataRoot, runtime, hostLocale })
69
69
  let scopedContributors;
70
70
  let selectedRoleSuites;
71
71
  let suiteSession;
72
- let listRoles = async () => [];
72
+ let listRoles = async () => ({
73
+ entries: [],
74
+ complete: false
75
+ });
73
76
  const mount = ({ catalog, panels, resources, readUserDeclarations }) => {
74
77
  ctx.inject(['agents', 'sessions', 'sessionQuery', 'tools'], hostCtx => {
75
78
  const eligible = (agent) => {
@@ -302,8 +305,12 @@ export function createSessionExtensions({ ctx, dataRoot, runtime, hostLocale })
302
305
  });
303
306
  listRoles = async (parent) => {
304
307
  const agent = parent;
308
+ // "Not ready" is not "no roles": the extension runtime may still be
309
+ // initializing or recovering, so an empty answer must not replace the
310
+ // published catalog. A read failure propagates for the same reason, and
311
+ // the catalog publisher turns both into "no new information".
305
312
  if (!agent || !extensionPresets?.ready(agent))
306
- return [];
313
+ return { entries: [], complete: false };
307
314
  const user = (await resources.agents.list(true))
308
315
  .filter(entry => entry.origin === 'user' && extensionPresets?.allows(agent, 'agents:' + (entry.id ?? entry.name)))
309
316
  .map(entry => ({ ...entry, title: entry.name, name: entry.id ?? entry.name, selectionEnabled: true }));
@@ -311,7 +318,7 @@ export function createSessionExtensions({ ctx, dataRoot, runtime, hostLocale })
311
318
  suites: () => selectedRoleSuites?.(agent) ?? Promise.resolve([]),
312
319
  selected: role => extensionPresets?.allows(agent, 'agents:' + role.name) === true
313
320
  });
314
- return [...user, ...project];
321
+ return { entries: [...user, ...project], complete: true };
315
322
  };
316
323
  };
317
324
  return {
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Structural filesystem questions, answered without trusting an error code.
3
+ *
4
+ * Operating systems disagree about which code a failed read carries: Windows
5
+ * can report `ENOENT` for a child of a path that exists as a file, which a
6
+ * code-only guard mistakes for a removed entry. A caller that tolerates "not
7
+ * there yet" asks this module instead, so the decision comes from the path
8
+ * shape rather than from the platform error vocabulary.
9
+ */
10
+ import { stat } from 'node:fs/promises';
11
+ import { dirname } from 'node:path';
12
+ /** One path's stat, or `undefined` when the path cannot be read. */
13
+ async function statOf(path) {
14
+ try {
15
+ return await stat(path);
16
+ }
17
+ catch {
18
+ return undefined;
19
+ }
20
+ }
21
+ /**
22
+ * Whether a path is confirmed absent rather than unreadable.
23
+ *
24
+ * An error code alone cannot separate a removed entry from an unreadable
25
+ * source, because a platform can report `ENOENT` for a child of a file. The
26
+ * path ancestors answer the question instead: when the nearest existing
27
+ * ancestor is a directory, the entry is genuinely gone, and when it is not a
28
+ * directory, the source cannot be read and the caller must fail closed.
29
+ * @param path - the path to classify.
30
+ * @returns `true` only when the path is confirmed absent.
31
+ */
32
+ export async function isAbsentPath(path) {
33
+ let current = path;
34
+ for (;;) {
35
+ const info = await statOf(current);
36
+ if (info !== undefined)
37
+ return current !== path && info.isDirectory();
38
+ const parent = dirname(current);
39
+ if (parent === current)
40
+ return true;
41
+ current = parent;
42
+ }
43
+ }
@@ -7,6 +7,7 @@ import { pluginRootOf } from '../../../market-catalog/src/index.js';
7
7
  import { isWithin, suiteDataDir } from '../../../market-catalog/src/index.js';
8
8
  import { parseSkillFrontmatter, stripFrontmatter } from '../../../market-catalog/src/index.js';
9
9
  import { parseFrontmatterRecord } from './panels/user-store.js';
10
+ import { isAbsentPath } from './fs-probe.js';
10
11
  /**
11
12
  * Id of one suite-owned document, whichever surface addresses it. The leading
12
13
  * `[` is what distinguishes a plugin entry from a user-authored one;
@@ -334,8 +335,8 @@ class PanelResources {
334
335
  : (suite.resources?.[this.kind] ?? (await defaultMarkdownResources(suite.root, this.kind)));
335
336
  for (const resource of files) {
336
337
  const { name, file } = resource;
337
- const rawText = await resourceText(resource).catch(error => {
338
- if (strict && error.code !== 'ENOENT')
338
+ const rawText = await resourceText(resource).catch(async (error) => {
339
+ if (strict && !(await isAbsentPath(file)))
339
340
  throw error;
340
341
  return undefined;
341
342
  });
@@ -14,6 +14,7 @@
14
14
  * @module application/user-store
15
15
  */
16
16
  import { readdir, readFile, rmdir, rm, stat } from 'node:fs/promises';
17
+ import { isAbsentPath } from '../fs-probe.js';
17
18
  import { dirname, join } from 'node:path';
18
19
  import { writeFileAtomic } from '@deepseek-ai/dsh-atomic-write';
19
20
  import { parseDocument, stringify } from 'yaml';
@@ -44,15 +45,48 @@ export const SKILL_ENTRY_SHAPES = ['skill-directory', 'file'];
44
45
  export function entryDocumentPath(dir, name, shape) {
45
46
  return shape === 'skill-directory' ? join(dir, name, SKILL_ENTRY_FILE) : join(dir, `${name}.md`);
46
47
  }
48
+ /**
49
+ * Whether one panel directory may be listed, answered structurally rather than
50
+ * from a listing failure.
51
+ *
52
+ * A path is either an existing directory, absent (a user who authored nothing
53
+ * has not broken anything), or something that can never hold entries. Only the
54
+ * first is listed; the second is a valid empty panel; the third is a broken
55
+ * configuration. Confirming the shape before listing keeps that decision
56
+ * independent of the code a `readdir` failure happens to carry.
57
+ * @param dir - the panel directory.
58
+ * @param strict - whether a broken configuration is an error or an empty read.
59
+ * @returns `true` when the directory is confirmed and may be listed.
60
+ */
61
+ async function confirmDirectory(dir, strict) {
62
+ let info;
63
+ try {
64
+ info = await stat(dir);
65
+ }
66
+ catch (error) {
67
+ // A directory is absent only when its ancestors stay searchable: a platform
68
+ // can report ENOENT for a child of a file, which is an unreadable panel.
69
+ if (await isAbsentPath(dir))
70
+ return false;
71
+ if (strict)
72
+ throw error;
73
+ return false;
74
+ }
75
+ if (info.isDirectory())
76
+ return true;
77
+ if (strict)
78
+ throw Object.assign(new Error(`ENOTDIR: not a directory, scandir '${dir}'`), { code: 'ENOTDIR' });
79
+ return false;
80
+ }
47
81
  /** Whether a path is a regular file; strict runtime snapshots propagate real I/O failures. */
48
82
  async function isFile(file, strict) {
49
83
  try {
50
84
  return (await stat(file)).isFile();
51
85
  }
52
86
  catch (error) {
53
- if (strict && error.code !== 'ENOENT')
54
- throw error;
55
- return false;
87
+ if (!strict || (await isAbsentPath(file)))
88
+ return false;
89
+ throw error;
56
90
  }
57
91
  }
58
92
  /**
@@ -83,14 +117,18 @@ export async function listEntryDocuments(dir, strict = false, shapes = ['file'],
83
117
  await collectNestedEntryDocuments(dir, '', shapes, strict, found);
84
118
  return [...found.values()].sort((a, b) => a.name.localeCompare(b.name));
85
119
  }
120
+ if (!(await confirmDirectory(dir, strict)))
121
+ return [];
86
122
  let entries;
87
123
  try {
88
124
  entries = await readdir(dir);
89
125
  }
90
126
  catch (error) {
91
- if (strict && error.code !== 'ENOENT')
92
- throw error;
93
- return [];
127
+ // Only a structurally confirmed absence is tolerated: the directory can be
128
+ // removed between the confirmation and the listing.
129
+ if (!strict || (await isAbsentPath(dir)))
130
+ return [];
131
+ throw error;
94
132
  }
95
133
  for (const entry of entries.sort()) {
96
134
  const name = entry.endsWith('.md') ? entry.slice(0, -3) : shapes.includes('skill-directory') ? entry : undefined;
@@ -114,14 +152,16 @@ export async function listEntryDocuments(dir, strict = false, shapes = ['file'],
114
152
  * `/` separators and no trailing slash.
115
153
  */
116
154
  async function collectNestedEntryDocuments(dir, prefix, shapes, strict, found) {
155
+ if (!(await confirmDirectory(dir, strict)))
156
+ return;
117
157
  let entries;
118
158
  try {
119
159
  entries = await readdir(dir, { withFileTypes: true });
120
160
  }
121
161
  catch (error) {
122
- if (strict && error.code !== 'ENOENT')
123
- throw error;
124
- return;
162
+ if (!strict || (await isAbsentPath(dir)))
163
+ return;
164
+ throw error;
125
165
  }
126
166
  for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
127
167
  if (entry.isSymbolicLink() || entry.name.startsWith('.') || entry.name === 'node_modules')
@@ -171,9 +211,9 @@ export async function readEntryDocument(document, strict = false) {
171
211
  text = await readFile(document.file, 'utf8');
172
212
  }
173
213
  catch (error) {
174
- if (strict && error.code !== 'ENOENT')
175
- throw error;
176
- return undefined;
214
+ if (!strict || (await isAbsentPath(document.file)))
215
+ return undefined;
216
+ throw error;
177
217
  }
178
218
  let meta;
179
219
  try {
@@ -3,6 +3,7 @@ import { defaultMarkdownResources, resourceText } from '../../../market-catalog/
3
3
  import { pluginRootOf } from '../../../market-catalog/src/index.js';
4
4
  import { suiteDataDir } from '../../../market-catalog/src/index.js';
5
5
  import { parseAgentRole } from './agent-roles.js';
6
+ import { isAbsentPath } from './fs-probe.js';
6
7
  export async function projectAgentRoles(catalog, parent, options = {}) {
7
8
  const cwd = parent?.session?.header?.cwd;
8
9
  if (typeof cwd !== 'string' || cwd === '')
@@ -16,8 +17,10 @@ export async function projectAgentRoles(catalog, parent, options = {}) {
16
17
  const suiteData = suiteRoot === undefined ? undefined : suiteDataDir(catalog.dataRoot, suite.sourceId, suite.id);
17
18
  for (const resource of suite.resources?.agents ?? (options.suites ? [] : await defaultMarkdownResources(suite.root, 'agents'))) {
18
19
  const path = resource.file;
19
- const rawText = await resourceText(options.suites && resource.file !== suite.manifest.path ? { name: resource.name, file: resource.file } : resource).catch(error => {
20
- if (error.code !== 'ENOENT')
20
+ const rawText = await resourceText(options.suites && resource.file !== suite.manifest.path ? { name: resource.name, file: resource.file } : resource).catch(async (error) => {
21
+ // A vanished document is an ordinary removal; any other failure must not
22
+ // silently drop a project role from the catalog.
23
+ if (!(await isAbsentPath(path)))
21
24
  throw error;
22
25
  return undefined;
23
26
  });
@@ -2,6 +2,7 @@
2
2
  import { readFile } from 'node:fs/promises';
3
3
  import { defineTool } from '@deepseek-ai/dsh-tools';
4
4
  import { mountSubagentCatalog } from './subagent-catalog.js';
5
+ import { isAbsentPath } from '../../application/fs-probe.js';
5
6
  import { namedAgentRoles } from './agent-role-names.js';
6
7
  import { expandPluginPaths } from '../../../../market-catalog/src/index.js';
7
8
  import { parseAgentRole } from '../../application/agent-roles.js';
@@ -98,7 +99,9 @@ export async function agentRoleCatalog(entries, signal, diagnose = () => { }, pr
98
99
  text = entry.rawText ?? (await readFile(entry.path, 'utf8'));
99
100
  }
100
101
  catch (error) {
101
- if (error.code !== 'ENOENT')
102
+ // Only a confirmed disappearance is a normal removal; any other failure
103
+ // aborts the publication instead of publishing a smaller catalog.
104
+ if (!(await isAbsentPath(entry.path)))
102
105
  throw error;
103
106
  continue;
104
107
  }
@@ -232,16 +235,13 @@ export async function executeAgentRole(host, listRoles, agentName, prompt, paren
232
235
  await run.dispose();
233
236
  }
234
237
  }
235
- /**
236
- * Mount once after tools, llm and subagents are available; the returned disposer belongs to the plugin lifecycle.
237
- *
238
- * The delegation contract lives here rather than in the injected catalog: a tool
239
- * description is present in every request, while the catalog message is
240
- * re-published whenever roles change, so guidance kept out of the catalog is
241
- * sent once and stays readable through compaction.
242
- */
238
+ /** Normalize one observation; a bare list means the read completed. */
239
+ export function roleSnapshot(observation) {
240
+ return Array.isArray(observation) ? { entries: observation, complete: true } : observation;
241
+ }
243
242
  export function mountAgentRoleTool(ctx, listRoles) {
244
243
  const host = ctx;
244
+ const entries = async (parent) => roleSnapshot(await listRoles(parent)).entries;
245
245
  const tool = defineTool({
246
246
  name: AGENT_ROLE_TOOL_NAME,
247
247
  description: "Delegate a task to a named role child from the session's subagent-catalog: the role's own instructions and its configured model apply, and the child starts without this conversation. Use it proactively for self-contained work — codebase exploration whose raw reads would fill this context, a scoped implementation, a review, or an analysis you can brief in one prompt — and start independent children together in one message. The child runs in " +
@@ -307,7 +307,7 @@ export function mountAgentRoleTool(ctx, listRoles) {
307
307
  // The parameter keeps the host tool's name, shape and semantics: only an
308
308
  // explicit `false` leaves the durable-child default for a foreground run.
309
309
  const mode = args.run_in_background === false ? 'foreground' : 'continuable';
310
- return executeAgentRole(host, listRoles, args.agent, args.prompt, exec.agent, {
310
+ return executeAgentRole(host, entries, args.agent, args.prompt, exec.agent, {
311
311
  ...(args.provider === undefined ? {} : { provider: args.provider }),
312
312
  ...(args.model === undefined ? {} : { model: args.model }),
313
313
  ...(args.reasoning_effort === undefined ? {} : { reasoningEffort: args.reasoning_effort })
@@ -317,7 +317,13 @@ export function mountAgentRoleTool(ctx, listRoles) {
317
317
  const disposeTool = host.tools.register(tool);
318
318
  let disposeCatalog;
319
319
  try {
320
- disposeCatalog = mountSubagentCatalog(ctx, tool, async (agent, signal) => agentRoleCatalog(await listRoles(agent), signal, message => ctx.logger?.warn(message), sessionCwd(agent)));
320
+ disposeCatalog = mountSubagentCatalog(ctx, tool, async (agent, signal) => {
321
+ const observation = roleSnapshot(await listRoles(agent));
322
+ return {
323
+ entries: await agentRoleCatalog(observation.entries, signal, message => ctx.logger?.warn(message), sessionCwd(agent)),
324
+ complete: observation.complete
325
+ };
326
+ });
321
327
  }
322
328
  catch (error) {
323
329
  disposeTool();
@@ -1,7 +1,17 @@
1
1
  /** Durable role catalogs follow DSH tool-skill's pre-step publication and session-surface recovery. */
2
2
  import { createHash } from 'node:crypto';
3
3
  import { createUserMessage } from '@deepseek-ai/dsh-llm';
4
- /** Register after the exact tool definition; teardown removes guidance before execution. */
4
+ /** Normalize the two accepted provider shapes; a bare list means it read everything. */
5
+ function normalizeSnapshot(observation) {
6
+ return Array.isArray(observation) ? { entries: observation, complete: true } : observation;
7
+ }
8
+ /**
9
+ * Register after the exact tool definition; teardown removes guidance before execution.
10
+ *
11
+ * The snapshot callback follows the host skill registry's provider protocol: it may
12
+ * return the entries directly (meaning a complete read) or an explicit snapshot
13
+ * whose `complete` flag reports whether every source answered.
14
+ */
5
15
  export function mountSubagentCatalog(ctx, tool, snapshot, mode = 'subagent_role') {
6
16
  const host = ctx;
7
17
  let disposed = false;
@@ -10,9 +20,9 @@ export function mountSubagentCatalog(ctx, tool, snapshot, mode = 'subagent_role'
10
20
  if (decision.kind === 'reject' || disposed)
11
21
  return decision;
12
22
  signal.throwIfAborted();
13
- let entries;
23
+ let observed;
14
24
  try {
15
- entries = host.tools.get(tool.name, agent) === tool ? await snapshot(agent, signal) : [];
25
+ observed = normalizeSnapshot(host.tools.get(tool.name, agent) === tool ? await snapshot(agent, signal) : { entries: [], complete: true });
16
26
  }
17
27
  catch (error) {
18
28
  signal.throwIfAborted();
@@ -22,6 +32,12 @@ export function mountSubagentCatalog(ctx, tool, snapshot, mode = 'subagent_role'
22
32
  signal.throwIfAborted();
23
33
  if (disposed)
24
34
  return decision;
35
+ // A reader that could not enumerate every source publishes nothing: the
36
+ // previous catalog stays the model's authority until a complete read says
37
+ // otherwise, so a temporarily unreadable directory cannot shrink the list.
38
+ if (!observed.complete)
39
+ return decision;
40
+ let entries = [...observed.entries];
25
41
  if (host.tools.get(tool.name, agent) !== tool)
26
42
  entries = [];
27
43
  const digest = digestEntries(entries);
@@ -1,12 +1,13 @@
1
1
  import { resolveChildAgentOptions } from '@deepseek-ai/dsh-subagent';
2
2
  import { defineTool } from '@deepseek-ai/dsh-tools';
3
- import { agentRoleCatalog, requireCurrentRole, resolveAgentOptions, resolveRolePolicy, sessionCwd } from './agent-role-router.js';
3
+ import { agentRoleCatalog, requireCurrentRole, resolveAgentOptions, resolveRolePolicy, roleSnapshot, sessionCwd } from './agent-role-router.js';
4
4
  import { mountSubagentCatalog } from './subagent-catalog.js';
5
5
  import { TeammateRoleRuntime } from './teammate-role-runtime.js';
6
6
  export const TEAMMATE_ROLE_TOOL_NAME = 'spawn_teammate_role';
7
7
  /** Install the enhanced tool after its replay listener is ready; teardown drains owned role creations. */
8
8
  export async function mountTeammateRoleTool(ctx, listRoles) {
9
9
  const runtime = new TeammateRoleRuntime(ctx);
10
+ const entries = async (parent) => roleSnapshot(await listRoles(parent)).entries;
10
11
  const cleanups = [];
11
12
  try {
12
13
  await runtime.restore();
@@ -48,7 +49,7 @@ export async function mountTeammateRoleTool(ctx, listRoles) {
48
49
  exec.signal.throwIfAborted();
49
50
  if (ctx.agentTeams.membership(parent).role !== 'lead')
50
51
  throw new Error('only the Team Lead can create role teammates');
51
- const { entry, policy } = await resolveRolePolicy(listRoles, args.agent, parent);
52
+ const { entry, policy } = await resolveRolePolicy(entries, args.agent, parent);
52
53
  const options = await resolveAgentOptions(policy, {
53
54
  ...(args.provider === undefined ? {} : { provider: args.provider }),
54
55
  ...(args.model === undefined ? {} : { model: args.model }),
@@ -60,7 +61,7 @@ export async function mountTeammateRoleTool(ctx, listRoles) {
60
61
  throw new Error('role teammate requires an effective provider and model');
61
62
  // The route lookup awaited the live LLM runtime; a role revoked during
62
63
  // it must not become a Team member.
63
- await requireCurrentRole(listRoles, entry, parent);
64
+ await requireCurrentRole(entries, entry, parent);
64
65
  exec.signal.throwIfAborted();
65
66
  return runtime.spawn(parent, args, {
66
67
  roleId: entry.name,
@@ -105,9 +106,15 @@ export async function mountTeammateRoleTool(ctx, listRoles) {
105
106
  });
106
107
  for (const agent of ctx.agents.list())
107
108
  denyFor(agent);
108
- cleanups.push(mountSubagentCatalog(ctx, tool, async (agent, signal) => ctx.agentTeams.tryMembership(agent)?.role === 'lead'
109
- ? agentRoleCatalog(await listRoles(agent), signal, message => ctx.logger.warn(message), sessionCwd(agent))
110
- : [], 'spawn_teammate_role'));
109
+ cleanups.push(mountSubagentCatalog(ctx, tool, async (agent, signal) => {
110
+ if (ctx.agentTeams.tryMembership(agent)?.role !== 'lead')
111
+ return { entries: [], complete: true };
112
+ const observation = roleSnapshot(await listRoles(agent));
113
+ return {
114
+ entries: await agentRoleCatalog(observation.entries, signal, message => ctx.logger.warn(message), sessionCwd(agent)),
115
+ complete: observation.complete
116
+ };
117
+ }, 'spawn_teammate_role'));
111
118
  return async () => {
112
119
  for (const off of cleanups.splice(0).reverse())
113
120
  off();
@@ -24,7 +24,10 @@ interface SessionExtensions {
24
24
  invalidate(invalidateDefaultSkills: () => void): void;
25
25
  refresh(): Promise<void> | undefined;
26
26
  commandRegistrations(): ReturnType<ScopedExtensionContributors['registrations']>;
27
- roles: (parent?: unknown) => ReturnType<typeof projectAgentRoles>;
27
+ roles: (parent?: unknown) => Promise<{
28
+ entries: Awaited<ReturnType<typeof projectAgentRoles>>;
29
+ complete: boolean;
30
+ }>;
28
31
  session(): SuiteRouteSessionResolver | undefined;
29
32
  }
30
33
  /** The catalog reads the settings Hooks page needs. */
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Whether a path is confirmed absent rather than unreadable.
3
+ *
4
+ * An error code alone cannot separate a removed entry from an unreadable
5
+ * source, because a platform can report `ENOENT` for a child of a file. The
6
+ * path ancestors answer the question instead: when the nearest existing
7
+ * ancestor is a directory, the entry is genuinely gone, and when it is not a
8
+ * directory, the source cannot be read and the caller must fail closed.
9
+ * @param path - the path to classify.
10
+ * @returns `true` only when the path is confirmed absent.
11
+ */
12
+ export declare function isAbsentPath(path: string): Promise<boolean>;
@@ -166,4 +166,21 @@ export declare function executeAgentRole(host: AgentRoleHost, listRoles: (parent
166
166
  * re-published whenever roles change, so guidance kept out of the catalog is
167
167
  * sent once and stays readable through compaction.
168
168
  */
169
- export declare function mountAgentRoleTool(ctx: Context, listRoles: (parent?: unknown) => Promise<AgentRoleEntry[]>): () => void;
169
+ /**
170
+ * One observation of the parent-scoped role source.
171
+ *
172
+ * The complete flag is the discovery contract the host skill registry uses: a
173
+ * reader that could not enumerate every source reports an incomplete
174
+ * observation, and the catalog publisher never replaces a published list from
175
+ * one, because a failed read is not evidence that its roles were removed. A
176
+ * bare entry list is the older protocol and means the read completed.
177
+ */
178
+ export interface AgentRoleSnapshot {
179
+ entries: AgentRoleEntry[];
180
+ complete: boolean;
181
+ }
182
+ /** A role reader answers with entries directly or with an explicit snapshot. */
183
+ export type AgentRoleObservation = AgentRoleEntry[] | AgentRoleSnapshot;
184
+ /** Normalize one observation; a bare list means the read completed. */
185
+ export declare function roleSnapshot(observation: AgentRoleObservation): AgentRoleSnapshot;
186
+ export declare function mountAgentRoleTool(ctx: Context, listRoles: (parent?: unknown) => Promise<AgentRoleObservation>): () => void;
@@ -51,10 +51,31 @@ export type CatalogStepListener = (payload: {
51
51
  agent: CatalogAgent;
52
52
  signal: AbortSignal;
53
53
  }, next: () => Promise<CatalogStepDecision>) => Promise<CatalogStepDecision>;
54
- /** Register after the exact tool definition; teardown removes guidance before execution. */
54
+ /**
55
+ * One observation of the roles a session can delegate to.
56
+ *
57
+ * The complete flag is the discovery contract the host skill registry already
58
+ * uses: an observation that could not read every source carries no authority to
59
+ * replace the published list, because a failed read is not evidence that its
60
+ * roles were removed. Only a complete observation may publish, including a
61
+ * complete observation that is genuinely empty.
62
+ */
63
+ export interface SubagentCatalogSnapshot {
64
+ entries: readonly SubagentCatalogEntry[];
65
+ complete: boolean;
66
+ }
67
+ /** A snapshot, or a bare entry list, which the protocol treats as complete. */
68
+ export type SubagentCatalogObservation = SubagentCatalogEntry[] | SubagentCatalogSnapshot;
69
+ /**
70
+ * Register after the exact tool definition; teardown removes guidance before execution.
71
+ *
72
+ * The snapshot callback follows the host skill registry's provider protocol: it may
73
+ * return the entries directly (meaning a complete read) or an explicit snapshot
74
+ * whose `complete` flag reports whether every source answered.
75
+ */
55
76
  export declare function mountSubagentCatalog(ctx: Context, tool: {
56
77
  name: string;
57
- }, snapshot: (agent: CatalogAgent, signal: AbortSignal) => Promise<SubagentCatalogEntry[]>, mode?: 'subagent_role' | 'spawn_teammate_role'): () => void;
78
+ }, snapshot: (agent: CatalogAgent, signal: AbortSignal) => Promise<SubagentCatalogObservation>, mode?: 'subagent_role' | 'spawn_teammate_role'): () => void;
58
79
  /**
59
80
  * Model-facing catalog text: the delegation triggers, then the role list, then
60
81
  * the same guidance on first publication and on every update, so a replacement
@@ -1,6 +1,6 @@
1
1
  /** Role-aware creation is an additional Team entry point, not another member manager. */
2
2
  import type { Context } from '@deepseek-ai/cordis';
3
- import { type AgentRoleEntry } from './agent-role-router.js';
3
+ import { type AgentRoleObservation } from './agent-role-router.js';
4
4
  export declare const TEAMMATE_ROLE_TOOL_NAME = "spawn_teammate_role";
5
5
  /** Install the enhanced tool after its replay listener is ready; teardown drains owned role creations. */
6
- export declare function mountTeammateRoleTool(ctx: Context, listRoles: (parent?: unknown) => Promise<AgentRoleEntry[]>): Promise<() => Promise<void>>;
6
+ export declare function mountTeammateRoleTool(ctx: Context, listRoles: (parent?: unknown) => Promise<AgentRoleObservation>): Promise<() => Promise<void>>;
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "dsh-agent-plugins-market",
3
3
  "icon": "./assets/dsh-agent-plugins.png",
4
4
  "description": "One-stop skills, subagent, MCP and LSP manager inside DeepSeek Harness (DSH), compatible with Claude Code, Codex, Cursor, Kimi and other agent plugin layouts.",
5
- "version": "0.9.1",
5
+ "version": "0.9.2",
6
6
  "type": "module",
7
7
  "main": "lib/index.js",
8
8
  "types": "lib/types/index.d.ts",
package/schemas/README.md CHANGED
@@ -29,7 +29,7 @@ schemas/
29
29
 
30
30
  ## Dialect index
31
31
 
32
- This table records **upstream client conventions**, including their own fallback orders; it does not define this plugin's discovery priority. DSH uses one shared layout order for suite manifests and Marketplace catalogs, shown in the [README priority table](../README.md#layout-detection-precedence) ([中文](../README.zh.md#布局识别优先级)). Catalogs without a dedicated layout use root `marketplace.json` as the final fallback.
32
+ This table records **upstream client conventions**, including their own fallback orders; it does not define this plugin's discovery priority. DSH uses one shared layout order for suite manifests and Marketplace catalogs, shown on the [compatible plugins page](https://sivan757.github.io/dsh-agent-plugins-market/compatible-plugins/#shared-layout-precedence). Catalogs without a dedicated layout use root `marketplace.json` as the final fallback.
33
33
 
34
34
  | Dialect | Upstream plugin manifest conventions | Upstream marketplace conventions | Upstream schema |
35
35
  | --- | --- | --- | --- |