@lyupro/skillforge-mcp 1.2.0 → 1.4.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.
Files changed (81) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/CHANGELOG.md +47 -0
  4. package/README.md +27 -12
  5. package/dist/cli/dispatcher.d.ts.map +1 -1
  6. package/dist/cli/dispatcher.js +13 -10
  7. package/dist/cli/dispatcher.js.map +1 -1
  8. package/dist/cli/folders-format.d.ts +10 -0
  9. package/dist/cli/folders-format.d.ts.map +1 -0
  10. package/dist/cli/folders-format.js +41 -0
  11. package/dist/cli/folders-format.js.map +1 -0
  12. package/dist/cli/folders-handlers.d.ts +16 -0
  13. package/dist/cli/folders-handlers.d.ts.map +1 -0
  14. package/dist/cli/folders-handlers.js +195 -0
  15. package/dist/cli/folders-handlers.js.map +1 -0
  16. package/dist/cli/folders-shared.d.ts +29 -0
  17. package/dist/cli/folders-shared.d.ts.map +1 -0
  18. package/dist/cli/folders-shared.js +82 -0
  19. package/dist/cli/folders-shared.js.map +1 -0
  20. package/dist/cli/folders.d.ts +7 -2
  21. package/dist/cli/folders.d.ts.map +1 -1
  22. package/dist/cli/folders.js +28 -177
  23. package/dist/cli/folders.js.map +1 -1
  24. package/dist/cli/skills-format.d.ts +15 -0
  25. package/dist/cli/skills-format.d.ts.map +1 -0
  26. package/dist/cli/skills-format.js +84 -0
  27. package/dist/cli/skills-format.js.map +1 -0
  28. package/dist/cli/skills-handlers.d.ts +15 -0
  29. package/dist/cli/skills-handlers.d.ts.map +1 -0
  30. package/dist/cli/skills-handlers.js +112 -0
  31. package/dist/cli/skills-handlers.js.map +1 -0
  32. package/dist/cli/skills-shared.d.ts +32 -0
  33. package/dist/cli/skills-shared.d.ts.map +1 -0
  34. package/dist/cli/skills-shared.js +90 -0
  35. package/dist/cli/skills-shared.js.map +1 -0
  36. package/dist/cli/skills.d.ts +46 -0
  37. package/dist/cli/skills.d.ts.map +1 -0
  38. package/dist/cli/skills.js +107 -0
  39. package/dist/cli/skills.js.map +1 -0
  40. package/dist/cli/tools.d.ts.map +1 -1
  41. package/dist/cli/tools.js +6 -0
  42. package/dist/cli/tools.js.map +1 -1
  43. package/dist/config/config-schema.d.ts +248 -136
  44. package/dist/config/config-schema.d.ts.map +1 -1
  45. package/dist/config/config-schema.js +34 -14
  46. package/dist/config/config-schema.js.map +1 -1
  47. package/dist/detect/skill-source-conflict.d.ts +24 -7
  48. package/dist/detect/skill-source-conflict.d.ts.map +1 -1
  49. package/dist/detect/skill-source-conflict.js +62 -10
  50. package/dist/detect/skill-source-conflict.js.map +1 -1
  51. package/dist/reconcile.d.ts +5 -0
  52. package/dist/reconcile.d.ts.map +1 -0
  53. package/dist/reconcile.js +20 -0
  54. package/dist/reconcile.js.map +1 -0
  55. package/dist/runtime.d.ts +14 -0
  56. package/dist/runtime.d.ts.map +1 -0
  57. package/dist/runtime.js +29 -0
  58. package/dist/runtime.js.map +1 -0
  59. package/dist/server-deps.d.ts +3 -1
  60. package/dist/server-deps.d.ts.map +1 -1
  61. package/dist/server.d.ts.map +1 -1
  62. package/dist/server.js +26 -9
  63. package/dist/server.js.map +1 -1
  64. package/dist/tools/configure.d.ts +2 -0
  65. package/dist/tools/configure.d.ts.map +1 -1
  66. package/dist/tools/configure.js +22 -26
  67. package/dist/tools/configure.js.map +1 -1
  68. package/dist/tools/list.d.ts +2 -0
  69. package/dist/tools/list.d.ts.map +1 -1
  70. package/dist/tools/list.js +12 -0
  71. package/dist/tools/list.js.map +1 -1
  72. package/dist/watcher/config-watcher.d.ts +25 -0
  73. package/dist/watcher/config-watcher.d.ts.map +1 -0
  74. package/dist/watcher/config-watcher.js +92 -0
  75. package/dist/watcher/config-watcher.js.map +1 -0
  76. package/dist/watcher/index.d.ts +2 -0
  77. package/dist/watcher/index.d.ts.map +1 -1
  78. package/dist/watcher/index.js +1 -0
  79. package/dist/watcher/index.js.map +1 -1
  80. package/manifest.json +3 -3
  81. package/package.json +1 -1
