@daweifu/capability-menu 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +39 -18
- package/README.md +46 -25
- package/cordis.patch.yml +15 -24
- package/lib/client.d.ts +211 -32
- package/lib/client.d.ts.map +1 -1
- package/lib/client.js +1510 -158
- package/lib/constants.js +33 -0
- package/lib/constants.js.map +1 -0
- package/lib/index.js +1 -1
- package/lib/locations.js +541 -0
- package/lib/locations.js.map +1 -0
- package/lib/patch-file.js +192 -0
- package/lib/patch-file.js.map +1 -0
- package/lib/policy.js +211 -27
- package/lib/policy.js.map +1 -1
- package/lib/registry.js +256 -38
- package/lib/registry.js.map +1 -1
- package/lib/search.js +10 -2
- package/lib/search.js.map +1 -1
- package/lib/server/remote.js +137 -4
- package/lib/server/remote.js.map +1 -1
- package/lib/types/constants.d.ts +33 -0
- package/lib/types/constants.d.ts.map +1 -0
- package/lib/types/index.d.ts +1 -1
- package/lib/types/locations.d.ts +142 -0
- package/lib/types/locations.d.ts.map +1 -0
- package/lib/types/patch-file.d.ts +46 -0
- package/lib/types/patch-file.d.ts.map +1 -0
- package/lib/types/policy.d.ts +39 -0
- package/lib/types/policy.d.ts.map +1 -1
- package/lib/types/registry.d.ts +48 -16
- package/lib/types/registry.d.ts.map +1 -1
- package/lib/types/search.d.ts.map +1 -1
- package/lib/types/server/remote.d.ts +47 -2
- package/lib/types/server/remote.d.ts.map +1 -1
- package/package.json +24 -23
package/lib/constants.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Constants shared by the server-side registry and the browser bundle.
|
|
3
|
+
*
|
|
4
|
+
* Kept in a dependency-free module so `src/client` can import them without
|
|
5
|
+
* pulling the registry's `node:fs` / `js-yaml` imports into the web bundle.
|
|
6
|
+
*/
|
|
7
|
+
/** Prefix of every MCP tool's registered name: `mcp__<server>__<raw>`. */
|
|
8
|
+
export const MCP_ID_PREFIX = 'mcp__';
|
|
9
|
+
/**
|
|
10
|
+
* Reserved pseudo-server that groups harness-native (non-MCP) tools in the
|
|
11
|
+
* management surface. Native tools (bash/read/write/…) are cataloged like MCP
|
|
12
|
+
* tools — same `server` dimension — so 能力菜单 can group them, classify them
|
|
13
|
+
* Resident/On-demand/Disabled, and `meta_invoke` can dispatch them.
|
|
14
|
+
*/
|
|
15
|
+
export const BUILT_IN_SERVER = 'built-in';
|
|
16
|
+
/**
|
|
17
|
+
* dsh's source labels for a project's own skill roots — the `project`-prefixed
|
|
18
|
+
* providers of `@deepseek-ai/dsh-skill-filesystem`, which scan
|
|
19
|
+
* `<projectRoot>/.dsh/skills` and `<projectRoot>/.agents/skills`. Every other
|
|
20
|
+
* label (`user-dsh`, `user-agents`, `bundled`, `custom`, `runtime`) is a
|
|
21
|
+
* user-level root. Shared so the server's location manager and the browser's
|
|
22
|
+
* 全局 / 项目 grouping agree on what "project scoped" means.
|
|
23
|
+
*/
|
|
24
|
+
export const PROJECT_SKILL_SOURCES = new Set(['project-dsh', 'project-agents']);
|
|
25
|
+
/**
|
|
26
|
+
* Source labels for user-level skill roots whose entries this plugin can adopt:
|
|
27
|
+
* linking the skill's own directory into the user root (where the entry becomes
|
|
28
|
+
* editable) without touching its content. `user-dsh` is excluded because that
|
|
29
|
+
* root is already managed, and `bundled` because a packaged skill should not be
|
|
30
|
+
* shadowed by a user copy.
|
|
31
|
+
*/
|
|
32
|
+
export const ADOPTABLE_SKILL_SOURCES = new Set(['user-agents', 'custom']);
|
|
33
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,0EAA0E;AAC1E,MAAM,CAAC,MAAM,aAAa,GAAG,OAAO,CAAA;AAEpC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,UAAU,CAAA;AAEzC;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAwB,IAAI,GAAG,CAAC,CAAC,aAAa,EAAE,gBAAgB,CAAC,CAAC,CAAA;AAEpG;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAwB,IAAI,GAAG,CAAC,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC,CAAA"}
|
package/lib/index.js
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* - `policy` (P3): Resident/On-demand/Disabled projection policy + `ctx.capabilityPolicy`.
|
|
12
12
|
* - the package root entry (`name` + `apply` below): mounts the Typert gateway
|
|
13
13
|
* that exposes `ctx.capabilityPolicy` to the browser as the `capabilityPolicy`
|
|
14
|
-
* remote namespace — the data source of the
|
|
14
|
+
* remote namespace — the data source of the 能力菜单 settings tab.
|
|
15
15
|
* - a browser bundle via the `./client` subpath (`src/client`), discovered by
|
|
16
16
|
* `@deepseek-ai/dsh-client-modules` from this package's `dsh.client`
|
|
17
17
|
* declaration and served as `/plugins/<id>/client.js`.
|
package/lib/locations.js
ADDED
|
@@ -0,0 +1,541 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Location registry: the places capabilities come from.
|
|
3
|
+
*
|
|
4
|
+
* Two kinds of location, each following the medium dsh itself uses:
|
|
5
|
+
*
|
|
6
|
+
* - **MCP servers** are declared as `@deepseek-ai/dsh-mcp-client` rows in the
|
|
7
|
+
* patch file. Writing the row is all we do — dsh mounts the server, reconnects
|
|
8
|
+
* and disposes it. That is why this module never imports `dsh-mcp-client`,
|
|
9
|
+
* never mounts a fiber, and never has to arbitrate `serverName` reservations:
|
|
10
|
+
* there is exactly one source of truth (the file) and one owner (dsh).
|
|
11
|
+
* - **Skill directories** are symlinked into `~/.dsh/skills/`, the default user
|
|
12
|
+
* root `skill-filesystem` discovers with no configuration at all. No patch
|
|
13
|
+
* entry, no hot reload.
|
|
14
|
+
*/
|
|
15
|
+
import { access, readdir, lstat, mkdir, readFile, realpath, rm, stat, symlink } from 'node:fs/promises';
|
|
16
|
+
import { homedir } from 'node:os';
|
|
17
|
+
import { basename, dirname, isAbsolute, join, resolve } from 'node:path';
|
|
18
|
+
import yaml from 'js-yaml';
|
|
19
|
+
import { addEntry, defaultPatchFile, mutatePatch, readEntries, removeEntry, setEntryConfig } from "./patch-file.js";
|
|
20
|
+
/** Plugin name of the MCP bridge, as declared in patch rows. */
|
|
21
|
+
export const MCP_CLIENT_PLUGIN = '@deepseek-ai/dsh-mcp-client';
|
|
22
|
+
/** `serverName` must match `[A-Za-z0-9_-]{1,32}` and be unique per scope. */
|
|
23
|
+
const SERVER_NAME_RE = /^[A-Za-z0-9_-]{1,32}$/;
|
|
24
|
+
export function defaultLocationConfig() {
|
|
25
|
+
return {
|
|
26
|
+
patchFile: defaultPatchFile(),
|
|
27
|
+
skillsDir: defaultSkillsDir(),
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/** Default skill root: the user root `skill-filesystem` scans with no config. */
|
|
31
|
+
export function defaultSkillsDir() {
|
|
32
|
+
const home = process.env['DSH_HOME'];
|
|
33
|
+
if (home !== undefined && home.length > 0)
|
|
34
|
+
return join(home, 'skills');
|
|
35
|
+
return join(homedir(), '.dsh', 'skills');
|
|
36
|
+
}
|
|
37
|
+
export class LocationRegistry {
|
|
38
|
+
ctx;
|
|
39
|
+
config;
|
|
40
|
+
constructor(ctx, config) {
|
|
41
|
+
this.ctx = ctx;
|
|
42
|
+
this.config = config;
|
|
43
|
+
}
|
|
44
|
+
// --- MCP servers -------------------------------------------------------
|
|
45
|
+
/** Every MCP server declared in the patch file, in file order. */
|
|
46
|
+
async listMcp() {
|
|
47
|
+
const entries = await readEntries(this.config.patchFile).catch((error) => {
|
|
48
|
+
this.ctx.logger.warn(`capability-locations: cannot read ${this.config.patchFile}: ${String(error)}`);
|
|
49
|
+
return [];
|
|
50
|
+
});
|
|
51
|
+
const rows = [];
|
|
52
|
+
for (const entry of entries) {
|
|
53
|
+
if (entry.name !== MCP_CLIENT_PLUGIN)
|
|
54
|
+
continue;
|
|
55
|
+
const config = entry.config ?? {};
|
|
56
|
+
const serverName = config['serverName'];
|
|
57
|
+
if (typeof serverName !== 'string')
|
|
58
|
+
continue;
|
|
59
|
+
const transport = config['transport'] === 'stdio' ? 'stdio' : 'streamable-http';
|
|
60
|
+
const command = typeof config['command'] === 'string' ? config['command'] : undefined;
|
|
61
|
+
const args = Array.isArray(config['args'])
|
|
62
|
+
? config['args'].filter((arg) => typeof arg === 'string')
|
|
63
|
+
: undefined;
|
|
64
|
+
const url = typeof config['url'] === 'string' ? config['url'] : undefined;
|
|
65
|
+
const cwd = typeof config['cwd'] === 'string' ? config['cwd'] : undefined;
|
|
66
|
+
const env = stringRecord(config['env']);
|
|
67
|
+
const headers = stringRecord(config['headers']);
|
|
68
|
+
const timeout = typeof config['toolCallTimeoutMs'] === 'number' ? config['toolCallTimeoutMs'] : undefined;
|
|
69
|
+
rows.push({
|
|
70
|
+
id: entry.id,
|
|
71
|
+
serverName,
|
|
72
|
+
transport,
|
|
73
|
+
disabled: entry.disabled === true,
|
|
74
|
+
...command !== undefined ? { command } : {},
|
|
75
|
+
...args !== undefined && args.length > 0 ? { args } : {},
|
|
76
|
+
...url !== undefined ? { url } : {},
|
|
77
|
+
...cwd !== undefined ? { cwd } : {},
|
|
78
|
+
...env !== undefined ? { env } : {},
|
|
79
|
+
...headers !== undefined ? { headers } : {},
|
|
80
|
+
...timeout !== undefined ? { toolCallTimeoutMs: timeout } : {},
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
return rows;
|
|
84
|
+
}
|
|
85
|
+
/** Declare a new MCP server row. Throws on invalid or duplicate input. */
|
|
86
|
+
async addMcp(input) {
|
|
87
|
+
const serverName = input.serverName.trim();
|
|
88
|
+
if (!SERVER_NAME_RE.test(serverName)) {
|
|
89
|
+
throw new Error(`serverName 必须匹配 [A-Za-z0-9_-]{1,32}:${serverName}`);
|
|
90
|
+
}
|
|
91
|
+
if (input.transport === 'stdio' && (input.command ?? '').trim().length === 0) {
|
|
92
|
+
throw new Error('stdio 传输必须提供 command');
|
|
93
|
+
}
|
|
94
|
+
if (input.transport === 'streamable-http' && (input.url ?? '').trim().length === 0) {
|
|
95
|
+
throw new Error('streamable-http 传输必须提供 url');
|
|
96
|
+
}
|
|
97
|
+
// Duplicate `serverName` fails at mount time with a reservation error, so
|
|
98
|
+
// reject it here where the user can still fix the form.
|
|
99
|
+
const rows = await this.listMcp();
|
|
100
|
+
if (rows.some(row => row.serverName === serverName)) {
|
|
101
|
+
throw new Error(`serverName 已被占用:${serverName}`);
|
|
102
|
+
}
|
|
103
|
+
const id = `mcp-${serverName}`;
|
|
104
|
+
if (rows.some(row => row.id === id)) {
|
|
105
|
+
throw new Error(`条目 id 已存在:${id}`);
|
|
106
|
+
}
|
|
107
|
+
const written = await mutatePatch(this.config.patchFile, doc => {
|
|
108
|
+
addEntry(doc, { id, name: MCP_CLIENT_PLUGIN, config: mcpConfig(input) });
|
|
109
|
+
return true;
|
|
110
|
+
});
|
|
111
|
+
if (written)
|
|
112
|
+
this.ctx.logger.info(`capability-locations: registered MCP server "${serverName}"`);
|
|
113
|
+
return id;
|
|
114
|
+
}
|
|
115
|
+
/** Remove a declared MCP server. Returns false when the row is absent. */
|
|
116
|
+
async removeMcp(id) {
|
|
117
|
+
const known = await this.hasMcp(id);
|
|
118
|
+
if (!known)
|
|
119
|
+
return false;
|
|
120
|
+
const written = await mutatePatch(this.config.patchFile, doc => removeEntry(doc, id));
|
|
121
|
+
if (written)
|
|
122
|
+
this.ctx.logger.info(`capability-locations: removed MCP row "${id}"`);
|
|
123
|
+
return written;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Replace a declared server's connection config. The row id (and therefore
|
|
127
|
+
* `serverName`, which is baked into every `mcp__<serverName>__<tool>` tool
|
|
128
|
+
* name, session history and permission rule) is never changed here.
|
|
129
|
+
*/
|
|
130
|
+
async updateMcp(id, input) {
|
|
131
|
+
const rows = await this.listMcp();
|
|
132
|
+
const existing = rows.find(row => row.id === id);
|
|
133
|
+
if (existing === undefined)
|
|
134
|
+
return false;
|
|
135
|
+
if (input.transport === 'stdio' && (input.command ?? '').trim().length === 0) {
|
|
136
|
+
throw new Error('stdio 传输必须提供 command');
|
|
137
|
+
}
|
|
138
|
+
if (input.transport === 'streamable-http' && (input.url ?? '').trim().length === 0) {
|
|
139
|
+
throw new Error('streamable-http 传输必须提供 url');
|
|
140
|
+
}
|
|
141
|
+
const written = await mutatePatch(this.config.patchFile, doc => setEntryConfig(doc, id,
|
|
142
|
+
// Keep the existing serverName: it is the row's identity.
|
|
143
|
+
mcpConfig({ ...input, serverName: existing.serverName })));
|
|
144
|
+
if (written)
|
|
145
|
+
this.ctx.logger.info(`capability-locations: updated MCP server "${existing.serverName}"`);
|
|
146
|
+
return written;
|
|
147
|
+
}
|
|
148
|
+
async hasMcp(id) {
|
|
149
|
+
const rows = await this.listMcp();
|
|
150
|
+
return rows.some(row => row.id === id);
|
|
151
|
+
}
|
|
152
|
+
// --- Skill directories -------------------------------------------------
|
|
153
|
+
// --- Skill directories -------------------------------------------------
|
|
154
|
+
//
|
|
155
|
+
// Two root shapes are managed: the default user root (`~/.dsh/skills`, or
|
|
156
|
+
// `$DSH_HOME/skills`) and a project's own `<projectRoot>/.dsh/skills`. dsh also
|
|
157
|
+
// scans `~/.agents/skills` and `<projectRoot>/.agents/skills`; entries there
|
|
158
|
+
// are listed and editable when a project's root produced them, but a
|
|
159
|
+
// registration always writes the `.dsh` root.
|
|
160
|
+
/** Every entry under the default (user) skill root. */
|
|
161
|
+
async listSkills() {
|
|
162
|
+
let names = [];
|
|
163
|
+
try {
|
|
164
|
+
names = await readdir(this.config.skillsDir);
|
|
165
|
+
}
|
|
166
|
+
catch (error) {
|
|
167
|
+
this.ctx.logger.warn(`capability-locations: cannot read ${this.config.skillsDir}: ${String(error)}`);
|
|
168
|
+
return [];
|
|
169
|
+
}
|
|
170
|
+
const rows = [];
|
|
171
|
+
for (const name of names) {
|
|
172
|
+
const row = await describeSkillEntry(this.config.skillsDir, name, 'user');
|
|
173
|
+
if (row !== undefined)
|
|
174
|
+
rows.push(row);
|
|
175
|
+
}
|
|
176
|
+
return rows.sort((a, b) => a.name.localeCompare(b.name));
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Which skills directory an operation targets.
|
|
180
|
+
*
|
|
181
|
+
* `entryDir` comes back from a listing and is taken as given, but validated —
|
|
182
|
+
* a caller must not be able to aim `remove` at an arbitrary tree. Otherwise,
|
|
183
|
+
* `projectPath` is a path *inside* a project and the project root is derived
|
|
184
|
+
* from it exactly the way dsh derives it; with neither, the user root.
|
|
185
|
+
*/
|
|
186
|
+
async resolveSkillsDir(entryDir, projectPath) {
|
|
187
|
+
if (entryDir !== undefined && entryDir.length > 0) {
|
|
188
|
+
const dir = resolve(entryDir);
|
|
189
|
+
if (dir !== resolve(this.config.skillsDir))
|
|
190
|
+
await assertSkillsDir(dir);
|
|
191
|
+
return dir;
|
|
192
|
+
}
|
|
193
|
+
const asked = projectPath?.trim() ?? '';
|
|
194
|
+
if (asked.length === 0)
|
|
195
|
+
return this.config.skillsDir;
|
|
196
|
+
if (!isAbsolute(asked))
|
|
197
|
+
throw new Error('项目路径必须是绝对路径');
|
|
198
|
+
const start = await realpath(asked).catch(() => undefined);
|
|
199
|
+
if (start === undefined)
|
|
200
|
+
throw new Error(`项目路径不存在:${asked}`);
|
|
201
|
+
const projectRoot = await findProjectRoot(start);
|
|
202
|
+
this.ctx.logger.info(`capability-locations: project path "${asked}" resolves to project root "${projectRoot}"`);
|
|
203
|
+
return join(projectRoot, '.dsh/skills');
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Register a skill directory by symlinking it into a managed root — the user
|
|
207
|
+
* root by default, or a project's `.dsh/skills` when `projectPath` is given.
|
|
208
|
+
* Returns the entry path actually written, so the caller can report where the
|
|
209
|
+
* skill landed instead of leaving the operator to guess.
|
|
210
|
+
*/
|
|
211
|
+
async addSkill(dir, projectPath) {
|
|
212
|
+
const skillsDir = await this.resolveSkillsDir(undefined, projectPath);
|
|
213
|
+
if (!isAbsolute(dir))
|
|
214
|
+
throw new Error('skill 目录必须是绝对路径');
|
|
215
|
+
const target = await realpath(dir).catch(() => undefined);
|
|
216
|
+
if (target === undefined)
|
|
217
|
+
throw new Error(`skill 目录不存在:${dir}`);
|
|
218
|
+
const info = await stat(target);
|
|
219
|
+
if (!info.isDirectory())
|
|
220
|
+
throw new Error(`不是目录:${dir}`);
|
|
221
|
+
const manifest = await checkSkillManifest(target);
|
|
222
|
+
if (!manifest.ok)
|
|
223
|
+
throw new Error(manifest.message);
|
|
224
|
+
const name = basename(target);
|
|
225
|
+
if (name.length === 0)
|
|
226
|
+
throw new Error(`无法从路径推导技能名:${dir}`);
|
|
227
|
+
const link = join(skillsDir, name);
|
|
228
|
+
const existing = await lstat(link).catch(() => undefined);
|
|
229
|
+
if (existing !== undefined) {
|
|
230
|
+
throw new Error(skillsDir === this.config.skillsDir
|
|
231
|
+
? `技能「${name}」已存在`
|
|
232
|
+
: `技能「${name}」已存在于该项目的 ${skillsDir}`);
|
|
233
|
+
}
|
|
234
|
+
await mkdir(skillsDir, { recursive: true });
|
|
235
|
+
await symlink(target, link, 'dir');
|
|
236
|
+
this.ctx.logger.info(`capability-locations: linked skill "${name}" → ${target} (root ${skillsDir})`);
|
|
237
|
+
return link;
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Unregister a skill entry. Only removes a symlink or a directory that
|
|
241
|
+
* actually carries a `SKILL.md` — never an arbitrary file.
|
|
242
|
+
*/
|
|
243
|
+
async removeSkill(name, entryDir) {
|
|
244
|
+
if (name.includes('/') || name.includes('..') || name.length === 0) {
|
|
245
|
+
throw new Error(`无效的技能名:${name}`);
|
|
246
|
+
}
|
|
247
|
+
const skillsDir = await this.resolveSkillsDir(entryDir);
|
|
248
|
+
const path = join(skillsDir, name);
|
|
249
|
+
const info = await lstat(path).catch(() => undefined);
|
|
250
|
+
if (info === undefined)
|
|
251
|
+
return false;
|
|
252
|
+
if (info.isSymbolicLink()) {
|
|
253
|
+
await rm(path);
|
|
254
|
+
this.ctx.logger.info(`capability-locations: unlinked skill "${name}" (root ${skillsDir})`);
|
|
255
|
+
return true;
|
|
256
|
+
}
|
|
257
|
+
if (info.isDirectory() && (await readSkillManifest(path)) !== undefined) {
|
|
258
|
+
await rm(path, { recursive: true });
|
|
259
|
+
this.ctx.logger.info(`capability-locations: removed skill directory "${name}" (root ${skillsDir})`);
|
|
260
|
+
return true;
|
|
261
|
+
}
|
|
262
|
+
throw new Error(`「${name}」不是可移除的技能目录`);
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Repoint a registered skill at a different directory: unlink the old entry
|
|
266
|
+
* and link the new one under the same name. The name is the skill's identity
|
|
267
|
+
* in `ctx.skills`, so a rename is a remove + add, not an update.
|
|
268
|
+
*/
|
|
269
|
+
async updateSkill(name, dir, entryDir) {
|
|
270
|
+
const skillsDir = await this.resolveSkillsDir(entryDir);
|
|
271
|
+
const existing = await describeSkillEntry(skillsDir, name, entryDir === undefined ? 'user' : 'project');
|
|
272
|
+
if (existing === undefined)
|
|
273
|
+
return false;
|
|
274
|
+
if (!isAbsolute(dir))
|
|
275
|
+
throw new Error('skill 目录必须是绝对路径');
|
|
276
|
+
const target = await realpath(dir).catch(() => undefined);
|
|
277
|
+
if (target === undefined)
|
|
278
|
+
throw new Error(`skill 目录不存在:${dir}`);
|
|
279
|
+
if (!(await stat(target)).isDirectory())
|
|
280
|
+
throw new Error(`不是目录:${dir}`);
|
|
281
|
+
const manifest = await checkSkillManifest(target);
|
|
282
|
+
if (!manifest.ok)
|
|
283
|
+
throw new Error(manifest.message);
|
|
284
|
+
// Resolve the current target so re-submitting the same path is a no-op
|
|
285
|
+
// rather than an unlink/relink that briefly removes the skill.
|
|
286
|
+
const current = await realpath(existing.path).catch(() => undefined);
|
|
287
|
+
if (current === target)
|
|
288
|
+
return false;
|
|
289
|
+
await this.removeSkill(name, entryDir);
|
|
290
|
+
await symlink(target, join(skillsDir, name), 'dir');
|
|
291
|
+
this.ctx.logger.info(`capability-locations: repointed skill "${name}" → ${target} (root ${skillsDir})`);
|
|
292
|
+
return true;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Describe `<entryDir>/<name>` as a skill entry, or `undefined` when nothing
|
|
297
|
+
* there looks like one. Used both for listing the user root and for describing
|
|
298
|
+
* project entries that dsh discovered on its own.
|
|
299
|
+
*/
|
|
300
|
+
export async function describeSkillEntry(entryDir, name, root) {
|
|
301
|
+
if (name.length === 0 || name.includes('/') || name.includes('..'))
|
|
302
|
+
return undefined;
|
|
303
|
+
const path = join(entryDir, name);
|
|
304
|
+
const info = await lstat(path).catch(() => undefined);
|
|
305
|
+
if (info === undefined)
|
|
306
|
+
return undefined;
|
|
307
|
+
// A skill entry is either a directory or a link to one.
|
|
308
|
+
if (!(info.isDirectory() || info.isSymbolicLink()))
|
|
309
|
+
return undefined;
|
|
310
|
+
const target = await realpath(path).catch(() => undefined);
|
|
311
|
+
if (target === undefined)
|
|
312
|
+
return undefined;
|
|
313
|
+
if ((await stat(target).catch(() => undefined))?.isDirectory() !== true)
|
|
314
|
+
return undefined;
|
|
315
|
+
const manifest = await checkSkillManifest(target);
|
|
316
|
+
return {
|
|
317
|
+
name,
|
|
318
|
+
...manifest.ok ? { skillName: manifest.name } : {},
|
|
319
|
+
path,
|
|
320
|
+
linked: info.isSymbolicLink(),
|
|
321
|
+
valid: manifest.ok,
|
|
322
|
+
root,
|
|
323
|
+
entryDir,
|
|
324
|
+
target,
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
/** True when `dir` has the shape of a project skills root. */
|
|
328
|
+
export function isProjectSkillsDir(dir) {
|
|
329
|
+
const owner = basename(dirname(dir));
|
|
330
|
+
return basename(dir) === 'skills' && (owner === '.dsh' || owner === '.agents');
|
|
331
|
+
}
|
|
332
|
+
/** True when `path` exists, of any type. */
|
|
333
|
+
async function pathExists(path) {
|
|
334
|
+
return await access(path).then(() => true, () => false);
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* The project root dsh derives from a working directory: the nearest ancestor
|
|
338
|
+
* carrying `.git`, falling back to the starting directory when there is none.
|
|
339
|
+
*
|
|
340
|
+
* Mirrors `findProjectRoot` in `@deepseek-ai/dsh-skill-filesystem`, which looks
|
|
341
|
+
* for project skills under `<projectRoot>/.dsh/skills` and
|
|
342
|
+
* `<projectRoot>/.agents/skills`. A directory placed anywhere else is never
|
|
343
|
+
* scanned, so this walk has to agree with dsh's exactly — otherwise we would
|
|
344
|
+
* write entries that nothing ever loads, which is the silent failure this whole
|
|
345
|
+
* code path exists to avoid.
|
|
346
|
+
*/
|
|
347
|
+
async function findProjectRoot(start) {
|
|
348
|
+
let current = start;
|
|
349
|
+
for (;;) {
|
|
350
|
+
if (await pathExists(join(current, '.git')))
|
|
351
|
+
return current;
|
|
352
|
+
const parent = dirname(current);
|
|
353
|
+
if (parent === current)
|
|
354
|
+
return start;
|
|
355
|
+
current = parent;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* Guard for a skills directory a caller handed back to us. It must be a
|
|
360
|
+
* canonical `<projectRoot>/.dsh/skills` (or `.agents/skills`) whose project root
|
|
361
|
+
* carries `.git` — precisely the condition under which dsh scans it — so
|
|
362
|
+
* update/remove can never be aimed at a tree dsh does not read.
|
|
363
|
+
*/
|
|
364
|
+
async function assertSkillsDir(dir) {
|
|
365
|
+
if (!isProjectSkillsDir(dir)) {
|
|
366
|
+
throw new Error(`不是可管理的技能目录(应为 <项目>/.dsh/skills 或 <项目>/.agents/skills):${dir}`);
|
|
367
|
+
}
|
|
368
|
+
const projectRoot = dirname(dirname(dir));
|
|
369
|
+
if (!(await pathExists(join(projectRoot, '.git')))) {
|
|
370
|
+
throw new Error(`项目根下没有 .git,dsh 不会扫描该目录:${projectRoot}`);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
/** Build the `config:` block of a `dsh-mcp-client` row. */
|
|
374
|
+
function mcpConfig(input) {
|
|
375
|
+
const config = {
|
|
376
|
+
serverName: input.serverName.trim(),
|
|
377
|
+
transport: input.transport,
|
|
378
|
+
};
|
|
379
|
+
if (input.transport === 'stdio') {
|
|
380
|
+
config['command'] = (input.command ?? '').trim();
|
|
381
|
+
if (input.args !== undefined && input.args.length > 0)
|
|
382
|
+
config['args'] = [...input.args];
|
|
383
|
+
if (input.env !== undefined && Object.keys(input.env).length > 0)
|
|
384
|
+
config['env'] = { ...input.env };
|
|
385
|
+
if (input.cwd !== undefined && input.cwd.trim().length > 0)
|
|
386
|
+
config['cwd'] = input.cwd.trim();
|
|
387
|
+
}
|
|
388
|
+
else {
|
|
389
|
+
config['url'] = (input.url ?? '').trim();
|
|
390
|
+
if (input.headers !== undefined && Object.keys(input.headers).length > 0)
|
|
391
|
+
config['headers'] = { ...input.headers };
|
|
392
|
+
}
|
|
393
|
+
// Only write a timeout when explicitly set, so an unset field keeps falling
|
|
394
|
+
// back to the `dsh-mcp-client` default instead of pinning today's value.
|
|
395
|
+
if (input.toolCallTimeoutMs !== undefined && Number.isFinite(input.toolCallTimeoutMs)) {
|
|
396
|
+
config['toolCallTimeoutMs'] = input.toolCallTimeoutMs;
|
|
397
|
+
}
|
|
398
|
+
return config;
|
|
399
|
+
}
|
|
400
|
+
/** Narrow an unknown config value to a string→string map, or undefined. */
|
|
401
|
+
function stringRecord(value) {
|
|
402
|
+
if (value === null || typeof value !== 'object' || Array.isArray(value))
|
|
403
|
+
return undefined;
|
|
404
|
+
const out = {};
|
|
405
|
+
for (const [key, item] of Object.entries(value)) {
|
|
406
|
+
if (typeof item === 'string')
|
|
407
|
+
out[key] = item;
|
|
408
|
+
}
|
|
409
|
+
return Object.keys(out).length > 0 ? out : undefined;
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Skill-name grammar enforced by `@deepseek-ai/dsh-skill` (`isSkillName`):
|
|
413
|
+
* lowercase alphanumerics in kebab-case.
|
|
414
|
+
*/
|
|
415
|
+
const SKILL_NAME_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
416
|
+
/**
|
|
417
|
+
* Invocation keys the loader reads, and the legacy spellings it rejects. Both
|
|
418
|
+
* are optional; a legacy key or a value that cannot be read as a boolean makes
|
|
419
|
+
* `parseInvocationPolicy` throw, which drops the whole skill.
|
|
420
|
+
*/
|
|
421
|
+
const INVOCATION_KEYS = ['disable-model-invocation', 'user-invocable'];
|
|
422
|
+
const LEGACY_INVOCATION_KEYS = [
|
|
423
|
+
['disableModelInvocation', 'disable-model-invocation'],
|
|
424
|
+
['modelInvocable', 'disable-model-invocation'],
|
|
425
|
+
['userInvocable', 'user-invocable'],
|
|
426
|
+
];
|
|
427
|
+
/** Read `dir/SKILL.md`, or `undefined` when it is missing or unreadable. */
|
|
428
|
+
async function readSkillManifest(dir) {
|
|
429
|
+
return await readFile(join(dir, 'SKILL.md'), 'utf8').catch(() => undefined);
|
|
430
|
+
}
|
|
431
|
+
/** The failing side of {@link SkillManifestCheck}. */
|
|
432
|
+
function manifestProblem(message) {
|
|
433
|
+
return { ok: false, message };
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* Validate the manifest in `dir` the way `@deepseek-ai/dsh-skill-filesystem`
|
|
437
|
+
* will when it loads the skill root.
|
|
438
|
+
*
|
|
439
|
+
* The loader needs YAML frontmatter that parses to a mapping carrying a
|
|
440
|
+
* kebab-case `name` and a `description`, and an invocation policy it can read
|
|
441
|
+
* (`parseSkillFile` in that package); for anything else it logs a warning and
|
|
442
|
+
* *silently skips* the skill. A directory that fails those checks would
|
|
443
|
+
* therefore register successfully here and then never appear in a session, so
|
|
444
|
+
* we run the same checks and reject loudly.
|
|
445
|
+
*/
|
|
446
|
+
async function checkSkillManifest(dir) {
|
|
447
|
+
const raw = await readSkillManifest(dir);
|
|
448
|
+
if (raw === undefined)
|
|
449
|
+
return manifestProblem(`目录中没有 SKILL.md:${dir}`);
|
|
450
|
+
const front = parseFrontmatter(raw);
|
|
451
|
+
if (front === 'no-frontmatter') {
|
|
452
|
+
return manifestProblem(`SKILL.md 缺少 YAML frontmatter(首行需为 --- 并以 --- 闭合):${dir}`);
|
|
453
|
+
}
|
|
454
|
+
if (front === 'bad-yaml') {
|
|
455
|
+
return manifestProblem(`SKILL.md 的 frontmatter 不是合法的 YAML 对象:${dir}`);
|
|
456
|
+
}
|
|
457
|
+
const { name, description } = front;
|
|
458
|
+
if (typeof name !== 'string' || typeof description !== 'string') {
|
|
459
|
+
return manifestProblem(`SKILL.md 的 frontmatter 需要字符串 name 和 description:${dir}`);
|
|
460
|
+
}
|
|
461
|
+
if (!SKILL_NAME_RE.test(name)) {
|
|
462
|
+
return manifestProblem(`SKILL.md 的 name「${name}」不是合法技能名(仅小写字母、数字与连字符,如 my-skill):${dir}`);
|
|
463
|
+
}
|
|
464
|
+
const problem = checkInvocation(front, dir);
|
|
465
|
+
if (problem !== undefined)
|
|
466
|
+
return manifestProblem(problem);
|
|
467
|
+
return { ok: true, name };
|
|
468
|
+
}
|
|
469
|
+
/**
|
|
470
|
+
* Validate the invocation fields. A skill without them is fine — the loader
|
|
471
|
+
* defaults to model- and user-invocable — but one it cannot parse is dropped,
|
|
472
|
+
* so a legacy spelling or a non-boolean value is rejected here with the
|
|
473
|
+
* canonical replacement named. Returns the problem, or undefined when the
|
|
474
|
+
* fields are all readable.
|
|
475
|
+
*/
|
|
476
|
+
function checkInvocation(front, dir) {
|
|
477
|
+
for (const [legacy, canonical] of LEGACY_INVOCATION_KEYS) {
|
|
478
|
+
if (Object.hasOwn(front, legacy)) {
|
|
479
|
+
return `SKILL.md 的 frontmatter 字段「${legacy}」已废弃,请改用「${canonical}」:${dir}`;
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
for (const key of INVOCATION_KEYS) {
|
|
483
|
+
if (Object.hasOwn(front, key) && !isFrontmatterBoolean(front[key])) {
|
|
484
|
+
return `SKILL.md 的 frontmatter 字段「${key}」必须是布尔值:${dir}`;
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
return undefined;
|
|
488
|
+
}
|
|
489
|
+
/**
|
|
490
|
+
* Whether the loader would read `value` as a boolean: a boolean, the numbers
|
|
491
|
+
* 1/0, or an on/off word in any case. Mirrors `frontmatterBoolean` in
|
|
492
|
+
* `@deepseek-ai/dsh-skill-filesystem`, so a manifest it accepts is not
|
|
493
|
+
* rejected here.
|
|
494
|
+
*/
|
|
495
|
+
function isFrontmatterBoolean(value) {
|
|
496
|
+
if (typeof value === 'boolean')
|
|
497
|
+
return true;
|
|
498
|
+
if (value === 1 || value === 0 || value === '1' || value === '0')
|
|
499
|
+
return true;
|
|
500
|
+
if (typeof value !== 'string')
|
|
501
|
+
return false;
|
|
502
|
+
return ['true', 'false', 'yes', 'no', 'on', 'off'].includes(value.toLowerCase());
|
|
503
|
+
}
|
|
504
|
+
/**
|
|
505
|
+
* Split the `---`-delimited YAML frontmatter off a markdown document, mirroring
|
|
506
|
+
* the loader's parser: the opening `---` must be the first line and a closing
|
|
507
|
+
* `---` must exist on a line of its own.
|
|
508
|
+
*/
|
|
509
|
+
function parseFrontmatter(raw) {
|
|
510
|
+
const firstLineEnd = raw.indexOf('\n');
|
|
511
|
+
if (firstLineEnd < 0)
|
|
512
|
+
return 'no-frontmatter';
|
|
513
|
+
if (raw.slice(0, firstLineEnd).replace(/\r$/, '') !== '---')
|
|
514
|
+
return 'no-frontmatter';
|
|
515
|
+
let closing = -1;
|
|
516
|
+
let lineStart = firstLineEnd + 1;
|
|
517
|
+
while (lineStart <= raw.length) {
|
|
518
|
+
const nextNewline = raw.indexOf('\n', lineStart);
|
|
519
|
+
const lineEnd = nextNewline < 0 ? raw.length : nextNewline;
|
|
520
|
+
if (raw.slice(lineStart, lineEnd).replace(/\r$/, '') === '---') {
|
|
521
|
+
closing = lineStart;
|
|
522
|
+
break;
|
|
523
|
+
}
|
|
524
|
+
if (nextNewline < 0)
|
|
525
|
+
break;
|
|
526
|
+
lineStart = nextNewline + 1;
|
|
527
|
+
}
|
|
528
|
+
if (closing < 0)
|
|
529
|
+
return 'no-frontmatter';
|
|
530
|
+
let parsed;
|
|
531
|
+
try {
|
|
532
|
+
parsed = yaml.load(raw.slice(firstLineEnd + 1, closing));
|
|
533
|
+
}
|
|
534
|
+
catch {
|
|
535
|
+
return 'bad-yaml';
|
|
536
|
+
}
|
|
537
|
+
if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed))
|
|
538
|
+
return 'bad-yaml';
|
|
539
|
+
return parsed;
|
|
540
|
+
}
|
|
541
|
+
//# sourceMappingURL=locations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"locations.js","sourceRoot":"","sources":["../src/locations.ts"],"names":[],"mappings":"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"}
|