@lyupro/skillforge-mcp 1.1.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 +114 -0
- package/LICENSE +21 -0
- package/README.md +231 -0
- package/dist/cli/install.d.ts +41 -0
- package/dist/cli/install.d.ts.map +1 -0
- package/dist/cli/install.js +223 -0
- package/dist/cli/install.js.map +1 -0
- package/dist/config/config-schema.d.ts +175 -0
- package/dist/config/config-schema.d.ts.map +1 -0
- package/dist/config/config-schema.js +49 -0
- package/dist/config/config-schema.js.map +1 -0
- package/dist/config/config-store.d.ts +24 -0
- package/dist/config/config-store.d.ts.map +1 -0
- package/dist/config/config-store.js +67 -0
- package/dist/config/config-store.js.map +1 -0
- package/dist/config/index.d.ts +5 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +3 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config.d.ts +25 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +73 -0
- package/dist/config.js.map +1 -0
- package/dist/core/errors.d.ts +9 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +13 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/index.d.ts +6 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +5 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/skill-content-cache.d.ts +18 -0
- package/dist/core/skill-content-cache.d.ts.map +1 -0
- package/dist/core/skill-content-cache.js +56 -0
- package/dist/core/skill-content-cache.js.map +1 -0
- package/dist/core/skill-metadata-cache.d.ts +15 -0
- package/dist/core/skill-metadata-cache.d.ts.map +1 -0
- package/dist/core/skill-metadata-cache.js +31 -0
- package/dist/core/skill-metadata-cache.js.map +1 -0
- package/dist/core/skill-registry.d.ts +12 -0
- package/dist/core/skill-registry.d.ts.map +1 -0
- package/dist/core/skill-registry.js +28 -0
- package/dist/core/skill-registry.js.map +1 -0
- package/dist/core/skill-resolver.d.ts +6 -0
- package/dist/core/skill-resolver.d.ts.map +1 -0
- package/dist/core/skill-resolver.js +32 -0
- package/dist/core/skill-resolver.js.map +1 -0
- package/dist/core/types.d.ts +80 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +10 -0
- package/dist/core/types.js.map +1 -0
- package/dist/decorators/base-decorator.d.ts +10 -0
- package/dist/decorators/base-decorator.d.ts.map +1 -0
- package/dist/decorators/base-decorator.js +13 -0
- package/dist/decorators/base-decorator.js.map +1 -0
- package/dist/decorators/cache-decorator.d.ts +33 -0
- package/dist/decorators/cache-decorator.d.ts.map +1 -0
- package/dist/decorators/cache-decorator.js +89 -0
- package/dist/decorators/cache-decorator.js.map +1 -0
- package/dist/decorators/decorator-chain.d.ts +16 -0
- package/dist/decorators/decorator-chain.d.ts.map +1 -0
- package/dist/decorators/decorator-chain.js +31 -0
- package/dist/decorators/decorator-chain.js.map +1 -0
- package/dist/decorators/index.d.ts +10 -0
- package/dist/decorators/index.d.ts.map +1 -0
- package/dist/decorators/index.js +6 -0
- package/dist/decorators/index.js.map +1 -0
- package/dist/decorators/logging-decorator.d.ts +15 -0
- package/dist/decorators/logging-decorator.d.ts.map +1 -0
- package/dist/decorators/logging-decorator.js +34 -0
- package/dist/decorators/logging-decorator.js.map +1 -0
- package/dist/decorators/timeout-decorator.d.ts +19 -0
- package/dist/decorators/timeout-decorator.d.ts.map +1 -0
- package/dist/decorators/timeout-decorator.js +59 -0
- package/dist/decorators/timeout-decorator.js.map +1 -0
- package/dist/factory/index.d.ts +2 -0
- package/dist/factory/index.d.ts.map +1 -0
- package/dist/factory/index.js +2 -0
- package/dist/factory/index.js.map +1 -0
- package/dist/factory/strategy-factory.d.ts +10 -0
- package/dist/factory/strategy-factory.d.ts.map +1 -0
- package/dist/factory/strategy-factory.js +37 -0
- package/dist/factory/strategy-factory.js.map +1 -0
- package/dist/handlers/composite-resolver.d.ts +34 -0
- package/dist/handlers/composite-resolver.d.ts.map +1 -0
- package/dist/handlers/composite-resolver.js +94 -0
- package/dist/handlers/composite-resolver.js.map +1 -0
- package/dist/handlers/hybrid-strategy.d.ts +14 -0
- package/dist/handlers/hybrid-strategy.d.ts.map +1 -0
- package/dist/handlers/hybrid-strategy.js +42 -0
- package/dist/handlers/hybrid-strategy.js.map +1 -0
- package/dist/handlers/index.d.ts +3 -0
- package/dist/handlers/index.d.ts.map +1 -0
- package/dist/handlers/index.js +2 -0
- package/dist/handlers/index.js.map +1 -0
- package/dist/handlers/invocation-strategy.d.ts +17 -0
- package/dist/handlers/invocation-strategy.d.ts.map +1 -0
- package/dist/handlers/invocation-strategy.js +2 -0
- package/dist/handlers/invocation-strategy.js.map +1 -0
- package/dist/handlers/prompt-strategy.d.ts +8 -0
- package/dist/handlers/prompt-strategy.d.ts.map +1 -0
- package/dist/handlers/prompt-strategy.js +31 -0
- package/dist/handlers/prompt-strategy.js.map +1 -0
- package/dist/handlers/script-strategy.d.ts +20 -0
- package/dist/handlers/script-strategy.d.ts.map +1 -0
- package/dist/handlers/script-strategy.js +87 -0
- package/dist/handlers/script-strategy.js.map +1 -0
- package/dist/installers/atomic-write.d.ts +13 -0
- package/dist/installers/atomic-write.d.ts.map +1 -0
- package/dist/installers/atomic-write.js +98 -0
- package/dist/installers/atomic-write.js.map +1 -0
- package/dist/installers/claude-installer.d.ts +26 -0
- package/dist/installers/claude-installer.d.ts.map +1 -0
- package/dist/installers/claude-installer.js +118 -0
- package/dist/installers/claude-installer.js.map +1 -0
- package/dist/installers/codex-installer.d.ts +30 -0
- package/dist/installers/codex-installer.d.ts.map +1 -0
- package/dist/installers/codex-installer.js +125 -0
- package/dist/installers/codex-installer.js.map +1 -0
- package/dist/installers/cursor-installer.d.ts +29 -0
- package/dist/installers/cursor-installer.d.ts.map +1 -0
- package/dist/installers/cursor-installer.js +126 -0
- package/dist/installers/cursor-installer.js.map +1 -0
- package/dist/installers/paths.d.ts +20 -0
- package/dist/installers/paths.d.ts.map +1 -0
- package/dist/installers/paths.js +50 -0
- package/dist/installers/paths.js.map +1 -0
- package/dist/installers/registry.d.ts +8 -0
- package/dist/installers/registry.d.ts.map +1 -0
- package/dist/installers/registry.js +18 -0
- package/dist/installers/registry.js.map +1 -0
- package/dist/installers/types.d.ts +45 -0
- package/dist/installers/types.d.ts.map +1 -0
- package/dist/installers/types.js +9 -0
- package/dist/installers/types.js.map +1 -0
- package/dist/parser/file-scanner.d.ts +10 -0
- package/dist/parser/file-scanner.d.ts.map +1 -0
- package/dist/parser/file-scanner.js +37 -0
- package/dist/parser/file-scanner.js.map +1 -0
- package/dist/parser/format-detector.d.ts +11 -0
- package/dist/parser/format-detector.d.ts.map +1 -0
- package/dist/parser/format-detector.js +13 -0
- package/dist/parser/format-detector.js.map +1 -0
- package/dist/parser/frontmatter-parser.d.ts +14 -0
- package/dist/parser/frontmatter-parser.d.ts.map +1 -0
- package/dist/parser/frontmatter-parser.js +98 -0
- package/dist/parser/frontmatter-parser.js.map +1 -0
- package/dist/parser/index.d.ts +4 -0
- package/dist/parser/index.d.ts.map +1 -0
- package/dist/parser/index.js +4 -0
- package/dist/parser/index.js.map +1 -0
- package/dist/parser/scripts-dir-detector.d.ts +7 -0
- package/dist/parser/scripts-dir-detector.d.ts.map +1 -0
- package/dist/parser/scripts-dir-detector.js +17 -0
- package/dist/parser/scripts-dir-detector.js.map +1 -0
- package/dist/security/blacklist-filter.d.ts +32 -0
- package/dist/security/blacklist-filter.d.ts.map +1 -0
- package/dist/security/blacklist-filter.js +35 -0
- package/dist/security/blacklist-filter.js.map +1 -0
- package/dist/security/index.d.ts +5 -0
- package/dist/security/index.d.ts.map +1 -0
- package/dist/security/index.js +3 -0
- package/dist/security/index.js.map +1 -0
- package/dist/security/pattern-scanner.d.ts +27 -0
- package/dist/security/pattern-scanner.d.ts.map +1 -0
- package/dist/security/pattern-scanner.js +46 -0
- package/dist/security/pattern-scanner.js.map +1 -0
- package/dist/security/sandbox-runner.d.ts +48 -0
- package/dist/security/sandbox-runner.d.ts.map +1 -0
- package/dist/security/sandbox-runner.js +131 -0
- package/dist/security/sandbox-runner.js.map +1 -0
- package/dist/server-deps.d.ts +28 -0
- package/dist/server-deps.d.ts.map +1 -0
- package/dist/server-deps.js +2 -0
- package/dist/server-deps.js.map +1 -0
- package/dist/server.d.ts +12 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +174 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/configure.d.ts +22 -0
- package/dist/tools/configure.d.ts.map +1 -0
- package/dist/tools/configure.js +126 -0
- package/dist/tools/configure.js.map +1 -0
- package/dist/tools/get.d.ts +10 -0
- package/dist/tools/get.d.ts.map +1 -0
- package/dist/tools/get.js +20 -0
- package/dist/tools/get.js.map +1 -0
- package/dist/tools/index.d.ts +9 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +7 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/invoke.d.ts +12 -0
- package/dist/tools/invoke.d.ts.map +1 -0
- package/dist/tools/invoke.js +36 -0
- package/dist/tools/invoke.js.map +1 -0
- package/dist/tools/list.d.ts +16 -0
- package/dist/tools/list.d.ts.map +1 -0
- package/dist/tools/list.js +33 -0
- package/dist/tools/list.js.map +1 -0
- package/dist/tools/loader.d.ts +30 -0
- package/dist/tools/loader.d.ts.map +1 -0
- package/dist/tools/loader.js +92 -0
- package/dist/tools/loader.js.map +1 -0
- package/dist/tools/reload.d.ts +22 -0
- package/dist/tools/reload.d.ts.map +1 -0
- package/dist/tools/reload.js +39 -0
- package/dist/tools/reload.js.map +1 -0
- package/dist/watcher/chokidar-types.d.ts +20 -0
- package/dist/watcher/chokidar-types.d.ts.map +1 -0
- package/dist/watcher/chokidar-types.js +2 -0
- package/dist/watcher/chokidar-types.js.map +1 -0
- package/dist/watcher/folder-watcher.d.ts +27 -0
- package/dist/watcher/folder-watcher.d.ts.map +1 -0
- package/dist/watcher/folder-watcher.js +123 -0
- package/dist/watcher/folder-watcher.js.map +1 -0
- package/dist/watcher/index.d.ts +4 -0
- package/dist/watcher/index.d.ts.map +1 -0
- package/dist/watcher/index.js +2 -0
- package/dist/watcher/index.js.map +1 -0
- package/manifest.json +96 -0
- package/package.json +78 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import type { Logger } from '../decorators/logging-decorator.js';
|
|
3
|
+
export interface SandboxRunOptions {
|
|
4
|
+
/** Additional env vars overlaid ON TOP of the whitelist (e.g. SKILLFORGE_INPUT=...).
|
|
5
|
+
* These keys are merged into the env whitelist. */
|
|
6
|
+
env?: Record<string, string>;
|
|
7
|
+
/** AbortSignal from TimeoutDecorator. On abort: SIGTERM → 5s grace → SIGKILL. */
|
|
8
|
+
signal?: AbortSignal;
|
|
9
|
+
/** README signal field — NOT enforced at sandbox level. Node child_process
|
|
10
|
+
* cannot disable network egress. Pass-through for skill author awareness. */
|
|
11
|
+
allowNetwork?: boolean;
|
|
12
|
+
}
|
|
13
|
+
export interface SandboxResult {
|
|
14
|
+
exitCode: number | null;
|
|
15
|
+
stdout: string;
|
|
16
|
+
stderr: string;
|
|
17
|
+
timedOut: boolean;
|
|
18
|
+
durationMs: number;
|
|
19
|
+
}
|
|
20
|
+
export interface SandboxRunnerDeps {
|
|
21
|
+
logger?: Logger;
|
|
22
|
+
/** Injectable spawn for testing. Defaults to node:child_process spawn. */
|
|
23
|
+
spawnFn?: typeof spawn;
|
|
24
|
+
/** Injectable clock for testing. Defaults to performance.now. */
|
|
25
|
+
clock?: () => number;
|
|
26
|
+
/** Injectable tmpdir resolver for testing. Defaults to os.tmpdir. */
|
|
27
|
+
tmpdir?: () => string;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Spawns a subprocess with env whitelist + temp cwd isolation.
|
|
31
|
+
*
|
|
32
|
+
* Hard-enforced (Node child_process can guarantee):
|
|
33
|
+
* - env: only PATH + opts.env overrides. No ~/.ssh / ~/.aws / USER env propagation.
|
|
34
|
+
* - cwd: fresh fs.mkdtemp(os.tmpdir()/skillforge-xxxxxx/), recursive cleanup on exit.
|
|
35
|
+
*
|
|
36
|
+
* NOT enforced (Node child_process limitation):
|
|
37
|
+
* - Network egress: subprocess inherits host network stack.
|
|
38
|
+
* - Filesystem reads outside cwd: subprocess has OS-user permissions.
|
|
39
|
+
* - CPU / memory limits.
|
|
40
|
+
*
|
|
41
|
+
* Abort handling: opts.signal.aborted → SIGTERM → 5s grace → SIGKILL.
|
|
42
|
+
*/
|
|
43
|
+
export declare class SandboxRunner {
|
|
44
|
+
#private;
|
|
45
|
+
constructor(deps?: SandboxRunnerDeps);
|
|
46
|
+
run(cmd: string, args: readonly string[], opts?: SandboxRunOptions): Promise<SandboxResult>;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=sandbox-runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox-runner.d.ts","sourceRoot":"","sources":["../../src/security/sandbox-runner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAK3C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oCAAoC,CAAC;AAMjE,MAAM,WAAW,iBAAiB;IAChC;wDACoD;IACpD,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,iFAAiF;IACjF,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;kFAC8E;IAC9E,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0EAA0E;IAC1E,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;IACvB,iEAAiE;IACjE,KAAK,CAAC,EAAE,MAAM,MAAM,CAAC;IACrB,qEAAqE;IACrE,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC;CACvB;AAmBD;;;;;;;;;;;;;GAaG;AACH,qBAAa,aAAa;;gBAMZ,IAAI,GAAE,iBAAsB;IAOlC,GAAG,CACP,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,IAAI,GAAE,iBAAsB,GAC3B,OAAO,CAAC,aAAa,CAAC;CAoF1B"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import { promises as fs } from 'node:fs';
|
|
3
|
+
import * as os from 'node:os';
|
|
4
|
+
import * as path from 'node:path';
|
|
5
|
+
import { performance } from 'node:perf_hooks';
|
|
6
|
+
const STDOUT_TAIL_LIMIT = 1_000_000; // 1 MB
|
|
7
|
+
const STDERR_TAIL_LIMIT = 1_000_000;
|
|
8
|
+
const SIGTERM_GRACE_MS = 5_000;
|
|
9
|
+
// On Windows, restricting PATH to POSIX-only breaks subprocess discovery
|
|
10
|
+
// (node/python resolved via %PATH%). On Windows we pass through process.env.PATH.
|
|
11
|
+
// On POSIX we use a minimal whitelist to prevent env leakage.
|
|
12
|
+
const DEFAULT_PATH = process.platform === 'win32'
|
|
13
|
+
? (process.env.PATH ?? '')
|
|
14
|
+
: '/usr/bin:/bin';
|
|
15
|
+
function buildEnv(overrides) {
|
|
16
|
+
const base = { PATH: DEFAULT_PATH };
|
|
17
|
+
if (overrides) {
|
|
18
|
+
for (const [k, v] of Object.entries(overrides)) {
|
|
19
|
+
base[k] = v;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return base;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Spawns a subprocess with env whitelist + temp cwd isolation.
|
|
26
|
+
*
|
|
27
|
+
* Hard-enforced (Node child_process can guarantee):
|
|
28
|
+
* - env: only PATH + opts.env overrides. No ~/.ssh / ~/.aws / USER env propagation.
|
|
29
|
+
* - cwd: fresh fs.mkdtemp(os.tmpdir()/skillforge-xxxxxx/), recursive cleanup on exit.
|
|
30
|
+
*
|
|
31
|
+
* NOT enforced (Node child_process limitation):
|
|
32
|
+
* - Network egress: subprocess inherits host network stack.
|
|
33
|
+
* - Filesystem reads outside cwd: subprocess has OS-user permissions.
|
|
34
|
+
* - CPU / memory limits.
|
|
35
|
+
*
|
|
36
|
+
* Abort handling: opts.signal.aborted → SIGTERM → 5s grace → SIGKILL.
|
|
37
|
+
*/
|
|
38
|
+
export class SandboxRunner {
|
|
39
|
+
#logger;
|
|
40
|
+
#spawn;
|
|
41
|
+
#clock;
|
|
42
|
+
#tmpdir;
|
|
43
|
+
constructor(deps = {}) {
|
|
44
|
+
this.#logger = deps.logger;
|
|
45
|
+
this.#spawn = deps.spawnFn ?? spawn;
|
|
46
|
+
this.#clock = deps.clock ?? (() => performance.now());
|
|
47
|
+
this.#tmpdir = deps.tmpdir ?? (() => os.tmpdir());
|
|
48
|
+
}
|
|
49
|
+
async run(cmd, args, opts = {}) {
|
|
50
|
+
const start = this.#clock();
|
|
51
|
+
const tmpDir = await fs.mkdtemp(path.join(this.#tmpdir(), 'skillforge-'));
|
|
52
|
+
try {
|
|
53
|
+
return await this.#runInDir(cmd, args, opts, tmpDir, start);
|
|
54
|
+
}
|
|
55
|
+
finally {
|
|
56
|
+
// Cleanup must happen even if abort raced.
|
|
57
|
+
// fs.rm with force+recursive swallows ENOENT.
|
|
58
|
+
await fs.rm(tmpDir, { recursive: true, force: true }).catch((err) => {
|
|
59
|
+
this.#logger?.warn(`[skillforge] sandbox cleanup failed dir=${tmpDir} err=${err.message}`);
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
async #runInDir(cmd, args, opts, tmpDir, start) {
|
|
64
|
+
return new Promise((resolve, reject) => {
|
|
65
|
+
const child = this.#spawn(cmd, args, {
|
|
66
|
+
cwd: tmpDir,
|
|
67
|
+
env: buildEnv(opts.env),
|
|
68
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
69
|
+
});
|
|
70
|
+
let stdoutLen = 0;
|
|
71
|
+
let stderrLen = 0;
|
|
72
|
+
const stdoutChunks = [];
|
|
73
|
+
const stderrChunks = [];
|
|
74
|
+
let timedOut = false;
|
|
75
|
+
let sigkillTimer;
|
|
76
|
+
const onAbort = () => {
|
|
77
|
+
timedOut = true;
|
|
78
|
+
try {
|
|
79
|
+
child.kill('SIGTERM');
|
|
80
|
+
}
|
|
81
|
+
catch { /* ignore */ }
|
|
82
|
+
sigkillTimer = setTimeout(() => {
|
|
83
|
+
try {
|
|
84
|
+
child.kill('SIGKILL');
|
|
85
|
+
}
|
|
86
|
+
catch { /* ignore */ }
|
|
87
|
+
}, SIGTERM_GRACE_MS);
|
|
88
|
+
if (sigkillTimer.unref)
|
|
89
|
+
sigkillTimer.unref();
|
|
90
|
+
};
|
|
91
|
+
if (opts.signal) {
|
|
92
|
+
if (opts.signal.aborted) {
|
|
93
|
+
onAbort();
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
opts.signal.addEventListener('abort', onAbort, { once: true });
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
child.stdout?.on('data', (chunk) => {
|
|
100
|
+
if (stdoutLen < STDOUT_TAIL_LIMIT) {
|
|
101
|
+
stdoutChunks.push(chunk);
|
|
102
|
+
stdoutLen += chunk.length;
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
child.stderr?.on('data', (chunk) => {
|
|
106
|
+
if (stderrLen < STDERR_TAIL_LIMIT) {
|
|
107
|
+
stderrChunks.push(chunk);
|
|
108
|
+
stderrLen += chunk.length;
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
child.on('error', (err) => {
|
|
112
|
+
if (sigkillTimer)
|
|
113
|
+
clearTimeout(sigkillTimer);
|
|
114
|
+
if (opts.signal)
|
|
115
|
+
opts.signal.removeEventListener('abort', onAbort);
|
|
116
|
+
reject(err);
|
|
117
|
+
});
|
|
118
|
+
child.on('close', (exitCode) => {
|
|
119
|
+
if (sigkillTimer)
|
|
120
|
+
clearTimeout(sigkillTimer);
|
|
121
|
+
if (opts.signal)
|
|
122
|
+
opts.signal.removeEventListener('abort', onAbort);
|
|
123
|
+
const stdout = Buffer.concat(stdoutChunks).subarray(0, STDOUT_TAIL_LIMIT).toString('utf8');
|
|
124
|
+
const stderr = Buffer.concat(stderrChunks).subarray(0, STDERR_TAIL_LIMIT).toString('utf8');
|
|
125
|
+
const durationMs = Math.round(this.#clock() - start);
|
|
126
|
+
resolve({ exitCode, stdout, stderr, timedOut, durationMs });
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=sandbox-runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox-runner.js","sourceRoot":"","sources":["../../src/security/sandbox-runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { SkillRegistry, SkillResolver, SkillMetadataCache, SkillContentCache } from './core/index.js';
|
|
2
|
+
import type { FrontmatterParser, FileScanner } from './parser/index.js';
|
|
3
|
+
import type { StrategyFactory } from './factory/index.js';
|
|
4
|
+
import type { BlacklistFilter } from './security/index.js';
|
|
5
|
+
import type { ConfigStore } from './config/index.js';
|
|
6
|
+
import type { FolderWatcher } from './watcher/index.js';
|
|
7
|
+
import type { Logger } from './decorators/index.js';
|
|
8
|
+
import type { SandboxRunner } from './security/sandbox-runner.js';
|
|
9
|
+
import type { DecoratorChain } from './decorators/index.js';
|
|
10
|
+
export interface ServerDeps {
|
|
11
|
+
/** Mutable in-place: configure tool replaces contents via splice. The loader
|
|
12
|
+
* re-reads on every ensureRegistryFresh call, so swap-in-place propagates. */
|
|
13
|
+
folders: string[];
|
|
14
|
+
configStore: ConfigStore;
|
|
15
|
+
registry: SkillRegistry;
|
|
16
|
+
resolver: SkillResolver;
|
|
17
|
+
metadataCache: SkillMetadataCache;
|
|
18
|
+
contentCache: SkillContentCache;
|
|
19
|
+
scanner: FileScanner;
|
|
20
|
+
parser: FrontmatterParser;
|
|
21
|
+
factory: StrategyFactory;
|
|
22
|
+
blacklistFilter: BlacklistFilter;
|
|
23
|
+
folderWatcher: FolderWatcher;
|
|
24
|
+
logger: Logger;
|
|
25
|
+
sandboxRunner: SandboxRunner;
|
|
26
|
+
decoratorChain: DecoratorChain;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=server-deps.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server-deps.d.ts","sourceRoot":"","sources":["../src/server-deps.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAC3G,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACxE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,MAAM,WAAW,UAAU;IACzB;mFAC+E;IAC/E,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,EAAE,WAAW,CAAC;IACzB,QAAQ,EAAE,aAAa,CAAC;IACxB,QAAQ,EAAE,aAAa,CAAC;IACxB,aAAa,EAAE,kBAAkB,CAAC;IAClC,YAAY,EAAE,iBAAiB,CAAC;IAChC,OAAO,EAAE,WAAW,CAAC;IACrB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,OAAO,EAAE,eAAe,CAAC;IACzB,eAAe,EAAE,eAAe,CAAC;IACjC,aAAa,EAAE,aAAa,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,aAAa,CAAC;IAC7B,cAAc,EAAE,cAAc,CAAC;CAChC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server-deps.js","sourceRoot":"","sources":["../src/server-deps.ts"],"names":[],"mappings":""}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* SkillForge MCP — stdio entry point.
|
|
4
|
+
*
|
|
5
|
+
* buildServer() and buildDeps() are exported for integration tests so the
|
|
6
|
+
* same wiring is exercised in-process without spawning a subprocess.
|
|
7
|
+
*/
|
|
8
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
9
|
+
import type { ServerDeps } from './server-deps.js';
|
|
10
|
+
export declare function buildServer(deps: ServerDeps): McpServer;
|
|
11
|
+
export declare function buildDeps(): Promise<ServerDeps>;
|
|
12
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":";AACA;;;;;GAKG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAmBpE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAcnD,wBAAgB,WAAW,CAAC,IAAI,EAAE,UAAU,GAAG,SAAS,CAgGvD;AAED,wBAAsB,SAAS,IAAI,OAAO,CAAC,UAAU,CAAC,CA2DrD"}
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* SkillForge MCP — stdio entry point.
|
|
4
|
+
*
|
|
5
|
+
* buildServer() and buildDeps() are exported for integration tests so the
|
|
6
|
+
* same wiring is exercised in-process without spawning a subprocess.
|
|
7
|
+
*/
|
|
8
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
9
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
10
|
+
import { loadResolvedConfig, buildPatternScanner } from './config.js';
|
|
11
|
+
import { ConfigStore, defaultConfigPath } from './config/index.js';
|
|
12
|
+
import { FolderWatcher } from './watcher/index.js';
|
|
13
|
+
import { SkillRegistry, SkillResolver, SkillMetadataCache, SkillContentCache, } from './core/index.js';
|
|
14
|
+
import { FrontmatterParser, FileScanner } from './parser/index.js';
|
|
15
|
+
import { PromptStrategy } from './handlers/index.js';
|
|
16
|
+
import { ScriptStrategy } from './handlers/script-strategy.js';
|
|
17
|
+
import { HybridStrategy } from './handlers/hybrid-strategy.js';
|
|
18
|
+
import { StrategyFactory } from './factory/index.js';
|
|
19
|
+
import { BlacklistFilter } from './security/index.js';
|
|
20
|
+
import { SandboxRunner } from './security/sandbox-runner.js';
|
|
21
|
+
import { DecoratorChain, stderrLogger } from './decorators/index.js';
|
|
22
|
+
import { listInputSchema, getInputSchema, invokeInputSchema, configureInputSchema, reloadInputSchema, handleList, handleGet, handleInvoke, handleConfigure, handleReload, } from './tools/index.js';
|
|
23
|
+
export function buildServer(deps) {
|
|
24
|
+
const server = new McpServer({ name: 'skillforge-mcp', version: '0.1.0' });
|
|
25
|
+
server.registerTool('skills__list', {
|
|
26
|
+
title: 'List skills',
|
|
27
|
+
description: 'List available skills, optionally filtered by folder / search / source.',
|
|
28
|
+
inputSchema: listInputSchema,
|
|
29
|
+
}, async (args) => {
|
|
30
|
+
try {
|
|
31
|
+
const result = await handleList(deps, args);
|
|
32
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
36
|
+
return { content: [{ type: 'text', text: message }], isError: true };
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
server.registerTool('skills__get', {
|
|
40
|
+
title: 'Get skill',
|
|
41
|
+
description: 'Retrieve the full content (body + metadata) of a named skill.',
|
|
42
|
+
inputSchema: getInputSchema,
|
|
43
|
+
}, async (args) => {
|
|
44
|
+
try {
|
|
45
|
+
const result = await handleGet(deps, args);
|
|
46
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
47
|
+
}
|
|
48
|
+
catch (err) {
|
|
49
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
50
|
+
return { content: [{ type: 'text', text: message }], isError: true };
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
server.registerTool('skills__invoke', {
|
|
54
|
+
title: 'Invoke skill',
|
|
55
|
+
description: 'Invoke a skill by name, forwarding optional input to the strategy.',
|
|
56
|
+
inputSchema: invokeInputSchema,
|
|
57
|
+
}, async (args) => {
|
|
58
|
+
try {
|
|
59
|
+
const result = await handleInvoke(deps, args);
|
|
60
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
61
|
+
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
64
|
+
return { content: [{ type: 'text', text: message }], isError: true };
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
server.registerTool('skills__configure', {
|
|
68
|
+
title: 'Configure SkillForge',
|
|
69
|
+
description: 'Manage configured skill folders, blacklist, and reset to defaults. Mutates persisted config under defaultConfigPath().',
|
|
70
|
+
inputSchema: configureInputSchema,
|
|
71
|
+
}, async (args) => {
|
|
72
|
+
try {
|
|
73
|
+
const result = await handleConfigure(deps, args);
|
|
74
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
75
|
+
}
|
|
76
|
+
catch (err) {
|
|
77
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
78
|
+
return { content: [{ type: 'text', text: message }], isError: true };
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
server.registerTool('skills__reload', {
|
|
82
|
+
title: 'Reload skills',
|
|
83
|
+
description: 'Force a full rescan of all configured folders, returning the diff (added/removed) and any per-file errors. Pass an optional folder name to validate it is currently configured (the rescan itself remains global).',
|
|
84
|
+
inputSchema: reloadInputSchema,
|
|
85
|
+
}, async (args) => {
|
|
86
|
+
try {
|
|
87
|
+
const result = await handleReload(deps, args);
|
|
88
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
89
|
+
}
|
|
90
|
+
catch (err) {
|
|
91
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
92
|
+
return { content: [{ type: 'text', text: message }], isError: true };
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
return server;
|
|
96
|
+
}
|
|
97
|
+
export async function buildDeps() {
|
|
98
|
+
const configStore = new ConfigStore({ filePath: defaultConfigPath() });
|
|
99
|
+
const resolved = await loadResolvedConfig(process.env, configStore);
|
|
100
|
+
const scanner = buildPatternScanner(resolved.persisted);
|
|
101
|
+
const blacklistFilter = new BlacklistFilter({
|
|
102
|
+
manualBlacklist: resolved.persisted.blacklist,
|
|
103
|
+
patternScanner: scanner,
|
|
104
|
+
});
|
|
105
|
+
const metadataCache = new SkillMetadataCache({ ttlMs: resolved.ttlMs });
|
|
106
|
+
const folderWatcher = new FolderWatcher({
|
|
107
|
+
folders: resolved.folders,
|
|
108
|
+
debounceMs: resolved.persisted.watcher.debounceMs,
|
|
109
|
+
onBatch: () => metadataCache.invalidate(),
|
|
110
|
+
});
|
|
111
|
+
const logger = stderrLogger;
|
|
112
|
+
const sandboxRunner = new SandboxRunner({ logger });
|
|
113
|
+
// allowScripts flag captured from initial config load. A ref object is used
|
|
114
|
+
// so tools/configure can update it by calling configStore.load() indirectly.
|
|
115
|
+
// For the current scope this snapshot approach is sufficient — a restart or reload
|
|
116
|
+
// will pick up the latest value from disk via the tools/reload path.
|
|
117
|
+
const securityRef = { allowScripts: resolved.persisted.security.allowScripts };
|
|
118
|
+
const scriptStrategy = new ScriptStrategy({
|
|
119
|
+
sandboxRunner,
|
|
120
|
+
isGloballyAllowed: () => securityRef.allowScripts === true,
|
|
121
|
+
logger,
|
|
122
|
+
});
|
|
123
|
+
const hybridStrategy = new HybridStrategy({ scriptStrategy });
|
|
124
|
+
const factory = new StrategyFactory([
|
|
125
|
+
hybridStrategy,
|
|
126
|
+
scriptStrategy,
|
|
127
|
+
new PromptStrategy(),
|
|
128
|
+
]);
|
|
129
|
+
const invocation = resolved.persisted.invocation;
|
|
130
|
+
const decoratorChain = new DecoratorChain({
|
|
131
|
+
logger,
|
|
132
|
+
defaultTimeoutMs: invocation.defaultTimeoutMs,
|
|
133
|
+
cacheTtlMs: invocation.cacheTtlMs,
|
|
134
|
+
cacheMaxEntries: invocation.cacheMaxEntries,
|
|
135
|
+
});
|
|
136
|
+
return {
|
|
137
|
+
folders: resolved.folders,
|
|
138
|
+
configStore,
|
|
139
|
+
registry: new SkillRegistry(),
|
|
140
|
+
resolver: new SkillResolver(),
|
|
141
|
+
metadataCache,
|
|
142
|
+
contentCache: new SkillContentCache({ ttlMs: resolved.ttlMs }),
|
|
143
|
+
parser: new FrontmatterParser(),
|
|
144
|
+
scanner: new FileScanner(),
|
|
145
|
+
factory,
|
|
146
|
+
blacklistFilter,
|
|
147
|
+
folderWatcher,
|
|
148
|
+
logger,
|
|
149
|
+
sandboxRunner,
|
|
150
|
+
decoratorChain,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
async function main() {
|
|
154
|
+
const deps = await buildDeps();
|
|
155
|
+
const server = buildServer(deps);
|
|
156
|
+
await server.connect(new StdioServerTransport());
|
|
157
|
+
await deps.folderWatcher.start();
|
|
158
|
+
const shutdown = async () => {
|
|
159
|
+
await deps.folderWatcher.stop();
|
|
160
|
+
};
|
|
161
|
+
process.once('SIGTERM', () => { void shutdown(); });
|
|
162
|
+
process.once('SIGINT', () => { void shutdown(); });
|
|
163
|
+
}
|
|
164
|
+
// Only run main() when invoked directly, not when imported by tests.
|
|
165
|
+
// This is the canonical ESM "is this the entry point?" check.
|
|
166
|
+
import { fileURLToPath } from 'node:url';
|
|
167
|
+
const isDirectRun = process.argv[1] !== undefined && fileURLToPath(import.meta.url) === process.argv[1];
|
|
168
|
+
if (isDirectRun) {
|
|
169
|
+
main().catch((err) => {
|
|
170
|
+
console.error('[skillforge] fatal:', err);
|
|
171
|
+
process.exit(1);
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { ServerDeps } from '../server-deps.js';
|
|
3
|
+
export declare const configureInputSchema: {
|
|
4
|
+
readonly action: z.ZodEnum<["add_folder", "remove_folder", "list_folders", "set_blacklist", "get_blacklist", "reset"]>;
|
|
5
|
+
readonly folder: z.ZodOptional<z.ZodString>;
|
|
6
|
+
readonly blacklist: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
7
|
+
};
|
|
8
|
+
export type ConfigureAction = 'add_folder' | 'remove_folder' | 'list_folders' | 'set_blacklist' | 'get_blacklist' | 'reset';
|
|
9
|
+
export interface ConfigureResult {
|
|
10
|
+
/** Currently active resolved folders (post-action). */
|
|
11
|
+
folders: string[];
|
|
12
|
+
/** Currently active manual blacklist (post-action). */
|
|
13
|
+
blacklist: string[];
|
|
14
|
+
/** Skills visible in the registry after the action took effect. */
|
|
15
|
+
totalSkills: number;
|
|
16
|
+
}
|
|
17
|
+
export declare function handleConfigure(deps: ServerDeps, args: {
|
|
18
|
+
action: ConfigureAction;
|
|
19
|
+
folder?: string;
|
|
20
|
+
blacklist?: string[];
|
|
21
|
+
}): Promise<ConfigureResult>;
|
|
22
|
+
//# sourceMappingURL=configure.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configure.d.ts","sourceRoot":"","sources":["../../src/tools/configure.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAMpD,eAAO,MAAM,oBAAoB;;;;CAWvB,CAAC;AAEX,MAAM,MAAM,eAAe,GACvB,YAAY,GACZ,eAAe,GACf,cAAc,GACd,eAAe,GACf,eAAe,GACf,OAAO,CAAC;AAEZ,MAAM,WAAW,eAAe;IAC9B,uDAAuD;IACvD,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,uDAAuD;IACvD,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,mEAAmE;IACnE,WAAW,EAAE,MAAM,CAAC;CACrB;AAmBD,wBAAsB,eAAe,CACnC,IAAI,EAAE,UAAU,EAChB,IAAI,EAAE;IAAE,MAAM,EAAE,eAAe,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,GACvE,OAAO,CAAC,eAAe,CAAC,CAgG1B"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { resolve } from 'node:path';
|
|
3
|
+
import { defaultConfig } from '../config/index.js';
|
|
4
|
+
import { loadResolvedConfig } from '../config.js';
|
|
5
|
+
import { ensureRegistryFresh } from './loader.js';
|
|
6
|
+
export const configureInputSchema = {
|
|
7
|
+
action: z.enum([
|
|
8
|
+
'add_folder',
|
|
9
|
+
'remove_folder',
|
|
10
|
+
'list_folders',
|
|
11
|
+
'set_blacklist',
|
|
12
|
+
'get_blacklist',
|
|
13
|
+
'reset',
|
|
14
|
+
]),
|
|
15
|
+
folder: z.string().optional(),
|
|
16
|
+
blacklist: z.array(z.string()).optional(),
|
|
17
|
+
};
|
|
18
|
+
/** Recompute resolved folders from env + persisted config, then splice deps.folders in place. */
|
|
19
|
+
async function reconcileFolders(deps) {
|
|
20
|
+
const persisted = await deps.configStore.load();
|
|
21
|
+
const resolved = await loadResolvedConfig(process.env, deps.configStore);
|
|
22
|
+
// Splice in-place so all references to deps.folders see the new list.
|
|
23
|
+
deps.folders.splice(0, deps.folders.length, ...resolved.folders);
|
|
24
|
+
deps.blacklistFilter.setManualBlacklist(persisted.blacklist);
|
|
25
|
+
deps.metadataCache.invalidate();
|
|
26
|
+
try {
|
|
27
|
+
await deps.folderWatcher.setFolders(deps.folders);
|
|
28
|
+
}
|
|
29
|
+
catch (err) {
|
|
30
|
+
console.error(`[skillforge:configure] watcher setFolders failed: ${String(err)}`);
|
|
31
|
+
}
|
|
32
|
+
await ensureRegistryFresh(deps);
|
|
33
|
+
return persisted;
|
|
34
|
+
}
|
|
35
|
+
export async function handleConfigure(deps, args) {
|
|
36
|
+
const { action } = args;
|
|
37
|
+
try {
|
|
38
|
+
if (action === 'list_folders') {
|
|
39
|
+
const persisted = await deps.configStore.load();
|
|
40
|
+
return {
|
|
41
|
+
folders: [...deps.folders],
|
|
42
|
+
blacklist: persisted.blacklist,
|
|
43
|
+
totalSkills: deps.registry.size,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
if (action === 'get_blacklist') {
|
|
47
|
+
const persisted = await deps.configStore.load();
|
|
48
|
+
return {
|
|
49
|
+
folders: [...deps.folders],
|
|
50
|
+
blacklist: persisted.blacklist,
|
|
51
|
+
totalSkills: deps.registry.size,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
if (action === 'add_folder') {
|
|
55
|
+
if (args.folder === undefined) {
|
|
56
|
+
throw new Error(`configure: action "add_folder" requires "folder"`);
|
|
57
|
+
}
|
|
58
|
+
if (args.folder.trim().length === 0) {
|
|
59
|
+
throw new Error('configure: folder path must not be empty');
|
|
60
|
+
}
|
|
61
|
+
const absPath = resolve(args.folder);
|
|
62
|
+
const persisted = await deps.configStore.load();
|
|
63
|
+
const alreadyPresent = persisted.folders.some((f) => resolve(f.path) === absPath);
|
|
64
|
+
if (!alreadyPresent) {
|
|
65
|
+
persisted.folders.push({ path: absPath, priority: 100, enabled: true, tags: [] });
|
|
66
|
+
}
|
|
67
|
+
// Why: always save even on no-op — simpler than branching, atomic write is cheap.
|
|
68
|
+
await deps.configStore.save(persisted);
|
|
69
|
+
const finalPersisted = await reconcileFolders(deps);
|
|
70
|
+
return {
|
|
71
|
+
folders: [...deps.folders],
|
|
72
|
+
blacklist: finalPersisted.blacklist,
|
|
73
|
+
totalSkills: deps.registry.size,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
if (action === 'remove_folder') {
|
|
77
|
+
if (args.folder === undefined) {
|
|
78
|
+
throw new Error(`configure: action "remove_folder" requires "folder"`);
|
|
79
|
+
}
|
|
80
|
+
const absPath = resolve(args.folder);
|
|
81
|
+
const persisted = await deps.configStore.load();
|
|
82
|
+
persisted.folders = persisted.folders.filter((f) => resolve(f.path) !== absPath);
|
|
83
|
+
await deps.configStore.save(persisted);
|
|
84
|
+
const finalPersisted = await reconcileFolders(deps);
|
|
85
|
+
return {
|
|
86
|
+
folders: [...deps.folders],
|
|
87
|
+
blacklist: finalPersisted.blacklist,
|
|
88
|
+
totalSkills: deps.registry.size,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
if (action === 'set_blacklist') {
|
|
92
|
+
if (args.blacklist === undefined) {
|
|
93
|
+
throw new Error(`configure: action "set_blacklist" requires "blacklist"`);
|
|
94
|
+
}
|
|
95
|
+
const persisted = await deps.configStore.load();
|
|
96
|
+
persisted.blacklist = args.blacklist;
|
|
97
|
+
await deps.configStore.save(persisted);
|
|
98
|
+
const finalPersisted = await reconcileFolders(deps);
|
|
99
|
+
return {
|
|
100
|
+
folders: [...deps.folders],
|
|
101
|
+
blacklist: finalPersisted.blacklist,
|
|
102
|
+
totalSkills: deps.registry.size,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
if (action === 'reset') {
|
|
106
|
+
const fresh = defaultConfig();
|
|
107
|
+
await deps.configStore.save(fresh);
|
|
108
|
+
const finalPersisted = await reconcileFolders(deps);
|
|
109
|
+
return {
|
|
110
|
+
folders: [...deps.folders],
|
|
111
|
+
blacklist: finalPersisted.blacklist,
|
|
112
|
+
totalSkills: deps.registry.size,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
throw new Error(`configure: unknown action "${action}"`);
|
|
116
|
+
}
|
|
117
|
+
catch (err) {
|
|
118
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
119
|
+
// Avoid double-prefixing if error already has the action prefix.
|
|
120
|
+
if (msg.startsWith(`configure(${action}):`) || msg.startsWith('configure: ')) {
|
|
121
|
+
throw err;
|
|
122
|
+
}
|
|
123
|
+
throw new Error(`configure(${action}): ${msg}`);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=configure.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configure.js","sourceRoot":"","sources":["../../src/tools/configure.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAElD,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC;QACb,YAAY;QACZ,eAAe;QACf,cAAc;QACd,eAAe;QACf,eAAe;QACf,OAAO;KACR,CAAC;IACF,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC7B,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;CACjC,CAAC;AAmBX,iGAAiG;AACjG,KAAK,UAAU,gBAAgB,CAAC,IAAgB;IAC9C,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;IAChD,MAAM,QAAQ,GAAG,MAAM,kBAAkB,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IACzE,sEAAsE;IACtE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;IACjE,IAAI,CAAC,eAAe,CAAC,kBAAkB,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7D,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE,CAAC;IAChC,IAAI,CAAC;QACH,MAAM,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACpD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,qDAAqD,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACpF,CAAC;IACD,MAAM,mBAAmB,CAAC,IAAI,CAAC,CAAC;IAChC,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,IAAgB,EAChB,IAAwE;IAExE,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAExB,IAAI,CAAC;QACH,IAAI,MAAM,KAAK,cAAc,EAAE,CAAC;YAC9B,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;YAChD,OAAO;gBACL,OAAO,EAAE,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC;gBAC1B,SAAS,EAAE,SAAS,CAAC,SAAS;gBAC9B,WAAW,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI;aAChC,CAAC;QACJ,CAAC;QAED,IAAI,MAAM,KAAK,eAAe,EAAE,CAAC;YAC/B,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;YAChD,OAAO;gBACL,OAAO,EAAE,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC;gBAC1B,SAAS,EAAE,SAAS,CAAC,SAAS;gBAC9B,WAAW,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI;aAChC,CAAC;QACJ,CAAC;QAED,IAAI,MAAM,KAAK,YAAY,EAAE,CAAC;YAC5B,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBAC9B,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;YACtE,CAAC;YACD,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACpC,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;YAC9D,CAAC;YACD,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACrC,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;YAChD,MAAM,cAAc,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,CAAC;YAClF,IAAI,CAAC,cAAc,EAAE,CAAC;gBACpB,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;YACpF,CAAC;YACD,kFAAkF;YAClF,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACvC,MAAM,cAAc,GAAG,MAAM,gBAAgB,CAAC,IAAI,CAAC,CAAC;YACpD,OAAO;gBACL,OAAO,EAAE,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC;gBAC1B,SAAS,EAAE,cAAc,CAAC,SAAS;gBACnC,WAAW,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI;aAChC,CAAC;QACJ,CAAC;QAED,IAAI,MAAM,KAAK,eAAe,EAAE,CAAC;YAC/B,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBAC9B,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;YACzE,CAAC;YACD,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACrC,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;YAChD,SAAS,CAAC,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,CAAC;YACjF,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACvC,MAAM,cAAc,GAAG,MAAM,gBAAgB,CAAC,IAAI,CAAC,CAAC;YACpD,OAAO;gBACL,OAAO,EAAE,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC;gBAC1B,SAAS,EAAE,cAAc,CAAC,SAAS;gBACnC,WAAW,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI;aAChC,CAAC;QACJ,CAAC;QAED,IAAI,MAAM,KAAK,eAAe,EAAE,CAAC;YAC/B,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;gBACjC,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;YAC5E,CAAC;YACD,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;YAChD,SAAS,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;YACrC,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACvC,MAAM,cAAc,GAAG,MAAM,gBAAgB,CAAC,IAAI,CAAC,CAAC;YACpD,OAAO;gBACL,OAAO,EAAE,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC;gBAC1B,SAAS,EAAE,cAAc,CAAC,SAAS;gBACnC,WAAW,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI;aAChC,CAAC;QACJ,CAAC;QAED,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;YACvB,MAAM,KAAK,GAAG,aAAa,EAAE,CAAC;YAC9B,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACnC,MAAM,cAAc,GAAG,MAAM,gBAAgB,CAAC,IAAI,CAAC,CAAC;YACpD,OAAO;gBACL,OAAO,EAAE,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC;gBAC1B,SAAS,EAAE,cAAc,CAAC,SAAS;gBACnC,WAAW,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI;aAChC,CAAC;QACJ,CAAC;QAED,MAAM,IAAI,KAAK,CAAC,8BAA8B,MAAgB,GAAG,CAAC,CAAC;IACrE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7D,iEAAiE;QACjE,IAAI,GAAG,CAAC,UAAU,CAAC,aAAa,MAAM,IAAI,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;YAC7E,MAAM,GAAG,CAAC;QACZ,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,aAAa,MAAM,MAAM,GAAG,EAAE,CAAC,CAAC;IAClD,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { ServerDeps } from '../server-deps.js';
|
|
3
|
+
import type { SkillContent } from '../core/types.js';
|
|
4
|
+
export declare const getInputSchema: {
|
|
5
|
+
readonly name: z.ZodString;
|
|
6
|
+
};
|
|
7
|
+
export declare function handleGet(deps: ServerDeps, args: {
|
|
8
|
+
name: string;
|
|
9
|
+
}): Promise<SkillContent>;
|
|
10
|
+
//# sourceMappingURL=get.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get.d.ts","sourceRoot":"","sources":["../../src/tools/get.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAGrD,eAAO,MAAM,cAAc;;CAEjB,CAAC;AAEX,wBAAsB,SAAS,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,YAAY,CAAC,CAe/F"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { ensureRegistryFresh } from './loader.js';
|
|
3
|
+
export const getInputSchema = {
|
|
4
|
+
name: z.string(),
|
|
5
|
+
};
|
|
6
|
+
export async function handleGet(deps, args) {
|
|
7
|
+
await ensureRegistryFresh(deps);
|
|
8
|
+
if (!deps.registry.has(args.name)) {
|
|
9
|
+
throw new Error(`Skill not found: ${args.name}`);
|
|
10
|
+
}
|
|
11
|
+
const cached = deps.contentCache.get(args.name);
|
|
12
|
+
if (cached !== undefined)
|
|
13
|
+
return cached;
|
|
14
|
+
// Cache miss — re-parse from disk using the metadata's location.
|
|
15
|
+
const meta = deps.registry.get(args.name);
|
|
16
|
+
const content = await deps.parser.parseFile(meta.sourcePath, meta.folder);
|
|
17
|
+
deps.contentCache.set(args.name, content);
|
|
18
|
+
return content;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=get.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get.js","sourceRoot":"","sources":["../../src/tools/get.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAElD,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;CACR,CAAC;AAEX,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,IAAgB,EAAE,IAAsB;IACtE,MAAM,mBAAmB,CAAC,IAAI,CAAC,CAAC;IAEhC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CAAC,oBAAoB,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IACnD,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChD,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC;IAExC,iEAAiE;IACjE,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAE,CAAC;IAC3C,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAC1E,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC1C,OAAO,OAAO,CAAC;AACjB,CAAC"}
|