@skillsmith/cli 0.5.12 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/README.md +92 -2
- package/dist/.tsbuildinfo +1 -1
- package/dist/src/commands/audit-collisions.d.ts +71 -0
- package/dist/src/commands/audit-collisions.d.ts.map +1 -0
- package/dist/src/commands/audit-collisions.js +300 -0
- package/dist/src/commands/audit-collisions.js.map +1 -0
- package/dist/src/commands/audit.d.ts +27 -2
- package/dist/src/commands/audit.d.ts.map +1 -1
- package/dist/src/commands/audit.js +70 -10
- package/dist/src/commands/audit.js.map +1 -1
- package/dist/src/commands/audit.test.js +2 -2
- package/dist/src/commands/audit.test.js.map +1 -1
- package/dist/src/commands/config.d.ts +55 -0
- package/dist/src/commands/config.d.ts.map +1 -0
- package/dist/src/commands/config.js +211 -0
- package/dist/src/commands/config.js.map +1 -0
- package/dist/src/commands/create.d.ts +3 -3
- package/dist/src/commands/create.d.ts.map +1 -1
- package/dist/src/commands/create.js +11 -9
- package/dist/src/commands/create.js.map +1 -1
- package/dist/src/commands/diff.js +2 -2
- package/dist/src/commands/diff.js.map +1 -1
- package/dist/src/commands/import-local.d.ts +21 -0
- package/dist/src/commands/import-local.d.ts.map +1 -0
- package/dist/src/commands/import-local.helpers.d.ts +28 -0
- package/dist/src/commands/import-local.helpers.d.ts.map +1 -0
- package/dist/src/commands/import-local.helpers.js +166 -0
- package/dist/src/commands/import-local.helpers.js.map +1 -0
- package/dist/src/commands/import-local.js +265 -0
- package/dist/src/commands/import-local.js.map +1 -0
- package/dist/src/commands/import-local.types.d.ts +59 -0
- package/dist/src/commands/import-local.types.d.ts.map +1 -0
- package/dist/src/commands/import-local.types.js +2 -0
- package/dist/src/commands/import-local.types.js.map +1 -0
- package/dist/src/{import.d.ts → commands/import.d.ts} +11 -0
- package/dist/src/commands/import.d.ts.map +1 -0
- package/dist/src/{import.js → commands/import.js} +36 -2
- package/dist/src/commands/import.js.map +1 -0
- package/dist/src/commands/index.d.ts +3 -0
- package/dist/src/commands/index.d.ts.map +1 -1
- package/dist/src/commands/index.js +6 -0
- package/dist/src/commands/index.js.map +1 -1
- package/dist/src/commands/install-skill.d.ts.map +1 -1
- package/dist/src/commands/install-skill.js +6 -3
- package/dist/src/commands/install-skill.js.map +1 -1
- package/dist/src/commands/install.d.ts.map +1 -1
- package/dist/src/commands/install.js +71 -2
- package/dist/src/commands/install.js.map +1 -1
- package/dist/src/commands/manage.d.ts.map +1 -1
- package/dist/src/commands/manage.js +13 -0
- package/dist/src/commands/manage.js.map +1 -1
- package/dist/src/commands/recommend.helpers.d.ts +5 -1
- package/dist/src/commands/recommend.helpers.d.ts.map +1 -1
- package/dist/src/commands/recommend.helpers.js +9 -3
- package/dist/src/commands/recommend.helpers.js.map +1 -1
- package/dist/src/config.d.ts +6 -1
- package/dist/src/config.d.ts.map +1 -1
- package/dist/src/config.js +8 -2
- package/dist/src/config.js.map +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.js +10 -28
- package/dist/src/index.js.map +1 -1
- package/dist/src/templates/mcp-server.template.d.ts +1 -1
- package/dist/src/templates/mcp-server.template.d.ts.map +1 -1
- package/dist/src/templates/mcp-server.template.js +13 -13
- package/dist/src/templates/mcp-server.template.js.map +1 -1
- package/dist/src/templates/mcp-server.template.snippets.d.ts +51 -0
- package/dist/src/templates/mcp-server.template.snippets.d.ts.map +1 -0
- package/dist/src/templates/mcp-server.template.snippets.js +162 -0
- package/dist/src/templates/mcp-server.template.snippets.js.map +1 -0
- package/dist/src/templates/readme.md.template.d.ts +1 -1
- package/dist/src/templates/readme.md.template.d.ts.map +1 -1
- package/dist/src/templates/readme.md.template.js +2 -2
- package/dist/src/utils/skills-directory.d.ts +26 -7
- package/dist/src/utils/skills-directory.d.ts.map +1 -1
- package/dist/src/utils/skills-directory.js +75 -30
- package/dist/src/utils/skills-directory.js.map +1 -1
- package/dist/tests/audit-collisions.test.d.ts +42 -0
- package/dist/tests/audit-collisions.test.d.ts.map +1 -0
- package/dist/tests/audit-collisions.test.js +370 -0
- package/dist/tests/audit-collisions.test.js.map +1 -0
- package/dist/tests/audit-restructure.test.d.ts +15 -0
- package/dist/tests/audit-restructure.test.d.ts.map +1 -0
- package/dist/tests/audit-restructure.test.js +151 -0
- package/dist/tests/audit-restructure.test.js.map +1 -0
- package/dist/tests/config.test.d.ts +33 -0
- package/dist/tests/config.test.d.ts.map +1 -0
- package/dist/tests/config.test.js +240 -0
- package/dist/tests/config.test.js.map +1 -0
- package/dist/tests/install-multi-client.test.d.ts +2 -0
- package/dist/tests/install-multi-client.test.d.ts.map +1 -0
- package/dist/tests/install-multi-client.test.js +202 -0
- package/dist/tests/install-multi-client.test.js.map +1 -0
- package/dist/tests/integration/import-local.test.d.ts +2 -0
- package/dist/tests/integration/import-local.test.d.ts.map +1 -0
- package/dist/tests/integration/import-local.test.js +158 -0
- package/dist/tests/integration/import-local.test.js.map +1 -0
- package/dist/tests/mcp-server-template.test.js +21 -0
- package/dist/tests/mcp-server-template.test.js.map +1 -1
- package/dist/tests/skills-directory.test.d.ts +2 -0
- package/dist/tests/skills-directory.test.d.ts.map +1 -0
- package/dist/tests/skills-directory.test.js +97 -0
- package/dist/tests/skills-directory.test.js.map +1 -0
- package/dist/tests/unit/import-local.helpers.test.d.ts +2 -0
- package/dist/tests/unit/import-local.helpers.test.d.ts.map +1 -0
- package/dist/tests/unit/import-local.helpers.test.js +96 -0
- package/dist/tests/unit/import-local.helpers.test.js.map +1 -0
- package/package.json +9 -3
- package/dist/src/import.d.ts.map +0 -1
- package/dist/src/import.js.map +0 -1
|
@@ -70,7 +70,7 @@ export declare const EXAMPLE_TOOL_TS_TEMPLATE = "/**\n * Example Tool Implementa
|
|
|
70
70
|
/**
|
|
71
71
|
* README.md template for MCP server
|
|
72
72
|
*/
|
|
73
|
-
export declare const MCP_README_TEMPLATE = "# {{name}}\n\n{{description}}\n\n## Installation\n\n```bash\nnpm install -g {{name}}\n```\n\nOr use directly with npx:\n\n```bash\nnpx {{name}}\n```\n\n## Configuration\n\
|
|
73
|
+
export declare const MCP_README_TEMPLATE = "# {{name}}\n\n{{description}}\n\n## Installation\n\n```bash\nnpm install -g {{name}}\n```\n\nOr use directly with npx:\n\n```bash\nnpx {{name}}\n```\n\n## Configuration\n\nThis server is MCP-compatible \u2014 pick the snippet that matches your agent.\nSMI-4580: snippets are sourced from `@skillsmith/cli/templates/mcp-server.template.snippets`\nso docs and scaffolded READMEs can't drift.\n\n{{clientSnippets}}\n\n## Available Tools\n\n{{toolDocs}}\n\n## Development\n\n```bash\n# Install dependencies\nnpm install\n\n# Run in development mode\nnpm run dev\n\n# Build for production\nnpm run build\n\n# Run production build\nnpm start\n```\n\n## License\n\nMIT\n";
|
|
74
74
|
/**
|
|
75
75
|
* .gitignore template for MCP server
|
|
76
76
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-server.template.d.ts","sourceRoot":"","sources":["../../../src/templates/mcp-server.template.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAGH,YAAY,EACV,qBAAqB,EACrB,iBAAiB,EACjB,sBAAsB,GACvB,MAAM,yBAAyB,CAAA;AAGhC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAA;AAgBpE;;GAEG;AACH,eAAO,MAAM,qBAAqB,QAoCjC,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,sBAAsB,4gBAmBlC,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,iBAAiB,0YAmB7B,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,kBAAkB,wnDAoE9B,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,uBAAuB,0iBA6BnC,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,wBAAwB,wsBA+BpC,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,mBAAmB,
|
|
1
|
+
{"version":3,"file":"mcp-server.template.d.ts","sourceRoot":"","sources":["../../../src/templates/mcp-server.template.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAGH,YAAY,EACV,qBAAqB,EACrB,iBAAiB,EACjB,sBAAsB,GACvB,MAAM,yBAAyB,CAAA;AAGhC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAA;AAgBpE;;GAEG;AACH,eAAO,MAAM,qBAAqB,QAoCjC,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,sBAAsB,4gBAmBlC,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,iBAAiB,0YAmB7B,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,kBAAkB,wnDAoE9B,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,uBAAuB,0iBA6BnC,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,wBAAwB,wsBA+BpC,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,mBAAmB,4pBA+C/B,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,sBAAsB,oPA2BlC,CAAA;AASD;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,qBAAqB,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAyFzF"}
|
|
@@ -294,18 +294,11 @@ npx {{name}}
|
|
|
294
294
|
|
|
295
295
|
## Configuration
|
|
296
296
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
"{{name}}": {
|
|
303
|
-
"command": "npx",
|
|
304
|
-
"args": ["-y", "{{name}}"]
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
\`\`\`
|
|
297
|
+
This server is MCP-compatible — pick the snippet that matches your agent.
|
|
298
|
+
SMI-4580: snippets are sourced from \`@skillsmith/cli/templates/mcp-server.template.snippets\`
|
|
299
|
+
so docs and scaffolded READMEs can't drift.
|
|
300
|
+
|
|
301
|
+
{{clientSnippets}}
|
|
309
302
|
|
|
310
303
|
## Available Tools
|
|
311
304
|
|
|
@@ -362,6 +355,8 @@ npm-debug.log*
|
|
|
362
355
|
# Test coverage
|
|
363
356
|
coverage/
|
|
364
357
|
`;
|
|
358
|
+
// SMI-4580: per-client config snippet matrix
|
|
359
|
+
import { renderAllSnippetsAsMarkdown } from './mcp-server.template.snippets.js';
|
|
365
360
|
// ============================================================================
|
|
366
361
|
// Main Render Function
|
|
367
362
|
// ============================================================================
|
|
@@ -420,9 +415,14 @@ export function renderMcpServerTemplates(data) {
|
|
|
420
415
|
files.set('src/tools/example.ts', EXAMPLE_TOOL_TS_TEMPLATE);
|
|
421
416
|
}
|
|
422
417
|
// README.md
|
|
418
|
+
// SMI-4580: interpolate per-client snippets so the scaffolded README
|
|
419
|
+
// covers every supported agent (Claude Code, Cursor, Copilot,
|
|
420
|
+
// Windsurf, Codex, cross-agent) — same source as the website docs.
|
|
421
|
+
const clientSnippets = renderAllSnippetsAsMarkdown(data.name);
|
|
423
422
|
files.set('README.md', MCP_README_TEMPLATE.replace(/\{\{name\}\}/g, data.name)
|
|
424
423
|
.replace(/\{\{description\}\}/g, data.description)
|
|
425
|
-
.replace(/\{\{toolDocs\}\}/g, toolDocs)
|
|
424
|
+
.replace(/\{\{toolDocs\}\}/g, toolDocs)
|
|
425
|
+
.replace(/\{\{clientSnippets\}\}/g, clientSnippets));
|
|
426
426
|
// .gitignore
|
|
427
427
|
files.set('.gitignore', MCP_GITIGNORE_TEMPLATE);
|
|
428
428
|
return files;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-server.template.js","sourceRoot":"","sources":["../../../src/templates/mcp-server.template.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAWH,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAElD,kBAAkB;AAClB,OAAO,EACL,sBAAsB,EACtB,gBAAgB,EAChB,kBAAkB,EAClB,0BAA0B,EAC1B,gBAAgB,GACjB,MAAM,4BAA4B,CAAA;AAEnC,+EAA+E;AAC/E,qBAAqB;AACrB,+EAA+E;AAE/E;;GAEG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;oCAyBD,QAAQ,CAAC,OAAO;;;sBAG9B,QAAQ,CAAC,UAAU;cAC3B,QAAQ,CAAC,GAAG;qBACL,QAAQ,CAAC,UAAU;;;eAGzB,QAAQ,CAAC,WAAW;;;CAGlC,CAAA;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG;;;;;;;;;;;;;;;;;;;CAmBrC,CAAA;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG;;;;;;;;;;;;;;;;;;;CAmBhC,CAAA;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoEjC,CAAA;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6BtC,CAAA;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+BvC,CAAA;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG
|
|
1
|
+
{"version":3,"file":"mcp-server.template.js","sourceRoot":"","sources":["../../../src/templates/mcp-server.template.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SMI-4580: Per-client MCP config snippets.
|
|
3
|
+
*
|
|
4
|
+
* Single source of truth for the install-time configuration block each
|
|
5
|
+
* agent expects. Same source feeds:
|
|
6
|
+
* - the scaffolded mcp-server README (via mcp-server.template.ts)
|
|
7
|
+
* - the website docs (`getting-started.astro`, `quickstart.astro`)
|
|
8
|
+
* - the root README + packages/mcp-server/README.md
|
|
9
|
+
*
|
|
10
|
+
* Four of five clients accept the same `mcpServers` JSON shape.
|
|
11
|
+
* Codex needs TOML (separate `[mcp_servers.<name>]` table).
|
|
12
|
+
*
|
|
13
|
+
* @module @skillsmith/cli/templates/mcp-server.template.snippets
|
|
14
|
+
*/
|
|
15
|
+
import type { ClientId } from '@skillsmith/core/install';
|
|
16
|
+
export type SnippetClientId = ClientId | 'codex';
|
|
17
|
+
export interface ClientSnippet {
|
|
18
|
+
/** Display label for the per-client tab/section header */
|
|
19
|
+
label: string;
|
|
20
|
+
/** Path to the config file the user edits */
|
|
21
|
+
configPath: string;
|
|
22
|
+
/** File format hint for the syntax highlighter */
|
|
23
|
+
format: 'json' | 'toml';
|
|
24
|
+
/** Snippet body — interpolated with `{{name}}` for the package name */
|
|
25
|
+
body: string;
|
|
26
|
+
/** Notes shown beneath the snippet */
|
|
27
|
+
notes?: string;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Per-client snippet matrix. `name` placeholder is interpolated when the
|
|
31
|
+
* snippet is rendered; pass `'@skillsmith/mcp-server'` for the published
|
|
32
|
+
* package, or any other server name when scaffolding via the template.
|
|
33
|
+
*/
|
|
34
|
+
export declare const CLIENT_SNIPPETS: Record<SnippetClientId, ClientSnippet>;
|
|
35
|
+
/**
|
|
36
|
+
* Render a single client snippet with the package name interpolated.
|
|
37
|
+
*/
|
|
38
|
+
export declare function renderSnippet(client: SnippetClientId, packageName: string): string;
|
|
39
|
+
/**
|
|
40
|
+
* Render every snippet as a markdown section sequence — labelled with
|
|
41
|
+
* `<details>` + `<summary>` so the docs surface stays compact when no
|
|
42
|
+
* dedicated tabs component is available. Used by both the website
|
|
43
|
+
* markdown surfaces and the scaffolded mcp-server README.
|
|
44
|
+
*/
|
|
45
|
+
export declare function renderAllSnippetsAsMarkdown(packageName: string): string;
|
|
46
|
+
/**
|
|
47
|
+
* Snippet IDs in display order. Use when a docs surface needs to
|
|
48
|
+
* render snippets without a `<details>` accordion (e.g. printable PDF).
|
|
49
|
+
*/
|
|
50
|
+
export declare const SNIPPET_DISPLAY_ORDER: ReadonlyArray<SnippetClientId>;
|
|
51
|
+
//# sourceMappingURL=mcp-server.template.snippets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-server.template.snippets.d.ts","sourceRoot":"","sources":["../../../src/templates/mcp-server.template.snippets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAA;AAExD,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,OAAO,CAAA;AAEhD,MAAM,WAAW,aAAa;IAC5B,0DAA0D;IAC1D,KAAK,EAAE,MAAM,CAAA;IACb,6CAA6C;IAC7C,UAAU,EAAE,MAAM,CAAA;IAClB,kDAAkD;IAClD,MAAM,EAAE,MAAM,GAAG,MAAM,CAAA;IACvB,uEAAuE;IACvE,IAAI,EAAE,MAAM,CAAA;IACZ,sCAAsC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,eAAe,EAAE,aAAa,CAsGlE,CAAA;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAGlF;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAiBvE;AAED;;;GAGG;AACH,eAAO,MAAM,qBAAqB,EAAE,aAAa,CAAC,eAAe,CAO/D,CAAA"}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SMI-4580: Per-client MCP config snippets.
|
|
3
|
+
*
|
|
4
|
+
* Single source of truth for the install-time configuration block each
|
|
5
|
+
* agent expects. Same source feeds:
|
|
6
|
+
* - the scaffolded mcp-server README (via mcp-server.template.ts)
|
|
7
|
+
* - the website docs (`getting-started.astro`, `quickstart.astro`)
|
|
8
|
+
* - the root README + packages/mcp-server/README.md
|
|
9
|
+
*
|
|
10
|
+
* Four of five clients accept the same `mcpServers` JSON shape.
|
|
11
|
+
* Codex needs TOML (separate `[mcp_servers.<name>]` table).
|
|
12
|
+
*
|
|
13
|
+
* @module @skillsmith/cli/templates/mcp-server.template.snippets
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Per-client snippet matrix. `name` placeholder is interpolated when the
|
|
17
|
+
* snippet is rendered; pass `'@skillsmith/mcp-server'` for the published
|
|
18
|
+
* package, or any other server name when scaffolding via the template.
|
|
19
|
+
*/
|
|
20
|
+
export const CLIENT_SNIPPETS = {
|
|
21
|
+
'claude-code': {
|
|
22
|
+
label: 'Claude Code',
|
|
23
|
+
configPath: '~/.claude/settings.json',
|
|
24
|
+
format: 'json',
|
|
25
|
+
body: `{
|
|
26
|
+
"mcpServers": {
|
|
27
|
+
"{{name}}": {
|
|
28
|
+
"command": "npx",
|
|
29
|
+
"args": ["-y", "{{name}}"],
|
|
30
|
+
"env": {
|
|
31
|
+
"SKILLSMITH_API_KEY": "sk_live_..."
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}`,
|
|
36
|
+
notes: 'Restart Claude Code after editing settings.json.',
|
|
37
|
+
},
|
|
38
|
+
cursor: {
|
|
39
|
+
label: 'Cursor',
|
|
40
|
+
configPath: '~/.cursor/mcp.json',
|
|
41
|
+
format: 'json',
|
|
42
|
+
body: `{
|
|
43
|
+
"mcpServers": {
|
|
44
|
+
"{{name}}": {
|
|
45
|
+
"command": "npx",
|
|
46
|
+
"args": ["-y", "{{name}}"],
|
|
47
|
+
"env": {
|
|
48
|
+
"SKILLSMITH_API_KEY": "sk_live_..."
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}`,
|
|
53
|
+
notes: 'Cursor 2.4+ required. Reload the window after saving.',
|
|
54
|
+
},
|
|
55
|
+
copilot: {
|
|
56
|
+
label: 'GitHub Copilot (VS Code)',
|
|
57
|
+
configPath: '.vscode/mcp.json (workspace)',
|
|
58
|
+
format: 'json',
|
|
59
|
+
body: `{
|
|
60
|
+
"mcpServers": {
|
|
61
|
+
"{{name}}": {
|
|
62
|
+
"command": "npx",
|
|
63
|
+
"args": ["-y", "{{name}}"],
|
|
64
|
+
"env": {
|
|
65
|
+
"SKILLSMITH_API_KEY": "sk_live_..."
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}`,
|
|
70
|
+
notes: 'VS Code 1.108+ required. Workspace-scoped config (commit to repo if team-shared, or use user settings.json instead).',
|
|
71
|
+
},
|
|
72
|
+
windsurf: {
|
|
73
|
+
label: 'Windsurf',
|
|
74
|
+
configPath: '~/.codeium/windsurf/mcp_config.json',
|
|
75
|
+
format: 'json',
|
|
76
|
+
body: `{
|
|
77
|
+
"mcpServers": {
|
|
78
|
+
"{{name}}": {
|
|
79
|
+
"command": "npx",
|
|
80
|
+
"args": ["-y", "{{name}}"],
|
|
81
|
+
"env": {
|
|
82
|
+
"SKILLSMITH_API_KEY": "\${env:SKILLSMITH_API_KEY}"
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}`,
|
|
87
|
+
notes: 'Supports `${env:VAR}` interpolation; export SKILLSMITH_API_KEY in your shell instead of inlining the secret.',
|
|
88
|
+
},
|
|
89
|
+
agents: {
|
|
90
|
+
label: 'Cross-agent (open standard)',
|
|
91
|
+
configPath: '~/.agents/mcp.json',
|
|
92
|
+
format: 'json',
|
|
93
|
+
body: `{
|
|
94
|
+
"mcpServers": {
|
|
95
|
+
"{{name}}": {
|
|
96
|
+
"command": "npx",
|
|
97
|
+
"args": ["-y", "{{name}}"],
|
|
98
|
+
"env": {
|
|
99
|
+
"SKILLSMITH_API_KEY": "sk_live_..."
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}`,
|
|
104
|
+
notes: 'Read by any agent honouring the cross-agent skill convention. Codex CLI users prefer the Codex-native TOML snippet below.',
|
|
105
|
+
},
|
|
106
|
+
codex: {
|
|
107
|
+
label: 'Codex CLI',
|
|
108
|
+
configPath: '~/.codex/config.toml',
|
|
109
|
+
format: 'toml',
|
|
110
|
+
body: `[mcp_servers.{{name}}]
|
|
111
|
+
command = "npx"
|
|
112
|
+
args = ["-y", "{{name}}"]
|
|
113
|
+
|
|
114
|
+
[mcp_servers.{{name}}.env]
|
|
115
|
+
SKILLSMITH_API_KEY = "sk_live_..."`,
|
|
116
|
+
notes: 'Codex uses TOML, not JSON. Skill discovery still reads ~/.agents/skills (set --client agents when installing via Skillsmith CLI).',
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
/**
|
|
120
|
+
* Render a single client snippet with the package name interpolated.
|
|
121
|
+
*/
|
|
122
|
+
export function renderSnippet(client, packageName) {
|
|
123
|
+
const snippet = CLIENT_SNIPPETS[client];
|
|
124
|
+
return snippet.body.replace(/\{\{name\}\}/g, packageName);
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Render every snippet as a markdown section sequence — labelled with
|
|
128
|
+
* `<details>` + `<summary>` so the docs surface stays compact when no
|
|
129
|
+
* dedicated tabs component is available. Used by both the website
|
|
130
|
+
* markdown surfaces and the scaffolded mcp-server README.
|
|
131
|
+
*/
|
|
132
|
+
export function renderAllSnippetsAsMarkdown(packageName) {
|
|
133
|
+
const sections = Object.keys(CLIENT_SNIPPETS).map((id) => {
|
|
134
|
+
const snippet = CLIENT_SNIPPETS[id];
|
|
135
|
+
const body = renderSnippet(id, packageName);
|
|
136
|
+
const notes = snippet.notes ? `\n\n${snippet.notes}` : '';
|
|
137
|
+
return [
|
|
138
|
+
`<details>`,
|
|
139
|
+
`<summary><strong>${snippet.label}</strong> — \`${snippet.configPath}\`</summary>`,
|
|
140
|
+
``,
|
|
141
|
+
`\`\`\`${snippet.format}`,
|
|
142
|
+
body,
|
|
143
|
+
`\`\`\`${notes}`,
|
|
144
|
+
``,
|
|
145
|
+
`</details>`,
|
|
146
|
+
].join('\n');
|
|
147
|
+
});
|
|
148
|
+
return sections.join('\n\n');
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Snippet IDs in display order. Use when a docs surface needs to
|
|
152
|
+
* render snippets without a `<details>` accordion (e.g. printable PDF).
|
|
153
|
+
*/
|
|
154
|
+
export const SNIPPET_DISPLAY_ORDER = Object.freeze([
|
|
155
|
+
'claude-code',
|
|
156
|
+
'cursor',
|
|
157
|
+
'copilot',
|
|
158
|
+
'windsurf',
|
|
159
|
+
'codex',
|
|
160
|
+
'agents',
|
|
161
|
+
]);
|
|
162
|
+
//# sourceMappingURL=mcp-server.template.snippets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-server.template.snippets.js","sourceRoot":"","sources":["../../../src/templates/mcp-server.template.snippets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAmBH;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAA2C;IACrE,aAAa,EAAE;QACb,KAAK,EAAE,aAAa;QACpB,UAAU,EAAE,yBAAyB;QACrC,MAAM,EAAE,MAAM;QACd,IAAI,EAAE;;;;;;;;;;EAUR;QACE,KAAK,EAAE,kDAAkD;KAC1D;IACD,MAAM,EAAE;QACN,KAAK,EAAE,QAAQ;QACf,UAAU,EAAE,oBAAoB;QAChC,MAAM,EAAE,MAAM;QACd,IAAI,EAAE;;;;;;;;;;EAUR;QACE,KAAK,EAAE,uDAAuD;KAC/D;IACD,OAAO,EAAE;QACP,KAAK,EAAE,0BAA0B;QACjC,UAAU,EAAE,8BAA8B;QAC1C,MAAM,EAAE,MAAM;QACd,IAAI,EAAE;;;;;;;;;;EAUR;QACE,KAAK,EACH,sHAAsH;KACzH;IACD,QAAQ,EAAE;QACR,KAAK,EAAE,UAAU;QACjB,UAAU,EAAE,qCAAqC;QACjD,MAAM,EAAE,MAAM;QACd,IAAI,EAAE;;;;;;;;;;EAUR;QACE,KAAK,EACH,8GAA8G;KACjH;IACD,MAAM,EAAE;QACN,KAAK,EAAE,6BAA6B;QACpC,UAAU,EAAE,oBAAoB;QAChC,MAAM,EAAE,MAAM;QACd,IAAI,EAAE;;;;;;;;;;EAUR;QACE,KAAK,EACH,2HAA2H;KAC9H;IACD,KAAK,EAAE;QACL,KAAK,EAAE,WAAW;QAClB,UAAU,EAAE,sBAAsB;QAClC,MAAM,EAAE,MAAM;QACd,IAAI,EAAE;;;;;mCAKyB;QAC/B,KAAK,EACH,mIAAmI;KACtI;CACF,CAAA;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,MAAuB,EAAE,WAAmB;IACxE,MAAM,OAAO,GAAG,eAAe,CAAC,MAAM,CAAC,CAAA;IACvC,OAAO,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,WAAW,CAAC,CAAA;AAC3D,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,2BAA2B,CAAC,WAAmB;IAC7D,MAAM,QAAQ,GAAI,MAAM,CAAC,IAAI,CAAC,eAAe,CAAuB,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE;QAC9E,MAAM,OAAO,GAAG,eAAe,CAAC,EAAE,CAAC,CAAA;QACnC,MAAM,IAAI,GAAG,aAAa,CAAC,EAAE,EAAE,WAAW,CAAC,CAAA;QAC3C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;QACzD,OAAO;YACL,WAAW;YACX,oBAAoB,OAAO,CAAC,KAAK,iBAAiB,OAAO,CAAC,UAAU,cAAc;YAClF,EAAE;YACF,SAAS,OAAO,CAAC,MAAM,EAAE;YACzB,IAAI;YACJ,SAAS,KAAK,EAAE;YAChB,EAAE;YACF,YAAY;SACb,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACd,CAAC,CAAC,CAAA;IACF,OAAO,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;AAC9B,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAmC,MAAM,CAAC,MAAM,CAAC;IACjF,aAAa;IACb,QAAQ;IACR,SAAS;IACT,UAAU;IACV,OAAO;IACP,QAAQ;CACT,CAAC,CAAA"}
|
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Template for new skill README files.
|
|
5
5
|
*/
|
|
6
|
-
export declare const README_MD_TEMPLATE = "# {{name}}\n\n{{description}}\n\n## Overview\n\nThis is
|
|
6
|
+
export declare const README_MD_TEMPLATE = "# {{name}}\n\n{{description}}\n\n## Overview\n\nThis is an agent skill (SKILL.md format, MCP-compatible) that provides [describe functionality].\n\n## Installation\n\n### Via Skillsmith\n\n```bash\nskillsmith install {{author}}/{{name}}\n```\n\n### Manual Installation\n\n1. Clone or download this repository\n2. Copy to your skills directory:\n\n```bash\ncp -r {{name}} ~/.claude/skills/\n```\n\n## Quick Start\n\n1. Install the skill\n2. Start your MCP-compatible agent (Claude Code, Cursor, Copilot, Codex, Windsurf, etc.)\n3. Use the skill by [describe how to trigger]\n\n## Documentation\n\nSee [SKILL.md](./SKILL.md) for detailed documentation.\n\n## Development\n\n### Prerequisites\n\n- Node.js 18+\n- npm or pnpm\n\n### Setup\n\n```bash\n# Install dependencies (if any)\nnpm install\n\n# Run tests\nnpm test\n```\n\n### Project Structure\n\n```\n{{name}}/\n\u251C\u2500\u2500 SKILL.md # Skill definition and documentation\n\u251C\u2500\u2500 README.md # This file\n\u251C\u2500\u2500 scripts/ # Automation scripts\n\u2502 \u2514\u2500\u2500 example.js # Example script\n\u251C\u2500\u2500 resources/ # Static resources\n\u2514\u2500\u2500 .gitignore # Git ignore rules\n```\n\n## Contributing\n\n1. Fork the repository\n2. Create a feature branch\n3. Make your changes\n4. Submit a pull request\n\n## License\n\nMIT License\n\n## Author\n\nCreated with [Skillsmith](https://github.com/skillsmith/skillsmith)\n";
|
|
7
7
|
export default README_MD_TEMPLATE;
|
|
8
8
|
//# sourceMappingURL=readme.md.template.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"readme.md.template.d.ts","sourceRoot":"","sources":["../../../src/templates/readme.md.template.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,eAAO,MAAM,kBAAkB,
|
|
1
|
+
{"version":3,"file":"readme.md.template.d.ts","sourceRoot":"","sources":["../../../src/templates/readme.md.template.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,eAAO,MAAM,kBAAkB,47CA8E9B,CAAA;AAED,eAAe,kBAAkB,CAAA"}
|
|
@@ -9,7 +9,7 @@ export const README_MD_TEMPLATE = `# {{name}}
|
|
|
9
9
|
|
|
10
10
|
## Overview
|
|
11
11
|
|
|
12
|
-
This is
|
|
12
|
+
This is an agent skill (SKILL.md format, MCP-compatible) that provides [describe functionality].
|
|
13
13
|
|
|
14
14
|
## Installation
|
|
15
15
|
|
|
@@ -31,7 +31,7 @@ cp -r {{name}} ~/.claude/skills/
|
|
|
31
31
|
## Quick Start
|
|
32
32
|
|
|
33
33
|
1. Install the skill
|
|
34
|
-
2. Start Claude Code
|
|
34
|
+
2. Start your MCP-compatible agent (Claude Code, Cursor, Copilot, Codex, Windsurf, etc.)
|
|
35
35
|
3. Use the skill by [describe how to trigger]
|
|
36
36
|
|
|
37
37
|
## Documentation
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* from the global and local ~/.claude/skills directories.
|
|
4
4
|
*/
|
|
5
5
|
import { type TrustTier } from '@skillsmith/core';
|
|
6
|
+
import { type ClientId } from '@skillsmith/core/install';
|
|
6
7
|
export interface InstalledSkill {
|
|
7
8
|
name: string;
|
|
8
9
|
path: string;
|
|
@@ -10,6 +11,12 @@ export interface InstalledSkill {
|
|
|
10
11
|
trustTier: TrustTier;
|
|
11
12
|
installDate: string;
|
|
12
13
|
hasUpdates: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* SMI-4578: which client's directory this skill was discovered under.
|
|
16
|
+
* `'local'` = repo-local `./.claude/skills`. Other values are
|
|
17
|
+
* `ClientId` from the multi-client install table.
|
|
18
|
+
*/
|
|
19
|
+
installedVia: ClientId | 'local';
|
|
13
20
|
}
|
|
14
21
|
/**
|
|
15
22
|
* Get skills from a specific directory.
|
|
@@ -18,17 +25,29 @@ export interface InstalledSkill {
|
|
|
18
25
|
* whether a newer content hash has been recorded since the skill was installed.
|
|
19
26
|
* Falls back to hasUpdates: false when the database is unavailable.
|
|
20
27
|
*
|
|
21
|
-
* @param skillsDir
|
|
22
|
-
* @param dbPath
|
|
28
|
+
* @param skillsDir Directory to scan for installed skills
|
|
29
|
+
* @param dbPath Optional path to the Skillsmith SQLite database
|
|
30
|
+
* @param installedVia SMI-4578: which client (or `'local'`) this directory
|
|
31
|
+
* represents — propagated onto each returned skill so
|
|
32
|
+
* callers can render "installed via Cursor" badges.
|
|
23
33
|
*/
|
|
24
|
-
export declare function getSkillsFromDirectory(skillsDir: string, dbPath?: string): Promise<InstalledSkill[]>;
|
|
34
|
+
export declare function getSkillsFromDirectory(skillsDir: string, dbPath?: string, installedVia?: ClientId | 'local'): Promise<InstalledSkill[]>;
|
|
25
35
|
/**
|
|
26
|
-
* Get list of installed skills
|
|
27
|
-
* local (.claude/skills) directories.
|
|
36
|
+
* Get list of installed skills across every client directory.
|
|
28
37
|
*
|
|
29
|
-
* SMI-
|
|
38
|
+
* SMI-4578: scans the union of `CLIENT_NATIVE_PATHS` (claude-code,
|
|
39
|
+
* cursor, copilot, windsurf, agents) plus repo-local
|
|
40
|
+
* `./.claude/skills`. Results are deduplicated by `realpath` so a
|
|
41
|
+
* symlinked `~/.agents/skills/foo` pointing at `~/.claude/skills/foo`
|
|
42
|
+
* is reported once. Each entry carries `installedVia` so the caller
|
|
43
|
+
* can render "installed via Cursor" badges.
|
|
30
44
|
*
|
|
31
|
-
*
|
|
45
|
+
* Precedence (first wins after dedup): local (repo) > claude-code >
|
|
46
|
+
* cursor > copilot > windsurf > agents. This keeps the SMI-1630
|
|
47
|
+
* promise that repo-local overrides global.
|
|
48
|
+
*
|
|
49
|
+
* @param dbPath Optional path to the Skillsmith SQLite database for
|
|
50
|
+
* update detection.
|
|
32
51
|
*/
|
|
33
52
|
export declare function getInstalledSkills(dbPath?: string): Promise<InstalledSkill[]>;
|
|
34
53
|
//# sourceMappingURL=skills-directory.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skills-directory.d.ts","sourceRoot":"","sources":["../../../src/utils/skills-directory.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"skills-directory.d.ts","sourceRoot":"","sources":["../../../src/utils/skills-directory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAML,KAAK,SAAS,EACf,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAIL,KAAK,QAAQ,EACd,MAAM,0BAA0B,CAAA;AAGjC,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,SAAS,EAAE,SAAS,CAAA;IACpB,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,OAAO,CAAA;IACnB;;;;OAIG;IACH,YAAY,EAAE,QAAQ,GAAG,OAAO,CAAA;CACjC;AAiBD;;;;;;;;;;;;GAYG;AACH,wBAAsB,sBAAsB,CAC1C,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,MAAM,EACf,YAAY,GAAE,QAAQ,GAAG,OAA0B,GAClD,OAAO,CAAC,cAAc,EAAE,CAAC,CAmG3B;AAgBD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,kBAAkB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAwCnF"}
|
|
@@ -2,21 +2,18 @@
|
|
|
2
2
|
* SMI-2713: Extracted from manage.ts — helpers for reading installed skills
|
|
3
3
|
* from the global and local ~/.claude/skills directories.
|
|
4
4
|
*/
|
|
5
|
-
import { readdir, readFile, stat } from 'fs/promises';
|
|
5
|
+
import { readdir, readFile, realpath, stat } from 'fs/promises';
|
|
6
6
|
import { createHash } from 'crypto';
|
|
7
7
|
import { join } from 'path';
|
|
8
|
-
import { homedir } from 'os';
|
|
9
8
|
import { SkillParser, createDatabaseAsync, initializeSchema, SkillVersionRepository, } from '@skillsmith/core';
|
|
9
|
+
import { CANONICAL_CLIENT, CLIENT_IDS, CLIENT_NATIVE_PATHS, } from '@skillsmith/core/install';
|
|
10
10
|
import { DEFAULT_DB_PATH } from '../config.js';
|
|
11
11
|
/**
|
|
12
|
-
* SMI-1630
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* Local skills take precedence over global skills with the same name.
|
|
12
|
+
* SMI-1630 + SMI-4578: discovery scans every client directory
|
|
13
|
+
* (`CLIENT_NATIVE_PATHS`) plus repo-local `./.claude/skills`. Local
|
|
14
|
+
* skills take precedence over global; canonical (`claude-code`) takes
|
|
15
|
+
* precedence over secondary clients. See `getInstalledSkills` below.
|
|
18
16
|
*/
|
|
19
|
-
const GLOBAL_SKILLS_DIR = join(homedir(), '.claude', 'skills');
|
|
20
17
|
/**
|
|
21
18
|
* Returns the local skills directory path.
|
|
22
19
|
* Computed at call time to handle working directory changes.
|
|
@@ -31,10 +28,13 @@ function getLocalSkillsDir() {
|
|
|
31
28
|
* whether a newer content hash has been recorded since the skill was installed.
|
|
32
29
|
* Falls back to hasUpdates: false when the database is unavailable.
|
|
33
30
|
*
|
|
34
|
-
* @param skillsDir
|
|
35
|
-
* @param dbPath
|
|
31
|
+
* @param skillsDir Directory to scan for installed skills
|
|
32
|
+
* @param dbPath Optional path to the Skillsmith SQLite database
|
|
33
|
+
* @param installedVia SMI-4578: which client (or `'local'`) this directory
|
|
34
|
+
* represents — propagated onto each returned skill so
|
|
35
|
+
* callers can render "installed via Cursor" badges.
|
|
36
36
|
*/
|
|
37
|
-
export async function getSkillsFromDirectory(skillsDir, dbPath) {
|
|
37
|
+
export async function getSkillsFromDirectory(skillsDir, dbPath, installedVia = CANONICAL_CLIENT) {
|
|
38
38
|
const skills = [];
|
|
39
39
|
// Open the version repository if a db path was provided
|
|
40
40
|
let versionRepo = null;
|
|
@@ -95,6 +95,7 @@ export async function getSkillsFromDirectory(skillsDir, dbPath) {
|
|
|
95
95
|
trustTier: parsed ? parser.inferTrustTier(parsed) : 'unknown',
|
|
96
96
|
installDate: skillMdStat.mtime.toISOString().split('T')[0] || 'Unknown',
|
|
97
97
|
hasUpdates,
|
|
98
|
+
installedVia,
|
|
98
99
|
});
|
|
99
100
|
}
|
|
100
101
|
catch (error) {
|
|
@@ -113,6 +114,7 @@ export async function getSkillsFromDirectory(skillsDir, dbPath) {
|
|
|
113
114
|
trustTier: 'unknown',
|
|
114
115
|
installDate: dirStat.mtime.toISOString().split('T')[0] || 'Unknown',
|
|
115
116
|
hasUpdates: false,
|
|
117
|
+
installedVia,
|
|
116
118
|
});
|
|
117
119
|
}
|
|
118
120
|
}
|
|
@@ -129,30 +131,73 @@ export async function getSkillsFromDirectory(skillsDir, dbPath) {
|
|
|
129
131
|
return skills;
|
|
130
132
|
}
|
|
131
133
|
/**
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
+
* Resolve a path through `realpath` defensively. Returns the resolved
|
|
135
|
+
* path on success, or the input path unchanged if the path is missing
|
|
136
|
+
* or unreadable — dedup keying still works either way (we just won't
|
|
137
|
+
* collapse symlinked aliases when the link is broken).
|
|
138
|
+
*/
|
|
139
|
+
async function safeRealpath(p) {
|
|
140
|
+
try {
|
|
141
|
+
return await realpath(p);
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
return p;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Get list of installed skills across every client directory.
|
|
134
149
|
*
|
|
135
|
-
* SMI-
|
|
150
|
+
* SMI-4578: scans the union of `CLIENT_NATIVE_PATHS` (claude-code,
|
|
151
|
+
* cursor, copilot, windsurf, agents) plus repo-local
|
|
152
|
+
* `./.claude/skills`. Results are deduplicated by `realpath` so a
|
|
153
|
+
* symlinked `~/.agents/skills/foo` pointing at `~/.claude/skills/foo`
|
|
154
|
+
* is reported once. Each entry carries `installedVia` so the caller
|
|
155
|
+
* can render "installed via Cursor" badges.
|
|
136
156
|
*
|
|
137
|
-
*
|
|
157
|
+
* Precedence (first wins after dedup): local (repo) > claude-code >
|
|
158
|
+
* cursor > copilot > windsurf > agents. This keeps the SMI-1630
|
|
159
|
+
* promise that repo-local overrides global.
|
|
160
|
+
*
|
|
161
|
+
* @param dbPath Optional path to the Skillsmith SQLite database for
|
|
162
|
+
* update detection.
|
|
138
163
|
*/
|
|
139
164
|
export async function getInstalledSkills(dbPath) {
|
|
140
165
|
const resolvedDbPath = dbPath ?? DEFAULT_DB_PATH;
|
|
141
|
-
|
|
142
|
-
const
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
]
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
166
|
+
const localScan = getSkillsFromDirectory(getLocalSkillsDir(), resolvedDbPath, 'local');
|
|
167
|
+
const clientScans = CLIENT_IDS.map((client) => getSkillsFromDirectory(CLIENT_NATIVE_PATHS[client], resolvedDbPath, client));
|
|
168
|
+
const [localSkills, ...clientSkillsLists] = await Promise.all([localScan, ...clientScans]);
|
|
169
|
+
// Precedence order: local first, then canonical, then the rest.
|
|
170
|
+
const ordered = [...localSkills];
|
|
171
|
+
const canonicalIdx = CLIENT_IDS.indexOf(CANONICAL_CLIENT);
|
|
172
|
+
if (canonicalIdx >= 0 && clientSkillsLists[canonicalIdx]) {
|
|
173
|
+
ordered.push(...clientSkillsLists[canonicalIdx]);
|
|
174
|
+
}
|
|
175
|
+
for (let i = 0; i < CLIENT_IDS.length; i++) {
|
|
176
|
+
if (i === canonicalIdx)
|
|
177
|
+
continue;
|
|
178
|
+
const list = clientSkillsLists[i];
|
|
179
|
+
if (list)
|
|
180
|
+
ordered.push(...list);
|
|
151
181
|
}
|
|
152
|
-
//
|
|
153
|
-
|
|
154
|
-
|
|
182
|
+
// Dedup by both skill name AND resolved path. Name-keying enforces the
|
|
183
|
+
// precedence rule (local > canonical > others) when two clients carry
|
|
184
|
+
// independently-installed copies of the same skill. Realpath-keying
|
|
185
|
+
// collapses symlinked aliases (e.g. `~/.agents/skills` → `~/.claude/skills`)
|
|
186
|
+
// so the symlinked entry doesn't appear twice when the second hop has a
|
|
187
|
+
// different `installedVia` label.
|
|
188
|
+
const seenNames = new Set();
|
|
189
|
+
const seenPaths = new Set();
|
|
190
|
+
const out = [];
|
|
191
|
+
for (const skill of ordered) {
|
|
192
|
+
if (seenNames.has(skill.name))
|
|
193
|
+
continue;
|
|
194
|
+
const realPath = await safeRealpath(skill.path);
|
|
195
|
+
if (seenPaths.has(realPath))
|
|
196
|
+
continue;
|
|
197
|
+
seenNames.add(skill.name);
|
|
198
|
+
seenPaths.add(realPath);
|
|
199
|
+
out.push(skill);
|
|
155
200
|
}
|
|
156
|
-
return
|
|
201
|
+
return out;
|
|
157
202
|
}
|
|
158
203
|
//# sourceMappingURL=skills-directory.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skills-directory.js","sourceRoot":"","sources":["../../../src/utils/skills-directory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"skills-directory.js","sourceRoot":"","sources":["../../../src/utils/skills-directory.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview SMI-4590 Wave 4 PR 5/6 — `sklx audit collisions` tests
|
|
3
|
+
* @module @skillsmith/cli/tests/audit-collisions
|
|
4
|
+
*
|
|
5
|
+
* Coverage:
|
|
6
|
+
*
|
|
7
|
+
* Typed-confirmation gate (`requireConfirmationPhrase`) — load-bearing per
|
|
8
|
+
* plan §235-239. Strict literal equality, NO normalization.
|
|
9
|
+
* 1. Exact phrase ('APPLY ALL') — RESOLVES.
|
|
10
|
+
* 2. Single-letter ('Y') — REJECTS.
|
|
11
|
+
* 3. Lowercase word ('yes') — REJECTS.
|
|
12
|
+
* 4. Lowercase phrase ('apply all') — REJECTS.
|
|
13
|
+
* 5. No-space variant ('APPLYALL') — REJECTS.
|
|
14
|
+
* 6. Trailing whitespace ('APPLY ALL ') — REJECTS (no trim).
|
|
15
|
+
* 7. Empty string — REJECTS.
|
|
16
|
+
*
|
|
17
|
+
* Both interactive (TTY) and piped-stdin paths route through the same
|
|
18
|
+
* `@inquirer/prompts` `input()` call, so the rejection invariant holds for
|
|
19
|
+
* both. We mock `input` to assert the contract — the prompt library
|
|
20
|
+
* receives the answer verbatim and our code applies strict equality.
|
|
21
|
+
*
|
|
22
|
+
* Interactive prompt loop (`runInteractiveLoop`):
|
|
23
|
+
* 8. 'apply' choice → applyOneSuggestion called, status=applied.
|
|
24
|
+
* 9. 'skip' choice → outcome recorded as skipped, no apply call.
|
|
25
|
+
* 10. 'edit' choice → input prompts for custom name, applyRename
|
|
26
|
+
* receives `customName`.
|
|
27
|
+
* 11. 'quit' choice → loop terminates early; remaining suggestions
|
|
28
|
+
* are NOT processed.
|
|
29
|
+
* 12. Empty suggestion list → prints "No collisions found." and returns.
|
|
30
|
+
*
|
|
31
|
+
* Reset-ledger flow (`runResetLedger`):
|
|
32
|
+
* 13. Backs up an existing ledger to `~/.skillsmith/backups/ledger-*.json`
|
|
33
|
+
* BEFORE clearing.
|
|
34
|
+
* 14. No backup file when no prior ledger exists.
|
|
35
|
+
* 15. Confirmation phrase mismatch → throws, NO writeLedger call.
|
|
36
|
+
*
|
|
37
|
+
* `--json` output (`runAuditCollisions`):
|
|
38
|
+
* 16. JSON mode prints `RunInventoryAuditResult` to stdout, no prompts,
|
|
39
|
+
* no apply.
|
|
40
|
+
*/
|
|
41
|
+
export {};
|
|
42
|
+
//# sourceMappingURL=audit-collisions.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit-collisions.test.d.ts","sourceRoot":"","sources":["../../tests/audit-collisions.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG"}
|