@morehao/dsh-skills-console 0.0.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,8 @@
1
+ # dsh-skills-console bundle patch
2
+ #
3
+ # 一个 Host half(lib/index.js)加一个 Web Client half(client.js):
4
+ # Host 负责 canonical 扫描 / 软链 / CLI 调用 / 订阅与更新事务,Client 在设置页渲染「技能」分区。
5
+ - insert:
6
+ - id: dsh-skills-console
7
+ name: '@morehao/dsh-skills-console'
8
+ config: {}
package/icon.svg ADDED
@@ -0,0 +1,15 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64" role="img" aria-label="Skills Manager">
2
+ <defs>
3
+ <linearGradient id="dshsc-icon-bg" x1="6" y1="2" x2="58" y2="62" gradientUnits="userSpaceOnUse">
4
+ <stop stop-color="#3b82f6"/>
5
+ <stop offset="1" stop-color="#1d4ed8"/>
6
+ </linearGradient>
7
+ </defs>
8
+ <rect x="3" y="3" width="58" height="58" rx="14" fill="url(#dshsc-icon-bg)"/>
9
+ <path d="M32 32 18 17M32 32 46 17M32 32 32 49" stroke="#ffffff" stroke-opacity=".55" stroke-width="2.6" stroke-linecap="round"/>
10
+ <circle cx="18" cy="17" r="4.6" fill="#7ef0c0"/>
11
+ <circle cx="46" cy="17" r="4.6" fill="#ffffff"/>
12
+ <circle cx="32" cy="49" r="4.6" fill="#ffffff"/>
13
+ <rect x="21" y="21" width="22" height="22" rx="7" fill="#ffffff"/>
14
+ <path d="M27 32.5l3.6 3.6 6.8-7.4" fill="none" stroke="#1d4ed8" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
15
+ </svg>
@@ -0,0 +1,331 @@
1
+ {
2
+ "source": "skills CLI agents table",
3
+ "entries": [
4
+ {
5
+ "key": "adal",
6
+ "name": "AdaL",
7
+ "dir": ".adal/skills"
8
+ },
9
+ {
10
+ "key": "aider-desk",
11
+ "name": "AiderDesk",
12
+ "dir": ".aider-desk/skills"
13
+ },
14
+ {
15
+ "key": "amp",
16
+ "name": "Amp",
17
+ "dir": "agents/skills",
18
+ "base": "config"
19
+ },
20
+ {
21
+ "key": "antigravity",
22
+ "name": "Antigravity",
23
+ "dir": ".gemini/antigravity/skills"
24
+ },
25
+ {
26
+ "key": "antigravity-cli",
27
+ "name": "Antigravity CLI",
28
+ "dir": ".gemini/antigravity-cli/skills"
29
+ },
30
+ {
31
+ "key": "astrbot",
32
+ "name": "AstrBot",
33
+ "dir": ".astrbot/data/skills"
34
+ },
35
+ {
36
+ "key": "augment",
37
+ "name": "Augment",
38
+ "dir": ".augment/skills"
39
+ },
40
+ {
41
+ "key": "autohand-code",
42
+ "name": "Autohand Code CLI",
43
+ "dir": ".autohand/skills"
44
+ },
45
+ {
46
+ "key": "bob",
47
+ "name": "IBM Bob",
48
+ "dir": ".bob/skills"
49
+ },
50
+ {
51
+ "key": "claude-code",
52
+ "name": "Claude Code",
53
+ "dir": ".claude/skills"
54
+ },
55
+ {
56
+ "key": "codearts-agent",
57
+ "name": "CodeArts Agent",
58
+ "dir": ".codeartsdoer/skills"
59
+ },
60
+ {
61
+ "key": "codebuddy",
62
+ "name": "CodeBuddy",
63
+ "dir": ".codebuddy/skills"
64
+ },
65
+ {
66
+ "key": "codemaker",
67
+ "name": "Codemaker",
68
+ "dir": ".codemaker/skills"
69
+ },
70
+ {
71
+ "key": "codestudio",
72
+ "name": "Code Studio",
73
+ "dir": ".codestudio/skills"
74
+ },
75
+ {
76
+ "key": "command-code",
77
+ "name": "Command Code",
78
+ "dir": ".commandcode/skills"
79
+ },
80
+ {
81
+ "key": "continue",
82
+ "name": "Continue",
83
+ "dir": ".continue/skills"
84
+ },
85
+ {
86
+ "key": "cortex",
87
+ "name": "Cortex Code",
88
+ "dir": ".snowflake/cortex/skills"
89
+ },
90
+ {
91
+ "key": "crush",
92
+ "name": "Crush",
93
+ "dir": "crush/skills",
94
+ "base": "config"
95
+ },
96
+ {
97
+ "key": "cursor",
98
+ "name": "Cursor",
99
+ "dir": ".cursor/skills"
100
+ },
101
+ {
102
+ "key": "deepagents",
103
+ "name": "Deep Agents",
104
+ "dir": ".deepagents/agent/skills"
105
+ },
106
+ {
107
+ "key": "devin",
108
+ "name": "Devin for Terminal",
109
+ "dir": "devin/skills",
110
+ "base": "config"
111
+ },
112
+ {
113
+ "key": "droid",
114
+ "name": "Droid",
115
+ "dir": ".factory/skills"
116
+ },
117
+ {
118
+ "key": "firebender",
119
+ "name": "Firebender",
120
+ "dir": ".firebender/skills"
121
+ },
122
+ {
123
+ "key": "forgecode",
124
+ "name": "ForgeCode",
125
+ "dir": ".forge/skills"
126
+ },
127
+ {
128
+ "key": "gemini-cli",
129
+ "name": "Gemini CLI",
130
+ "dir": ".gemini/skills"
131
+ },
132
+ {
133
+ "key": "github-copilot",
134
+ "name": "GitHub Copilot",
135
+ "dir": ".copilot/skills"
136
+ },
137
+ {
138
+ "key": "goose",
139
+ "name": "Goose",
140
+ "dir": "goose/skills",
141
+ "base": "config"
142
+ },
143
+ {
144
+ "key": "grok",
145
+ "name": "Grok Build",
146
+ "dir": ".grok/skills"
147
+ },
148
+ {
149
+ "key": "hermes-agent",
150
+ "name": "Hermes Agent",
151
+ "dir": ".hermes/skills"
152
+ },
153
+ {
154
+ "key": "iflow-cli",
155
+ "name": "iFlow CLI",
156
+ "dir": ".iflow/skills"
157
+ },
158
+ {
159
+ "key": "inference-sh",
160
+ "name": "inference.sh",
161
+ "dir": ".inferencesh/skills"
162
+ },
163
+ {
164
+ "key": "jazz",
165
+ "name": "Jazz",
166
+ "dir": ".jazz/skills"
167
+ },
168
+ {
169
+ "key": "junie",
170
+ "name": "Junie",
171
+ "dir": ".junie/skills"
172
+ },
173
+ {
174
+ "key": "kilo",
175
+ "name": "Kilo Code",
176
+ "dir": ".kilo/skills"
177
+ },
178
+ {
179
+ "key": "kimchi",
180
+ "name": "Kimchi",
181
+ "dir": "kimchi/harness/skills",
182
+ "base": "config"
183
+ },
184
+ {
185
+ "key": "kiro-cli",
186
+ "name": "Kiro CLI",
187
+ "dir": ".kiro/skills"
188
+ },
189
+ {
190
+ "key": "kode",
191
+ "name": "Kode",
192
+ "dir": ".kode/skills"
193
+ },
194
+ {
195
+ "key": "lingma",
196
+ "name": "Lingma",
197
+ "dir": ".lingma/skills"
198
+ },
199
+ {
200
+ "key": "mcpjam",
201
+ "name": "MCPJam",
202
+ "dir": ".mcpjam/skills"
203
+ },
204
+ {
205
+ "key": "minimax-code",
206
+ "name": "MiniMax Code",
207
+ "dir": ".minimax/skills"
208
+ },
209
+ {
210
+ "key": "mistral-vibe",
211
+ "name": "Mistral Vibe",
212
+ "dir": ".vibe/skills"
213
+ },
214
+ {
215
+ "key": "moxby",
216
+ "name": "Moxby",
217
+ "dir": ".moxby/skills"
218
+ },
219
+ {
220
+ "key": "mux",
221
+ "name": "Mux",
222
+ "dir": ".mux/skills"
223
+ },
224
+ {
225
+ "key": "neovate",
226
+ "name": "Neovate",
227
+ "dir": ".neovate/skills"
228
+ },
229
+ {
230
+ "key": "ona",
231
+ "name": "Ona",
232
+ "dir": ".ona/skills"
233
+ },
234
+ {
235
+ "key": "openclaw",
236
+ "name": "OpenClaw",
237
+ "dir": ".openclaw/skills"
238
+ },
239
+ {
240
+ "key": "opencode",
241
+ "name": "OpenCode",
242
+ "dir": "opencode/skills",
243
+ "base": "config"
244
+ },
245
+ {
246
+ "key": "openhands",
247
+ "name": "OpenHands",
248
+ "dir": ".openhands/skills"
249
+ },
250
+ {
251
+ "key": "pochi",
252
+ "name": "Pochi",
253
+ "dir": ".pochi/skills"
254
+ },
255
+ {
256
+ "key": "posit-assistant",
257
+ "name": "Posit Assistant",
258
+ "dir": ".posit/assistant/skills"
259
+ },
260
+ {
261
+ "key": "qoder",
262
+ "name": "Qoder",
263
+ "dir": ".qoder/skills"
264
+ },
265
+ {
266
+ "key": "qoder-cn",
267
+ "name": "Qoder CN",
268
+ "dir": ".qoder-cn/skills"
269
+ },
270
+ {
271
+ "key": "qwen-code",
272
+ "name": "Qwen Code",
273
+ "dir": ".qwen/skills"
274
+ },
275
+ {
276
+ "key": "reasonix",
277
+ "name": "Reasonix",
278
+ "dir": ".reasonix/skills"
279
+ },
280
+ {
281
+ "key": "roo",
282
+ "name": "Roo Code",
283
+ "dir": ".roo/skills"
284
+ },
285
+ {
286
+ "key": "rovodev",
287
+ "name": "Rovo Dev",
288
+ "dir": ".rovodev/skills"
289
+ },
290
+ {
291
+ "key": "tabnine-cli",
292
+ "name": "Tabnine CLI",
293
+ "dir": ".tabnine/agent/skills"
294
+ },
295
+ {
296
+ "key": "terramind",
297
+ "name": "Terramind",
298
+ "dir": ".terramind/skills"
299
+ },
300
+ {
301
+ "key": "tinycloud",
302
+ "name": "Tinycloud",
303
+ "dir": ".tinycloud/skills"
304
+ },
305
+ {
306
+ "key": "trae",
307
+ "name": "Trae",
308
+ "dir": ".trae/skills"
309
+ },
310
+ {
311
+ "key": "trae-cn",
312
+ "name": "Trae CN",
313
+ "dir": ".trae-cn/skills"
314
+ },
315
+ {
316
+ "key": "windsurf",
317
+ "name": "Windsurf",
318
+ "dir": ".codeium/windsurf/skills"
319
+ },
320
+ {
321
+ "key": "zcode",
322
+ "name": "ZCode",
323
+ "dir": ".zcode/skills"
324
+ },
325
+ {
326
+ "key": "zencoder",
327
+ "name": "Zencoder",
328
+ "dir": ".zencoder/skills"
329
+ }
330
+ ]
331
+ }
@@ -0,0 +1,124 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { projectSkillsDir } from './paths.js';
5
+
6
+ const here = path.dirname(fileURLToPath(import.meta.url));
7
+ const table = JSON.parse(fs.readFileSync(path.join(here, '..', 'agent-table.json'), 'utf8'));
8
+
9
+ /** CLI agent 表里拥有独立目录的条目(`.agents/skills` 型的 universal 条目已排除,见 F23)。 */
10
+ export const CLI_AGENT_DIRS = table.entries;
11
+
12
+ export class UnknownTargetError extends Error {
13
+ constructor(target) {
14
+ super(`unknown target: ${target}`);
15
+ this.code = 'error.skills.unknown-target';
16
+ this.target = target;
17
+ }
18
+ }
19
+
20
+ /**
21
+ * 目标注册表:`dsh-global` / `dsh-project:<abs>` / `agent:<key>` / `custom:<id>`。
22
+ * 发现只做 `lstat` 探测根目录是否存在,不递归;不接受调用方传路径(防穿越)。
23
+ */
24
+ export function createRegistry({ paths, getState, existsSync = fs.existsSync }) {
25
+ function customEntries() {
26
+ const state = typeof getState === 'function' ? getState() : getState;
27
+ return (state?.agents?.custom || []).filter((item) => item && item.id && item.dir);
28
+ }
29
+
30
+ function builtinEntries() {
31
+ return [
32
+ {
33
+ target: 'dsh-global',
34
+ kind: 'dsh',
35
+ key: 'dsh-global',
36
+ label: 'dsh(全局)',
37
+ dir: paths.dshGlobalSkills,
38
+ required: true,
39
+ note: '原生 user-dsh 根(rank 400),装完必建',
40
+ },
41
+ ...CLI_AGENT_DIRS.map((entry) => ({
42
+ target: `agent:${entry.key}`,
43
+ kind: 'agent',
44
+ key: entry.key,
45
+ label: entry.name,
46
+ dir: path.join(entry.base === 'config' ? paths.configHome : paths.home, entry.dir),
47
+ required: false,
48
+ })),
49
+ ...customEntries().map((entry) => ({
50
+ target: `custom:${entry.id}`,
51
+ kind: 'custom',
52
+ key: entry.id,
53
+ label: entry.label || entry.id,
54
+ dir: entry.dir,
55
+ required: false,
56
+ })),
57
+ ];
58
+ }
59
+
60
+ function projectEntry(projectRoot) {
61
+ return {
62
+ target: `project:${projectRoot}`,
63
+ kind: 'project',
64
+ key: projectRoot,
65
+ label: path.basename(projectRoot) || projectRoot,
66
+ dir: projectSkillsDir(projectRoot),
67
+ required: false,
68
+ };
69
+ }
70
+
71
+ return {
72
+ /** 全量注册表(含不存在的条目,供 UI 展示「可接入」)。 */
73
+ all() {
74
+ const seen = new Set();
75
+ return builtinEntries()
76
+ .filter((entry) => {
77
+ // 去重:多个 agent 可能指向同一目录(如 `.agents/skills` 已排除,这里再兜一层)
78
+ const key = `${entry.dir}`;
79
+ if (seen.has(key)) return false;
80
+ seen.add(key);
81
+ return true;
82
+ })
83
+ .map((entry) => ({ ...entry, exists: existsSync(entry.dir) }));
84
+ },
85
+
86
+ /** 已探测到的目录(存在即为"这个 agent 装了")。 */
87
+ detected() {
88
+ return this.all().filter((entry) => entry.exists);
89
+ },
90
+
91
+ project(projectRoot) {
92
+ const entry = projectEntry(projectRoot);
93
+ return { ...entry, exists: existsSync(entry.dir) };
94
+ },
95
+
96
+ resolve(target) {
97
+ if (!target || typeof target !== 'string') throw new UnknownTargetError(target);
98
+ if (target === 'dsh-global') return withExists(this.all().find((e) => e.target === 'dsh-global'));
99
+ if (target.startsWith('agent:')) {
100
+ const key = target.slice('agent:'.length);
101
+ const found = this.all().find((e) => e.target === `agent:${key}`);
102
+ if (!found) throw new UnknownTargetError(target);
103
+ return found;
104
+ }
105
+ if (target.startsWith('custom:')) {
106
+ const id = target.slice('custom:'.length);
107
+ const found = this.all().find((e) => e.target === `custom:${id}`);
108
+ if (!found) throw new UnknownTargetError(target);
109
+ return found;
110
+ }
111
+ if (target.startsWith('project:')) {
112
+ const root = target.slice('project:'.length);
113
+ if (!path.isAbsolute(root)) throw new UnknownTargetError(target);
114
+ return this.project(root);
115
+ }
116
+ throw new UnknownTargetError(target);
117
+ },
118
+ };
119
+
120
+ function withExists(entry) {
121
+ if (!entry) throw new UnknownTargetError('dsh-global');
122
+ return { ...entry, exists: existsSync(entry.dir) };
123
+ }
124
+ }