@@ -0,0 +1,92 @@
1
+ import { basename, dirname } from 'node:path';
2
+ // The config CLI writes via temp+rename (atomic), so a direct file watch goes
3
+ // dead after the first save. We watch the parent directory instead and filter
4
+ // raw events down to the config file's basename. Hidden-file ignore patterns
5
+ // must NOT be applied — config.json lives in a dotted dir (~/.lyupro/.skillforge).
6
+ const CHOKIDAR_OPTS = {
7
+ ignoreInitial: true,
8
+ persistent: true,
9
+ awaitWriteFinish: { stabilityThreshold: 100, pollInterval: 50 },
10
+ depth: 0,
11
+ };
12
+ async function loadDefaultChokidar() {
13
+ const mod = await import('chokidar');
14
+ return {
15
+ watch: (paths, options) => mod.watch(paths, options),
16
+ };
17
+ }
18
+ /**
19
+ * Watches a single config file for out-of-process edits (e.g. the
20
+ * `skillforge folders` CLI rewriting config.json). Debounced — a burst of
21
+ * raw filesystem events coalesces into one onChange call.
22
+ */
23
+ export class ConfigWatcher {
24
+ #configPath;
25
+ #configDir;
26
+ #configBasename;
27
+ #onChange;
28
+ #debounceMs;
29
+ #setTimeoutFn;
30
+ #clearTimeoutFn;
31
+ #injectedChokidar;
32
+ #watcher = null;
33
+ #resolvedChokidar = null;
34
+ #pendingTimer = null;
35
+ constructor(opts) {
36
+ this.#configPath = opts.configPath;
37
+ this.#configDir = dirname(opts.configPath);
38
+ this.#configBasename = basename(opts.configPath);
39
+ this.#onChange = opts.onChange;
40
+ this.#debounceMs = opts.debounceMs ?? 400;
41
+ this.#injectedChokidar = opts.chokidar;
42
+ this.#setTimeoutFn = opts.setTimeoutFn ?? setTimeout;
43
+ this.#clearTimeoutFn = opts.clearTimeoutFn ?? clearTimeout;
44
+ }
45
+ isRunning() {
46
+ return this.#watcher !== null;
47
+ }
48
+ getConfigPath() {
49
+ return this.#configPath;
50
+ }
51
+ async start() {
52
+ if (this.#watcher !== null)
53
+ return;
54
+ const chokidar = this.#injectedChokidar ?? (await this.#getResolvedChokidar());
55
+ this.#watcher = chokidar.watch(this.#configDir, CHOKIDAR_OPTS);
56
+ this.#watcher.on('add', (path) => this.#handleRaw(path));
57
+ this.#watcher.on('change', (path) => this.#handleRaw(path));
58
+ this.#watcher.on('unlink', (path) => this.#handleRaw(path));
59
+ this.#watcher.on('error', (err) => {
60
+ console.error(`[skillforge:config-watcher] error: ${String(err)}`);
61
+ });
62
+ }
63
+ async stop() {
64
+ if (this.#watcher === null)
65
+ return;
66
+ if (this.#pendingTimer !== null) {
67
+ this.#clearTimeoutFn(this.#pendingTimer);
68
+ this.#pendingTimer = null;
69
+ }
70
+ await this.#watcher.close();
71
+ this.#watcher = null;
72
+ }
73
+ async #getResolvedChokidar() {
74
+ if (this.#resolvedChokidar === null) {
75
+ this.#resolvedChokidar = await loadDefaultChokidar();
76
+ }
77
+ return this.#resolvedChokidar;
78
+ }
79
+ #handleRaw(path) {
80
+ // Only react to the config file itself — the parent dir may hold siblings.
81
+ if (basename(path) !== this.#configBasename)
82
+ return;
83
+ if (this.#pendingTimer !== null) {
84
+ this.#clearTimeoutFn(this.#pendingTimer);
85
+ }
86
+ this.#pendingTimer = this.#setTimeoutFn(() => {
87
+ this.#pendingTimer = null;
88
+ void this.#onChange();
89
+ }, this.#debounceMs);
90
+ }
91
+ }
92
+ //# sourceMappingURL=config-watcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-watcher.js","sourceRoot":"","sources":["../../src/watcher/config-watcher.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,6 @@
1
1
  export { FolderWatcher } from './folder-watcher.js';
