dsh-agent-plugins-market 0.7.2 → 0.8.1
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 +11 -3
- package/README.zh.md +11 -3
- package/client/client.js +61 -44
- package/client/client.js.map +1 -1
- package/lib/application/catalog.js +9 -2
- package/lib/catalog/component-files.js +3 -1
- package/lib/catalog/native-project.js +1 -1
- package/lib/catalog/project-config.js +0 -2
- package/lib/catalog/project-hooks.js +12 -7
- package/lib/catalog/surfaces.js +17 -10
- package/lib/index.js +23 -2
- package/lib/model/command-names.js +14 -0
- package/lib/model/layouts.js +1 -0
- package/lib/runtime/commands-mounts.js +3 -2
- package/lib/runtime/hooks-mounts.js +7 -4
- package/lib/runtime/mcp-backend.js +3 -2
- package/lib/runtime/mcp-direct-config.js +18 -9
- package/lib/runtime/plugin-message-source.js +4 -0
- package/lib/runtime/project-runtime.js +10 -8
- package/lib/runtime/settings-namespace.js +44 -66
- package/lib/runtime/user-commands.js +23 -8
- package/lib/runtime/user-hooks.js +102 -0
- package/lib/runtime/user-panels.js +34 -22
- package/lib/runtime/user-store.js +81 -19
- package/lib/types/catalog/component-files.d.ts +1 -0
- package/lib/types/catalog/project-hooks.d.ts +15 -2
- package/lib/types/catalog/surfaces.d.ts +6 -4
- package/lib/types/contracts/market.d.ts +5 -1
- package/lib/types/index.d.ts +87 -1
- package/lib/types/model/command-names.d.ts +12 -0
- package/lib/types/model/layouts.d.ts +1 -0
- package/lib/types/model/types.d.ts +2 -1
- package/lib/types/runtime/mcp-backend.d.ts +20 -13
- package/lib/types/runtime/mcp-direct-config.d.ts +1 -5
- package/lib/types/runtime/plugin-message-source.d.ts +24 -0
- package/lib/types/runtime/settings-namespace.d.ts +41 -31
- package/lib/types/runtime/user-commands.d.ts +5 -2
- package/lib/types/runtime/user-hooks.d.ts +22 -0
- package/lib/types/runtime/user-panels.d.ts +35 -15
- package/lib/types/runtime/user-store.d.ts +27 -10
- package/package.json +38 -31
- package/schemas/com.deepseek.harness/spec.md +1 -1
|
@@ -22,19 +22,26 @@ export type McpBackend = 'builtin' | 'host';
|
|
|
22
22
|
* belong to {@link MARKET_SETTINGS_DEFAULTS}; this schema states them, it does
|
|
23
23
|
* not own them.
|
|
24
24
|
*/
|
|
25
|
-
export declare const
|
|
26
|
-
mcpEnhanced: z<boolean, boolean>;
|
|
27
|
-
scanProjectLayouts: z<boolean, boolean>;
|
|
28
|
-
downloadRegion: z<"auto" | "global" | "china", "auto" | "global" | "china">;
|
|
29
|
-
feedbackEnabled: z<boolean, boolean>;
|
|
30
|
-
autoUpdateSources: z<boolean, boolean>;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
25
|
+
export declare const MarketSettingsFields: {
|
|
26
|
+
readonly mcpEnhanced: z<boolean, boolean, "defined">;
|
|
27
|
+
readonly scanProjectLayouts: z<boolean, boolean, "defined">;
|
|
28
|
+
readonly downloadRegion: z<"auto" | "global" | "china", "auto" | "global" | "china", "defined">;
|
|
29
|
+
readonly feedbackEnabled: z<boolean, boolean, "defined">;
|
|
30
|
+
readonly autoUpdateSources: z<boolean, boolean, "defined">;
|
|
31
|
+
};
|
|
32
|
+
export declare const MarketSettingsSchema: z<Schemastery.ObjectS<NoInfer<{
|
|
33
|
+
readonly mcpEnhanced: z<boolean, boolean, "defined">;
|
|
34
|
+
readonly scanProjectLayouts: z<boolean, boolean, "defined">;
|
|
35
|
+
readonly downloadRegion: z<"auto" | "global" | "china", "auto" | "global" | "china", "defined">;
|
|
36
|
+
readonly feedbackEnabled: z<boolean, boolean, "defined">;
|
|
37
|
+
readonly autoUpdateSources: z<boolean, boolean, "defined">;
|
|
38
|
+
}>>, Schemastery.ObjectT<NoInfer<{
|
|
39
|
+
readonly mcpEnhanced: z<boolean, boolean, "defined">;
|
|
40
|
+
readonly scanProjectLayouts: z<boolean, boolean, "defined">;
|
|
41
|
+
readonly downloadRegion: z<"auto" | "global" | "china", "auto" | "global" | "china", "defined">;
|
|
42
|
+
readonly feedbackEnabled: z<boolean, boolean, "defined">;
|
|
43
|
+
readonly autoUpdateSources: z<boolean, boolean, "defined">;
|
|
44
|
+
}>>, "plain">;
|
|
38
45
|
/** Path of the legacy persisted settings file under the plugin data root. */
|
|
39
46
|
export declare function marketSettingsPath(dataRoot: string): string;
|
|
40
47
|
/** Read the legacy persisted backend; absent or invalid values read as the default. */
|
|
@@ -2,11 +2,7 @@ import { type McpSuiteConfig, type Suite } from '../model/types.js';
|
|
|
2
2
|
export declare const USER_MCP_SOURCE = "@user-mcp";
|
|
3
3
|
export declare const USER_MCP_SUITE = "user-mcp";
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* The declarations live in the shared Agent layout root
|
|
8
|
-
* (`~/.agents/mcp.json`), so a service the user adds by hand is ordinary
|
|
9
|
-
* `mcpServers` JSON in the same place other Agent tools look.
|
|
5
|
+
* Load the user's own MCP declaration file.
|
|
10
6
|
*
|
|
11
7
|
* The suite always carries an `mcp` document — an absent or malformed
|
|
12
8
|
* `mcp.json` leaves an empty one — so callers read `.mcp.servers` directly
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Message source this plugin declares for the bodies it injects as follow-up
|
|
3
|
+
* messages: suite command bodies and user command bodies ride the receiving
|
|
4
|
+
* agent's inbox with their producer identity attached. The host's message
|
|
5
|
+
* sources are merge-extensible — each producer declares its own kind through a
|
|
6
|
+
* module augmentation, and consumers fall through unknown kinds.
|
|
7
|
+
* @module runtime/plugin-message-source
|
|
8
|
+
*/
|
|
9
|
+
import type { UserMessage } from '@deepseek-ai/dsh-llm';
|
|
10
|
+
/** Producer identity of every follow-up message this plugin injects. */
|
|
11
|
+
export interface PluginMarketSource {
|
|
12
|
+
kind: 'plugin-market';
|
|
13
|
+
/** The injected body is author-written instruction text: a suite or user command body. */
|
|
14
|
+
form: 'instructions';
|
|
15
|
+
}
|
|
16
|
+
declare module '@deepseek-ai/dsh-llm' {
|
|
17
|
+
interface MessageSourceMap {
|
|
18
|
+
'plugin-market': PluginMarketSource;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
/** Build the source for one follow-up message; fresh per message, no shared state. */
|
|
22
|
+
export declare function pluginMarketSource(): PluginMarketSource;
|
|
23
|
+
/** A follow-up message this plugin injects. */
|
|
24
|
+
export type PluginMarketMessage = UserMessage;
|
|
@@ -1,25 +1,39 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The
|
|
2
|
+
* The market settings the host carries in this plugin's own config: the loader
|
|
3
|
+
* projects the entry's `Config` schema into the `dsh-agent-plugins-market`
|
|
4
|
+
* settings namespace, so the Plugins panel's configuration page reads and
|
|
5
|
+
* writes these five switches, and the host updates the volatile references in
|
|
6
|
+
* place on every change (emitting `loader/volatile-update`).
|
|
3
7
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* throws on a duplicate namespace, so there is exactly one inject block and one
|
|
9
|
-
* registration.
|
|
10
|
-
*
|
|
11
|
-
* The whole callback is failure-contained on purpose: a throw inside it is
|
|
12
|
-
* INVISIBLE in the UI (the inject resolves asynchronously and cordis only logs
|
|
13
|
-
* it) and silently removes the namespace from `settings.describe`, which is
|
|
14
|
-
* what hides the plugin-config card. Every failure mode lands in the logger
|
|
15
|
-
* with a loud prefix instead.
|
|
8
|
+
* Every consumer reads through {@link MarketSettingsNamespace.settings} so
|
|
9
|
+
* "the field is absent" has exactly one answer —
|
|
10
|
+
* {@link resolveMarketSettings} — instead of each caller inventing its own
|
|
11
|
+
* fallback for the window before the host applies its first value.
|
|
16
12
|
*
|
|
17
13
|
* @module runtime/settings-namespace
|
|
18
14
|
*/
|
|
19
15
|
import type { Context } from '@deepseek-ai/cordis';
|
|
20
16
|
import { type DownloadRegionSetting } from '../contracts/settings.js';
|
|
21
17
|
import type { HostTranslate } from './host-locale.js';
|
|
22
|
-
import {
|
|
18
|
+
import type { McpBackend } from './mcp-backend.js';
|
|
19
|
+
/** The five volatile references the entry's config carries for this namespace. */
|
|
20
|
+
export interface MarketSettingRefs {
|
|
21
|
+
mcpEnhanced: {
|
|
22
|
+
get(): boolean | undefined;
|
|
23
|
+
};
|
|
24
|
+
scanProjectLayouts: {
|
|
25
|
+
get(): boolean | undefined;
|
|
26
|
+
};
|
|
27
|
+
downloadRegion: {
|
|
28
|
+
get(): DownloadRegionSetting | undefined;
|
|
29
|
+
};
|
|
30
|
+
feedbackEnabled: {
|
|
31
|
+
get(): boolean | undefined;
|
|
32
|
+
};
|
|
33
|
+
autoUpdateSources: {
|
|
34
|
+
get(): boolean | undefined;
|
|
35
|
+
};
|
|
36
|
+
}
|
|
23
37
|
/** Runtime reactions the namespace drives. */
|
|
24
38
|
export interface SettingsNamespaceHost {
|
|
25
39
|
/** Apply the project-layout discovery switch; rejection is logged and contained. */
|
|
@@ -31,10 +45,10 @@ export interface SettingsNamespaceHost {
|
|
|
31
45
|
}
|
|
32
46
|
export declare class MarketSettingsNamespace {
|
|
33
47
|
private readonly ctx;
|
|
48
|
+
private readonly refs;
|
|
34
49
|
private readonly dataRoot;
|
|
35
50
|
private readonly locale;
|
|
36
51
|
private readonly host;
|
|
37
|
-
private scope;
|
|
38
52
|
private readonly watchers;
|
|
39
53
|
private feedbackDisposer;
|
|
40
54
|
/**
|
|
@@ -44,31 +58,27 @@ export declare class MarketSettingsNamespace {
|
|
|
44
58
|
* switch, or skipped because the host has no tools registry to register on.
|
|
45
59
|
*/
|
|
46
60
|
private feedbackMountState;
|
|
47
|
-
constructor(ctx: Context, dataRoot: string, locale: {
|
|
61
|
+
constructor(ctx: Context, refs: MarketSettingRefs, dataRoot: string, locale: {
|
|
48
62
|
t: HostTranslate;
|
|
49
63
|
}, host: SettingsNamespaceHost);
|
|
50
|
-
/**
|
|
64
|
+
/** Subscribe the runtime reactions to live settings updates. */
|
|
51
65
|
mount(): void;
|
|
52
|
-
/**
|
|
66
|
+
/** Release every watcher and unmount the feedback tool. */
|
|
67
|
+
dispose(): void;
|
|
68
|
+
/**
|
|
69
|
+
* The resolved settings, from the volatile references the host updates in place.
|
|
70
|
+
*/
|
|
71
|
+
private settings;
|
|
72
|
+
/** The persisted MCP backend choice; the built-in client until the host applies a value. */
|
|
53
73
|
backend(): Promise<McpBackend>;
|
|
54
74
|
/**
|
|
55
|
-
*
|
|
56
|
-
*
|
|
75
|
+
* Legacy write path for the backend choice: the value now lives in the host
|
|
76
|
+
* settings document, edited from the Plugins panel's configuration page, so
|
|
77
|
+
* this accepts the request and lets the volatile reference decide.
|
|
57
78
|
*/
|
|
58
79
|
setBackend(backend: McpBackend): Promise<void>;
|
|
59
80
|
/** The persisted download-region setting. */
|
|
60
81
|
downloadRegion(): Promise<DownloadRegionSetting>;
|
|
61
|
-
/**
|
|
62
|
-
* The resolved settings, whether or not the namespace is registered yet.
|
|
63
|
-
*
|
|
64
|
-
* Every reader goes through here so "the field is absent" has exactly one
|
|
65
|
-
* answer — {@link resolveMarketSettings} — instead of each caller inventing
|
|
66
|
-
* its own fallback for the window before registration lands.
|
|
67
|
-
*/
|
|
68
|
-
private settings;
|
|
69
|
-
/** Release every watcher and unmount the feedback tool. */
|
|
70
|
-
dispose(): void;
|
|
71
|
-
private register;
|
|
72
82
|
/** Apply the background source-update switch. */
|
|
73
83
|
private syncAutoUpdateSources;
|
|
74
84
|
private syncProjectLayouts;
|
|
@@ -2,8 +2,11 @@
|
|
|
2
2
|
* User command mounting: every enabled entry of the user commands panel
|
|
3
3
|
* registers as a dsh slash command, so user-authored quick replies behave
|
|
4
4
|
* exactly like suite commands — the body with `$ARGUMENTS` substituted rides
|
|
5
|
-
* one follow-up message on the receiving agent.
|
|
6
|
-
*
|
|
5
|
+
* one follow-up message on the receiving agent. A nested entry registers
|
|
6
|
+
* under its flattened call name (`git/commit` → `git-commit`) while the panel
|
|
7
|
+
* keeps addressing it by path; when two entries flatten to one call name the
|
|
8
|
+
* first registers and the other is reported. Reconciled on every catalog
|
|
9
|
+
* change, keyed by the call name.
|
|
7
10
|
* @module runtime/user-commands
|
|
8
11
|
*/
|
|
9
12
|
import type { Context } from '@deepseek-ai/cordis';
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type Suite } from '../model/types.js';
|
|
2
|
+
export declare const USER_HOOKS_SOURCE = "@user-hooks";
|
|
3
|
+
export declare const USER_HOOKS_SUITE = "user-hooks";
|
|
4
|
+
/**
|
|
5
|
+
* The Agent layout root's hook documents, relative to that root and read in
|
|
6
|
+
* order. Later files merge additively over earlier ones, the same order and
|
|
7
|
+
* semantics the project `.agents` layout applies. The first entry is also the
|
|
8
|
+
* suite's manifest path and the file a suite with no documents is addressed by.
|
|
9
|
+
*/
|
|
10
|
+
export declare const USER_HOOK_FILES: readonly [string, string];
|
|
11
|
+
/** Resolve one Agent-layout-relative hook document against the layout root. */
|
|
12
|
+
export declare function userHookPath(agentsRoot: string, file: string): string;
|
|
13
|
+
/**
|
|
14
|
+
* Load the user's Agent layout hooks as one synthetic suite.
|
|
15
|
+
*
|
|
16
|
+
* The suite is always built, so one call answers with both the events and the
|
|
17
|
+
* reasons a document was rejected: an absent, malformed, or event-free set of
|
|
18
|
+
* hook files leaves `surfaces.hooks` at 0 and carries the diagnostics.
|
|
19
|
+
* {@link ../application/catalog.ts} merges the suite into the enabled set only
|
|
20
|
+
* when it declares events.
|
|
21
|
+
*/
|
|
22
|
+
export declare function loadUserHooksSuite(agentsRoot: string): Promise<Suite>;
|
|
@@ -12,15 +12,21 @@
|
|
|
12
12
|
* personas follow Claude Code agents frontmatter (`name`, `description`,
|
|
13
13
|
* optional `whenToUse`, `tools`, `model`, `disabled`).
|
|
14
14
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
15
|
+
* Every panel reads the flat `<name>.md` children of its directory. The
|
|
16
|
+
* commands and agent-persona panels also read every `.md` document at any
|
|
17
|
+
* depth, addressing a nested entry by its path relative to the panel
|
|
18
|
+
* directory (`git/commit`, `review/code`), so subdirectories another Agent
|
|
19
|
+
* tool writes are picked up. The skills panel keeps the cross-tool
|
|
20
|
+
* `<name>/SKILL.md` directory spelling and reads it from the top level only,
|
|
21
|
+
* matching the harness's own reader of `~/.agents/skills`.
|
|
17
22
|
*
|
|
18
23
|
* An entry's name is the one its document declares — the same name the
|
|
19
|
-
* harness reader derives from that file —
|
|
20
|
-
* deletes the entry by that name. A document that
|
|
21
|
-
* listed disabled with the reason instead of joining
|
|
22
|
-
* is switched off by writing that reader's own
|
|
23
|
-
* state lives in the file rather than in this
|
|
24
|
+
* harness reader derives from that file — else its document name, and the
|
|
25
|
+
* panel addresses, edits, and deletes the entry by that name. A document that
|
|
26
|
+
* reader would reject is listed disabled with the reason instead of joining
|
|
27
|
+
* the catalog, and a skill is switched off by writing that reader's own
|
|
28
|
+
* invocation controls, so the off state lives in the file rather than in this
|
|
29
|
+
* provider.
|
|
24
30
|
* @module runtime/user-panels
|
|
25
31
|
*/
|
|
26
32
|
import type { SkillCandidate, SkillDefinition, SkillLookupOptions, SkillProvider } from '@deepseek-ai/dsh-skill';
|
|
@@ -29,7 +35,11 @@ import { type EntryShape, type UserEntryFile } from './user-store.js';
|
|
|
29
35
|
export declare const USER_PANEL_SKILL_SOURCE = "user-panel";
|
|
30
36
|
/** A user panel entry as the HTTP layer serializes it. */
|
|
31
37
|
export interface UserPanelEntry {
|
|
32
|
-
/**
|
|
38
|
+
/**
|
|
39
|
+
* Entry name: the name its document declares, else its document name — the
|
|
40
|
+
* file's base name, or, on a nested panel, the document's path relative to
|
|
41
|
+
* the panel directory (`git/commit`).
|
|
42
|
+
*/
|
|
33
43
|
name: string;
|
|
34
44
|
description: string;
|
|
35
45
|
/** True when the entry is disabled, either by its `disabled` frontmatter key or by a failed validation. */
|
|
@@ -47,10 +57,16 @@ export interface UserPanelEntry {
|
|
|
47
57
|
}
|
|
48
58
|
/** How one panel store treats names and on-disk spellings. */
|
|
49
59
|
export interface UserPanelStoreOptions {
|
|
50
|
-
/** Extra
|
|
60
|
+
/** Extra grammar one path segment must satisfy (runs after USER_ENTRY_NAME on each segment). */
|
|
51
61
|
extraNameCheck?: (name: string) => boolean;
|
|
52
62
|
/** The document spellings this panel serves, most preferred first. */
|
|
53
63
|
shapes?: readonly EntryShape[];
|
|
64
|
+
/**
|
|
65
|
+
* Read every subdirectory of the panel directory and address an entry by its
|
|
66
|
+
* path relative to that directory. Off for the skills panel, whose reader
|
|
67
|
+
* sees top-level documents only.
|
|
68
|
+
*/
|
|
69
|
+
nested?: boolean;
|
|
54
70
|
/**
|
|
55
71
|
* Rejection for a document this panel must not register, or `undefined` when
|
|
56
72
|
* it may. Skills validate against the harness reader that shares their
|
|
@@ -72,17 +88,20 @@ export declare class UserPanelStore {
|
|
|
72
88
|
private readonly kind;
|
|
73
89
|
private readonly shapes;
|
|
74
90
|
private readonly extraNameCheck;
|
|
91
|
+
private readonly namePattern;
|
|
92
|
+
private readonly nested;
|
|
75
93
|
private readonly validate;
|
|
76
94
|
private readonly honorInvocationControls;
|
|
77
95
|
constructor(agentsRoot: string, kind: 'skills' | 'commands' | 'agents', options?: UserPanelStoreOptions);
|
|
78
96
|
/** The panel's directory under the Agent layout root. */
|
|
79
97
|
dirPath(): string;
|
|
80
98
|
private get dir();
|
|
99
|
+
/** The path grammar plus the panel's per-segment extra grammar. */
|
|
81
100
|
private validName;
|
|
82
101
|
/**
|
|
83
102
|
* Resolve the document one entry name addresses. The name a panel entry
|
|
84
|
-
* carries is the one its document declares, which is only the
|
|
85
|
-
* convention, so a name that matches no path is matched against the
|
|
103
|
+
* carries is the one its document declares, which is only the document path
|
|
104
|
+
* by convention, so a name that matches no path is matched against the
|
|
86
105
|
* declared names of the served documents.
|
|
87
106
|
*/
|
|
88
107
|
private document;
|
|
@@ -101,7 +120,7 @@ export declare class UserPanelStore {
|
|
|
101
120
|
* find or fix it.
|
|
102
121
|
*/
|
|
103
122
|
private serialize;
|
|
104
|
-
/** Create an entry; refuses an occupied name. New entries use the flat spelling. */
|
|
123
|
+
/** Create an entry; refuses an occupied name. New entries use the flat `<name>.md` spelling, creating any parent directories. */
|
|
105
124
|
create(name: string, text: string): Promise<UserPanelEntry>;
|
|
106
125
|
/** Replace one entry's content wholesale, keeping the spelling it already has. */
|
|
107
126
|
update(name: string, text: string): Promise<void>;
|
|
@@ -115,11 +134,12 @@ export declare function createUserPanelStores(agentsRoot: string): {
|
|
|
115
134
|
agents: UserPanelStore;
|
|
116
135
|
};
|
|
117
136
|
/**
|
|
118
|
-
* The skills/agents panels accept only harness skill-grammar
|
|
137
|
+
* The skills/agents panels accept only harness skill-grammar path segments
|
|
119
138
|
* (`[a-z0-9-]`, no underscores): a candidate name reaching the skill
|
|
120
139
|
* registry's `get()` with an invalid name is dropped there, and several
|
|
121
|
-
* consumers validate strictly, so `_`-named entries would be dead weight.
|
|
122
|
-
* Commands keep the looser
|
|
140
|
+
* consumers validate strictly, so `_`-named entries would be dead weight. A
|
|
141
|
+
* nested persona applies this to each segment. Commands keep the looser
|
|
142
|
+
* command grammar (`_` allowed).
|
|
123
143
|
*/
|
|
124
144
|
export declare function isUserSkillEntryName(name: string): boolean;
|
|
125
145
|
/**
|
|
@@ -5,15 +5,25 @@
|
|
|
5
5
|
* frontmatter rules the catalog uses, so user entries look exactly like suite
|
|
6
6
|
* entries to the runtime mounts.
|
|
7
7
|
*
|
|
8
|
-
* An entry is one document.
|
|
9
|
-
*
|
|
10
|
-
*
|
|
8
|
+
* An entry is one document. A flat panel reads the immediate `<name>.md`
|
|
9
|
+
* children of its directory; a nested panel (commands and agent personas)
|
|
10
|
+
* reads every `.md` document at any depth and names each by its path relative
|
|
11
|
+
* to that directory. Skills also accept the cross-tool directory spelling
|
|
12
|
+
* (`<name>/SKILL.md`) that other Agent tools and the harness's own reader of
|
|
13
|
+
* `~/.agents/skills` author, and read it from the top level only.
|
|
11
14
|
* @module runtime/user-store
|
|
12
15
|
*/
|
|
13
16
|
/** Where user panel entries persist: `<agentsRoot>/<kind>/`. */
|
|
14
17
|
export declare function userEntryDir(agentsRoot: string, kind: 'skills' | 'commands' | 'agents'): string;
|
|
15
|
-
/** `[a-z][a-z0-9_-]*` —
|
|
18
|
+
/** `[a-z][a-z0-9_-]*` — one segment of a panel entry name. */
|
|
16
19
|
export declare const USER_ENTRY_NAME: RegExp;
|
|
20
|
+
/**
|
|
21
|
+
* The path grammar a nested panel entry name satisfies: one or more
|
|
22
|
+
* {@link USER_ENTRY_NAME} segments joined by `/`. It rejects `..`, leading or
|
|
23
|
+
* trailing separators, empty segments, backslashes, and uppercase, so the name
|
|
24
|
+
* stays a path relative to the panel directory.
|
|
25
|
+
*/
|
|
26
|
+
export declare const USER_ENTRY_PATH: RegExp;
|
|
17
27
|
/** The file name of a directory-shaped skill's document. */
|
|
18
28
|
export declare const SKILL_ENTRY_FILE = "SKILL.md";
|
|
19
29
|
/**
|
|
@@ -42,11 +52,18 @@ export interface EntryDocument {
|
|
|
42
52
|
}
|
|
43
53
|
/**
|
|
44
54
|
* Resolve one entry name to its document, taking the first shape the path
|
|
45
|
-
* exists in.
|
|
55
|
+
* exists in. A nested panel accepts a path name (`git/commit`); a flat panel
|
|
56
|
+
* accepts a single segment. Names outside the panel's grammar never touch the
|
|
57
|
+
* filesystem.
|
|
58
|
+
*/
|
|
59
|
+
export declare function resolveEntryDocument(dir: string, name: string, shapes: readonly EntryShape[], strict?: boolean, nested?: boolean): Promise<EntryDocument | undefined>;
|
|
60
|
+
/**
|
|
61
|
+
* Every entry document the served shapes expose. A flat panel reads immediate
|
|
62
|
+
* children only; a nested panel walks every subdirectory to any depth and
|
|
63
|
+
* names each entry by its path relative to `dir`. Entries are deduplicated by
|
|
64
|
+
* name at the first shape that has it.
|
|
46
65
|
*/
|
|
47
|
-
export declare function
|
|
48
|
-
/** Every entry document the served shapes expose, deduplicated by name at the first shape that has it. */
|
|
49
|
-
export declare function listEntryDocuments(dir: string, strict?: boolean, shapes?: readonly EntryShape[]): Promise<EntryDocument[]>;
|
|
66
|
+
export declare function listEntryDocuments(dir: string, strict?: boolean, shapes?: readonly EntryShape[], nested?: boolean): Promise<EntryDocument[]>;
|
|
50
67
|
/** Parse full YAML metadata without flattening arrays, mappings, or multiline strings. */
|
|
51
68
|
export declare function parseFrontmatterRecord(text: string): Record<string, unknown>;
|
|
52
69
|
/** Read one resolved entry; strict runtime snapshots throw on I/O errors other than a vanished file. */
|
|
@@ -79,7 +96,7 @@ export interface UserEntryFile {
|
|
|
79
96
|
};
|
|
80
97
|
}
|
|
81
98
|
/** List entries across the served shapes; strict runtime snapshots propagate I/O errors instead of publishing partial inventories. */
|
|
82
|
-
export declare function listEntryFiles(dir: string, strict?: boolean, shapes?: readonly EntryShape[]): Promise<UserEntryFile[]>;
|
|
99
|
+
export declare function listEntryFiles(dir: string, strict?: boolean, shapes?: readonly EntryShape[], nested?: boolean): Promise<UserEntryFile[]>;
|
|
83
100
|
/** Create one panel entry's document from its name: `<name>.md`, or `<name>/SKILL.md` in the directory shape. */
|
|
84
101
|
export declare function writeEntryFile(dir: string, name: string, text: string, shape?: EntryShape): Promise<void>;
|
|
85
102
|
/** Replace one resolved entry's document in place, wherever it lives. */
|
|
@@ -93,6 +110,6 @@ export declare function writeEntryDocument(document: EntryDocument, text: string
|
|
|
93
110
|
*/
|
|
94
111
|
export declare function deleteEntryDocument(document: EntryDocument): Promise<void>;
|
|
95
112
|
/** Whether an entry document with that name exists in any served shape. */
|
|
96
|
-
export declare function entryExists(dir: string, name: string, shapes?: readonly EntryShape[]): Promise<boolean>;
|
|
113
|
+
export declare function entryExists(dir: string, name: string, shapes?: readonly EntryShape[], nested?: boolean): Promise<boolean>;
|
|
97
114
|
/** Serialize a frontmatter block from a shallow record (deterministic key order). */
|
|
98
115
|
export declare function serializeFrontmatter(meta: Record<string, unknown>): string;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-agent-plugins-market",
|
|
3
|
-
"description": "
|
|
4
|
-
"version": "0.
|
|
3
|
+
"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.",
|
|
4
|
+
"version": "0.8.1",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
7
7
|
"types": "lib/types/index.d.ts",
|
|
@@ -74,16 +74,17 @@
|
|
|
74
74
|
"ai-agents"
|
|
75
75
|
],
|
|
76
76
|
"peerDependencies": {
|
|
77
|
-
"@deepseek-ai/cordis": "
|
|
78
|
-
"@deepseek-ai/dsh-attachment": "^0.1.
|
|
79
|
-
"@deepseek-ai/dsh-credentials": "^0.1.
|
|
80
|
-
"@deepseek-ai/dsh-hooks-claude-code": "^0.1.
|
|
81
|
-
"@deepseek-ai/dsh-llm": "^0.1.
|
|
82
|
-
"@deepseek-ai/dsh-mcp-client": "^0.1.
|
|
83
|
-
"@deepseek-ai/dsh-skill": "^0.1.
|
|
84
|
-
"@deepseek-ai/dsh-subprocess": "^0.1.
|
|
85
|
-
"@deepseek-ai/dsh-timeout": "^0.1.
|
|
86
|
-
"@deepseek-ai/dsh-tools": "^0.1.
|
|
77
|
+
"@deepseek-ai/cordis": "~4.0.4",
|
|
78
|
+
"@deepseek-ai/dsh-attachment": "^0.1.7-rc.1",
|
|
79
|
+
"@deepseek-ai/dsh-credentials": "^0.1.7-rc.1",
|
|
80
|
+
"@deepseek-ai/dsh-hooks-claude-code": "^0.1.7-rc.1",
|
|
81
|
+
"@deepseek-ai/dsh-llm": "^0.1.7-rc.1",
|
|
82
|
+
"@deepseek-ai/dsh-mcp-client": "^0.1.7-rc.1",
|
|
83
|
+
"@deepseek-ai/dsh-skill": "^0.1.7-rc.1",
|
|
84
|
+
"@deepseek-ai/dsh-subprocess": "^0.1.7-rc.1",
|
|
85
|
+
"@deepseek-ai/dsh-timeout": "^0.1.7-rc.1",
|
|
86
|
+
"@deepseek-ai/dsh-tools": "^0.1.7-rc.1",
|
|
87
|
+
"@deepseek-ai/dsh-util-workspace-path": "^0.1.7-rc.1"
|
|
87
88
|
},
|
|
88
89
|
"peerDependenciesMeta": {
|
|
89
90
|
"@deepseek-ai/dsh-hooks-claude-code": {
|
|
@@ -97,12 +98,12 @@
|
|
|
97
98
|
}
|
|
98
99
|
},
|
|
99
100
|
"dependencies": {
|
|
100
|
-
"@deepseek-ai/dsh-atomic-write": "^0.1.
|
|
101
|
-
"@deepseek-ai/dsh-home-paths": "^0.1.
|
|
102
|
-
"@deepseek-ai/dsh-lsp": "^0.1.
|
|
103
|
-
"@deepseek-ai/dsh-lsp-stdio": "^0.1.
|
|
104
|
-
"@deepseek-ai/dsh-tool-lsp": "^0.1.
|
|
105
|
-
"@deepseek-ai/schemastery": "^3.18.
|
|
101
|
+
"@deepseek-ai/dsh-atomic-write": "^0.1.7-rc.1",
|
|
102
|
+
"@deepseek-ai/dsh-home-paths": "^0.1.7-rc.1",
|
|
103
|
+
"@deepseek-ai/dsh-lsp": "^0.1.7-rc.1",
|
|
104
|
+
"@deepseek-ai/dsh-lsp-stdio": "^0.1.7-rc.1",
|
|
105
|
+
"@deepseek-ai/dsh-tool-lsp": "^0.1.7-rc.1",
|
|
106
|
+
"@deepseek-ai/schemastery": "^3.18.4",
|
|
106
107
|
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
107
108
|
"ajv": "^8.17.1",
|
|
108
109
|
"fflate": "^0.8.3",
|
|
@@ -117,19 +118,23 @@
|
|
|
117
118
|
"@codemirror/language": "^6.12.4",
|
|
118
119
|
"@codemirror/state": "^6.7.5",
|
|
119
120
|
"@codemirror/view": "^6.43.12",
|
|
120
|
-
"@deepseek-ai/cordis": "
|
|
121
|
-
"@deepseek-ai/dsh-attachment": "0.1.
|
|
122
|
-
"@deepseek-ai/dsh-client-store": "0.1.
|
|
123
|
-
"@deepseek-ai/dsh-client-ui-
|
|
124
|
-
"@deepseek-ai/dsh-client-ui-
|
|
125
|
-
"@deepseek-ai/dsh-
|
|
126
|
-
"@deepseek-ai/dsh-
|
|
127
|
-
"@deepseek-ai/dsh-
|
|
128
|
-
"@deepseek-ai/dsh-
|
|
129
|
-
"@deepseek-ai/dsh-
|
|
130
|
-
"@deepseek-ai/dsh-
|
|
131
|
-
"@deepseek-ai/dsh-
|
|
132
|
-
"@deepseek-ai/dsh-
|
|
121
|
+
"@deepseek-ai/cordis": "~4.0.4",
|
|
122
|
+
"@deepseek-ai/dsh-attachment": "0.1.7-rc.1",
|
|
123
|
+
"@deepseek-ai/dsh-client-store": "0.1.7-rc.1",
|
|
124
|
+
"@deepseek-ai/dsh-client-ui-plugin-manager": "0.1.7-rc.1",
|
|
125
|
+
"@deepseek-ai/dsh-client-ui-primitives": "0.1.7-rc.1",
|
|
126
|
+
"@deepseek-ai/dsh-client-ui-settings": "0.1.7-rc.1",
|
|
127
|
+
"@deepseek-ai/dsh-client-ui-slots": "0.1.7-rc.1",
|
|
128
|
+
"@deepseek-ai/dsh-credentials": "0.1.7-rc.1",
|
|
129
|
+
"@deepseek-ai/dsh-hooks-claude-code": "0.1.7-rc.1",
|
|
130
|
+
"@deepseek-ai/dsh-llm": "0.1.7-rc.1",
|
|
131
|
+
"@deepseek-ai/dsh-mcp-client": "0.1.7-rc.1",
|
|
132
|
+
"@deepseek-ai/dsh-skill": "0.1.7-rc.1",
|
|
133
|
+
"@deepseek-ai/dsh-subprocess": "0.1.7-rc.1",
|
|
134
|
+
"@deepseek-ai/dsh-timeout": "0.1.7-rc.1",
|
|
135
|
+
"@deepseek-ai/dsh-tools": "0.1.7-rc.1",
|
|
136
|
+
"@deepseek-ai/dsh-util-workspace-path": "0.1.7-rc.1",
|
|
137
|
+
"@deepseek-ai/cosmokit": "^1.8.5",
|
|
133
138
|
"@eslint/js": "^10.0.1",
|
|
134
139
|
"@shikijs/langs": "^4.4.3",
|
|
135
140
|
"@tsdown/css": "^0.22.14",
|
|
@@ -140,6 +145,7 @@
|
|
|
140
145
|
"anser": "^2.3.5",
|
|
141
146
|
"clsx": "^2.1.1",
|
|
142
147
|
"dependency-cruiser": "^18.4.0",
|
|
148
|
+
"diff": "^9.0.0",
|
|
143
149
|
"eslint": "^10.9.1",
|
|
144
150
|
"immer": "^11.1.18",
|
|
145
151
|
"jsdom": "^30.0.1",
|
|
@@ -159,6 +165,7 @@
|
|
|
159
165
|
"react": "^18.3.1",
|
|
160
166
|
"react-dom": "~18.3.1",
|
|
161
167
|
"shiki": "^4.4.3",
|
|
168
|
+
"simple-icons": "^16.31.0",
|
|
162
169
|
"tsdown": "^0.22.14",
|
|
163
170
|
"typescript": "^5.8.3",
|
|
164
171
|
"typescript-eslint": "^8.67.0",
|
|
@@ -27,7 +27,7 @@ Namespace values are the suite's defaults rather than a ceiling the user cannot
|
|
|
27
27
|
|
|
28
28
|
## User-owned declarations
|
|
29
29
|
|
|
30
|
-
`~/.agents/mcp.json` is local data rather than a distributable package. Keys this client does not know are stored back exactly as written, and the package-only rules — a closed server shape, bare command names, plugin-relative paths — do not apply to it. A suite's packaged `mcp.json` keeps every one of them, because a package carrying fields this client cannot honour is one it cannot promise to mount.
|
|
30
|
+
`~/.agents/mcp.json` is local data rather than a distributable package. Keys this client does not know are stored back exactly as written, and the package-only rules — a closed server shape, bare command names, plugin-relative paths — do not apply to it. A suite's packaged `mcp.json` keeps every one of them, because a package carrying fields this client cannot honour is one it cannot promise to mount. `$schema` is optional here: a file another Agent tool wrote is read as this release's dialect when the key is absent, and a declared version this client does not recognize is rejected.
|
|
31
31
|
|
|
32
32
|
The editor reads the same two seats a suite declares, for one server at a time: the portable definition under `mcpServers` and this client's policy under `com.deepseek.harness`. The form writes only the half it owns, so a field it has no control for — a key another client introduced, a policy entry the form does not show — survives both a form edit and a JSON edit. Only the policy entries the user changed are sent on save; an entry the document drops asks for inheritance.
|
|
33
33
|
|