2
2
  export type { FolderWatcherOptions, WatcherEvent, WatcherEventType } from './folder-watcher.js';
3
+ export { ConfigWatcher } from './config-watcher.js';
4
+ export type { ConfigWatcherOptions } from './config-watcher.js';
3
5
  export type { ChokidarLike, ChokidarWatcher, ChokidarOptions } from './chokidar-types.js';
4
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/watcher/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EAAE,oBAAoB,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAChG,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/watcher/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EAAE,oBAAoB,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAChG,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAChE,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC"}
@@ -1,2 +1,3 @@
1
1
  export { FolderWatcher } from './folder-watcher.js';
2
+ export { ConfigWatcher } from './config-watcher.js';
2
3
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/watcher/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/watcher/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC"}
package/manifest.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://modelcontextprotocol.io/schemas/manifest.json",
3
3
  "name": "@lyupro/skillforge-mcp",
4
4
  "displayName": "SkillForge MCP",
5
- "version": "1.2.0",
5
+ "version": "1.4.0",
6
6
  "description": "Universal Skills MCP server — load Markdown skills from arbitrary folders, lazy-by-design, cross-tool (Claude Code / Codex CLI / any MCP client).",
7
7
  "author": {
8
8
  "name": "Lyu Pro",
@@ -41,7 +41,7 @@
41
41
  "tools": [
42
42
  {
43
43
  "name": "skills__list",
44
- "description": "Enumerate available skills (metadata only). Filters: folder, search, source."
44
+ "description": "Enumerate available skills (metadata only). Filters: folder, search, source, folderTag (keeps skills under folders carrying that tag)."
45
45
  },
46
46
  {
47
47
  "name": "skills__get",
@@ -53,7 +53,7 @@
53
53
  },
54
54
  {
55
55
  "name": "skills__configure",
56
- "description": "Manage configured skill folders, blacklist, and reset to defaults. Actions: add_folder, remove_folder, list_folders, set_blacklist, get_blacklist, reset. Persists to the platform config path."
56
+ "description": "Manage configured skill folders, blacklist, and reset to defaults. Actions: add_folder (optionally with a kebab-case alias), remove_folder, list_folders, set_blacklist, get_blacklist, reset. Persists to the platform config path."
57
57
  },
58
58
  {
59
59
  "name": "skills__reload",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lyupro/skillforge-mcp",
3
- "version": "1.2.0",
3
+ "version": "1.4.0",
4
4
  "description": "Universal Skills MCP Server — load Markdown skills from arbitrary folders, lazy-by-design, cross-tool (Claude Code / Codex CLI / any MCP client).",
5
5
  "keywords": [
6
6
  "mcp",