@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.
Files changed (221) hide show
  1. package/CHANGELOG.md +114 -0
  2. package/LICENSE +21 -0
  3. package/README.md +231 -0
  4. package/dist/cli/install.d.ts +41 -0
  5. package/dist/cli/install.d.ts.map +1 -0
  6. package/dist/cli/install.js +223 -0
  7. package/dist/cli/install.js.map +1 -0
  8. package/dist/config/config-schema.d.ts +175 -0
  9. package/dist/config/config-schema.d.ts.map +1 -0
  10. package/dist/config/config-schema.js +49 -0
  11. package/dist/config/config-schema.js.map +1 -0
  12. package/dist/config/config-store.d.ts +24 -0
  13. package/dist/config/config-store.d.ts.map +1 -0
  14. package/dist/config/config-store.js +67 -0
  15. package/dist/config/config-store.js.map +1 -0
  16. package/dist/config/index.d.ts +5 -0
  17. package/dist/config/index.d.ts.map +1 -0
  18. package/dist/config/index.js +3 -0
  19. package/dist/config/index.js.map +1 -0
  20. package/dist/config.d.ts +25 -0
  21. package/dist/config.d.ts.map +1 -0
  22. package/dist/config.js +73 -0
  23. package/dist/config.js.map +1 -0
  24. package/dist/core/errors.d.ts +9 -0
  25. package/dist/core/errors.d.ts.map +1 -0
  26. package/dist/core/errors.js +13 -0
  27. package/dist/core/errors.js.map +1 -0
  28. package/dist/core/index.d.ts +6 -0
  29. package/dist/core/index.d.ts.map +1 -0
  30. package/dist/core/index.js +5 -0
  31. package/dist/core/index.js.map +1 -0
  32. package/dist/core/skill-content-cache.d.ts +18 -0
  33. package/dist/core/skill-content-cache.d.ts.map +1 -0
  34. package/dist/core/skill-content-cache.js +56 -0
  35. package/dist/core/skill-content-cache.js.map +1 -0
  36. package/dist/core/skill-metadata-cache.d.ts +15 -0
  37. package/dist/core/skill-metadata-cache.d.ts.map +1 -0
  38. package/dist/core/skill-metadata-cache.js +31 -0
  39. package/dist/core/skill-metadata-cache.js.map +1 -0
  40. package/dist/core/skill-registry.d.ts +12 -0
  41. package/dist/core/skill-registry.d.ts.map +1 -0
  42. package/dist/core/skill-registry.js +28 -0
  43. package/dist/core/skill-registry.js.map +1 -0
  44. package/dist/core/skill-resolver.d.ts +6 -0
  45. package/dist/core/skill-resolver.d.ts.map +1 -0
  46. package/dist/core/skill-resolver.js +32 -0
  47. package/dist/core/skill-resolver.js.map +1 -0
  48. package/dist/core/types.d.ts +80 -0
  49. package/dist/core/types.d.ts.map +1 -0
  50. package/dist/core/types.js +10 -0
  51. package/dist/core/types.js.map +1 -0
  52. package/dist/decorators/base-decorator.d.ts +10 -0
  53. package/dist/decorators/base-decorator.d.ts.map +1 -0
  54. package/dist/decorators/base-decorator.js +13 -0
  55. package/dist/decorators/base-decorator.js.map +1 -0
  56. package/dist/decorators/cache-decorator.d.ts +33 -0
  57. package/dist/decorators/cache-decorator.d.ts.map +1 -0
  58. package/dist/decorators/cache-decorator.js +89 -0
  59. package/dist/decorators/cache-decorator.js.map +1 -0
  60. package/dist/decorators/decorator-chain.d.ts +16 -0
  61. package/dist/decorators/decorator-chain.d.ts.map +1 -0
  62. package/dist/decorators/decorator-chain.js +31 -0
  63. package/dist/decorators/decorator-chain.js.map +1 -0
  64. package/dist/decorators/index.d.ts +10 -0
  65. package/dist/decorators/index.d.ts.map +1 -0
  66. package/dist/decorators/index.js +6 -0
  67. package/dist/decorators/index.js.map +1 -0
  68. package/dist/decorators/logging-decorator.d.ts +15 -0
  69. package/dist/decorators/logging-decorator.d.ts.map +1 -0
  70. package/dist/decorators/logging-decorator.js +34 -0
  71. package/dist/decorators/logging-decorator.js.map +1 -0
  72. package/dist/decorators/timeout-decorator.d.ts +19 -0
  73. package/dist/decorators/timeout-decorator.d.ts.map +1 -0
  74. package/dist/decorators/timeout-decorator.js +59 -0
  75. package/dist/decorators/timeout-decorator.js.map +1 -0
  76. package/dist/factory/index.d.ts +2 -0
  77. package/dist/factory/index.d.ts.map +1 -0
  78. package/dist/factory/index.js +2 -0
  79. package/dist/factory/index.js.map +1 -0
  80. package/dist/factory/strategy-factory.d.ts +10 -0
  81. package/dist/factory/strategy-factory.d.ts.map +1 -0
  82. package/dist/factory/strategy-factory.js +37 -0
  83. package/dist/factory/strategy-factory.js.map +1 -0
  84. package/dist/handlers/composite-resolver.d.ts +34 -0
  85. package/dist/handlers/composite-resolver.d.ts.map +1 -0
  86. package/dist/handlers/composite-resolver.js +94 -0
  87. package/dist/handlers/composite-resolver.js.map +1 -0
  88. package/dist/handlers/hybrid-strategy.d.ts +14 -0
  89. package/dist/handlers/hybrid-strategy.d.ts.map +1 -0
  90. package/dist/handlers/hybrid-strategy.js +42 -0
  91. package/dist/handlers/hybrid-strategy.js.map +1 -0
  92. package/dist/handlers/index.d.ts +3 -0
  93. package/dist/handlers/index.d.ts.map +1 -0
  94. package/dist/handlers/index.js +2 -0
  95. package/dist/handlers/index.js.map +1 -0
  96. package/dist/handlers/invocation-strategy.d.ts +17 -0
  97. package/dist/handlers/invocation-strategy.d.ts.map +1 -0
  98. package/dist/handlers/invocation-strategy.js +2 -0
  99. package/dist/handlers/invocation-strategy.js.map +1 -0
  100. package/dist/handlers/prompt-strategy.d.ts +8 -0
  101. package/dist/handlers/prompt-strategy.d.ts.map +1 -0
  102. package/dist/handlers/prompt-strategy.js +31 -0
  103. package/dist/handlers/prompt-strategy.js.map +1 -0
  104. package/dist/handlers/script-strategy.d.ts +20 -0
  105. package/dist/handlers/script-strategy.d.ts.map +1 -0
  106. package/dist/handlers/script-strategy.js +87 -0
  107. package/dist/handlers/script-strategy.js.map +1 -0
  108. package/dist/installers/atomic-write.d.ts +13 -0
  109. package/dist/installers/atomic-write.d.ts.map +1 -0
  110. package/dist/installers/atomic-write.js +98 -0
  111. package/dist/installers/atomic-write.js.map +1 -0
  112. package/dist/installers/claude-installer.d.ts +26 -0
  113. package/dist/installers/claude-installer.d.ts.map +1 -0
  114. package/dist/installers/claude-installer.js +118 -0
  115. package/dist/installers/claude-installer.js.map +1 -0
  116. package/dist/installers/codex-installer.d.ts +30 -0
  117. package/dist/installers/codex-installer.d.ts.map +1 -0
  118. package/dist/installers/codex-installer.js +125 -0
  119. package/dist/installers/codex-installer.js.map +1 -0
  120. package/dist/installers/cursor-installer.d.ts +29 -0
  121. package/dist/installers/cursor-installer.d.ts.map +1 -0
  122. package/dist/installers/cursor-installer.js +126 -0
  123. package/dist/installers/cursor-installer.js.map +1 -0
  124. package/dist/installers/paths.d.ts +20 -0
  125. package/dist/installers/paths.d.ts.map +1 -0
  126. package/dist/installers/paths.js +50 -0
  127. package/dist/installers/paths.js.map +1 -0
  128. package/dist/installers/registry.d.ts +8 -0
  129. package/dist/installers/registry.d.ts.map +1 -0
  130. package/dist/installers/registry.js +18 -0
  131. package/dist/installers/registry.js.map +1 -0
  132. package/dist/installers/types.d.ts +45 -0
  133. package/dist/installers/types.d.ts.map +1 -0
  134. package/dist/installers/types.js +9 -0
  135. package/dist/installers/types.js.map +1 -0
  136. package/dist/parser/file-scanner.d.ts +10 -0
  137. package/dist/parser/file-scanner.d.ts.map +1 -0
  138. package/dist/parser/file-scanner.js +37 -0
  139. package/dist/parser/file-scanner.js.map +1 -0
  140. package/dist/parser/format-detector.d.ts +11 -0
  141. package/dist/parser/format-detector.d.ts.map +1 -0
  142. package/dist/parser/format-detector.js +13 -0
  143. package/dist/parser/format-detector.js.map +1 -0
  144. package/dist/parser/frontmatter-parser.d.ts +14 -0
  145. package/dist/parser/frontmatter-parser.d.ts.map +1 -0
  146. package/dist/parser/frontmatter-parser.js +98 -0
  147. package/dist/parser/frontmatter-parser.js.map +1 -0
  148. package/dist/parser/index.d.ts +4 -0
  149. package/dist/parser/index.d.ts.map +1 -0
  150. package/dist/parser/index.js +4 -0
  151. package/dist/parser/index.js.map +1 -0
  152. package/dist/parser/scripts-dir-detector.d.ts +7 -0
  153. package/dist/parser/scripts-dir-detector.d.ts.map +1 -0
  154. package/dist/parser/scripts-dir-detector.js +17 -0
  155. package/dist/parser/scripts-dir-detector.js.map +1 -0
  156. package/dist/security/blacklist-filter.d.ts +32 -0
  157. package/dist/security/blacklist-filter.d.ts.map +1 -0
  158. package/dist/security/blacklist-filter.js +35 -0
  159. package/dist/security/blacklist-filter.js.map +1 -0
  160. package/dist/security/index.d.ts +5 -0
  161. package/dist/security/index.d.ts.map +1 -0
  162. package/dist/security/index.js +3 -0
  163. package/dist/security/index.js.map +1 -0
  164. package/dist/security/pattern-scanner.d.ts +27 -0
  165. package/dist/security/pattern-scanner.d.ts.map +1 -0
  166. package/dist/security/pattern-scanner.js +46 -0
  167. package/dist/security/pattern-scanner.js.map +1 -0
  168. package/dist/security/sandbox-runner.d.ts +48 -0
  169. package/dist/security/sandbox-runner.d.ts.map +1 -0
  170. package/dist/security/sandbox-runner.js +131 -0
  171. package/dist/security/sandbox-runner.js.map +1 -0
  172. package/dist/server-deps.d.ts +28 -0
  173. package/dist/server-deps.d.ts.map +1 -0
  174. package/dist/server-deps.js +2 -0
  175. package/dist/server-deps.js.map +1 -0
  176. package/dist/server.d.ts +12 -0
  177. package/dist/server.d.ts.map +1 -0
  178. package/dist/server.js +174 -0
  179. package/dist/server.js.map +1 -0
  180. package/dist/tools/configure.d.ts +22 -0
  181. package/dist/tools/configure.d.ts.map +1 -0
  182. package/dist/tools/configure.js +126 -0
  183. package/dist/tools/configure.js.map +1 -0
  184. package/dist/tools/get.d.ts +10 -0
  185. package/dist/tools/get.d.ts.map +1 -0
  186. package/dist/tools/get.js +20 -0
  187. package/dist/tools/get.js.map +1 -0
  188. package/dist/tools/index.d.ts +9 -0
  189. package/dist/tools/index.d.ts.map +1 -0
  190. package/dist/tools/index.js +7 -0
  191. package/dist/tools/index.js.map +1 -0
  192. package/dist/tools/invoke.d.ts +12 -0
  193. package/dist/tools/invoke.d.ts.map +1 -0
  194. package/dist/tools/invoke.js +36 -0
  195. package/dist/tools/invoke.js.map +1 -0
  196. package/dist/tools/list.d.ts +16 -0
  197. package/dist/tools/list.d.ts.map +1 -0
  198. package/dist/tools/list.js +33 -0
  199. package/dist/tools/list.js.map +1 -0
  200. package/dist/tools/loader.d.ts +30 -0
  201. package/dist/tools/loader.d.ts.map +1 -0
  202. package/dist/tools/loader.js +92 -0
  203. package/dist/tools/loader.js.map +1 -0
  204. package/dist/tools/reload.d.ts +22 -0
  205. package/dist/tools/reload.d.ts.map +1 -0
  206. package/dist/tools/reload.js +39 -0
  207. package/dist/tools/reload.js.map +1 -0
  208. package/dist/watcher/chokidar-types.d.ts +20 -0
  209. package/dist/watcher/chokidar-types.d.ts.map +1 -0
  210. package/dist/watcher/chokidar-types.js +2 -0
  211. package/dist/watcher/chokidar-types.js.map +1 -0
  212. package/dist/watcher/folder-watcher.d.ts +27 -0
  213. package/dist/watcher/folder-watcher.d.ts.map +1 -0
  214. package/dist/watcher/folder-watcher.js +123 -0
  215. package/dist/watcher/folder-watcher.js.map +1 -0
  216. package/dist/watcher/index.d.ts +4 -0
  217. package/dist/watcher/index.d.ts.map +1 -0
  218. package/dist/watcher/index.js +2 -0
  219. package/dist/watcher/index.js.map +1 -0
  220. package/manifest.json +96 -0
  221. package/package.json +78 -0
@@ -0,0 +1,31 @@
1
+ export class SkillMetadataCache {
2
+ #ttlMs;
3
+ #now;
4
+ #freshAt = null;
5
+ constructor(options) {
6
+ const ttlMs = options?.ttlMs ?? 300_000;
7
+ if (ttlMs <= 0) {
8
+ throw new Error('ttlMs must be a positive number');
9
+ }
10
+ this.#ttlMs = ttlMs;
11
+ this.#now = options?.now ?? Date.now;
12
+ }
13
+ isValid() {
14
+ return this.#freshAt !== null && this.#now() - this.#freshAt < this.#ttlMs;
15
+ }
16
+ markFresh() {
17
+ this.#freshAt = this.#now();
18
+ }
19
+ invalidate() {
20
+ this.#freshAt = null;
21
+ }
22
+ expiresAt() {
23
+ if (this.#freshAt === null)
24
+ return null;
25
+ return this.#freshAt + this.#ttlMs;
26
+ }
27
+ get ttlMs() {
28
+ return this.#ttlMs;
29
+ }
30
+ }
31
+ //# sourceMappingURL=skill-metadata-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-metadata-cache.js","sourceRoot":"","sources":["../../src/core/skill-metadata-cache.ts"],"names":[],"mappings":"AAKA,MAAM,OAAO,kBAAkB;IACpB,MAAM,CAAS;IACf,IAAI,CAAe;IAC5B,QAAQ,GAAkB,IAAI,CAAC;IAE/B,YAAY,OAA8B;QACxC,MAAM,KAAK,GAAG,OAAO,EAAE,KAAK,IAAI,OAAO,CAAC;QACxC,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;QACrD,CAAC;QACD,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,IAAI,CAAC,IAAI,GAAG,OAAO,EAAE,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;IACvC,CAAC;IAED,OAAO;QACL,OAAO,IAAI,CAAC,QAAQ,KAAK,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC;IAC7E,CAAC;IAED,SAAS;QACP,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC9B,CAAC;IAED,UAAU;QACR,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;IACvB,CAAC;IAED,SAAS;QACP,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC;QACxC,OAAO,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC;IACrC,CAAC;IAED,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;CACF"}
@@ -0,0 +1,12 @@
1
+ import type { SkillMetadata } from './types.js';
2
+ export declare class SkillRegistry {
3
+ #private;
4
+ register(metadata: SkillMetadata): void;
5
+ get(name: string): SkillMetadata | undefined;
6
+ has(name: string): boolean;
7
+ unregister(name: string): boolean;
8
+ clear(): void;
9
+ getAll(): SkillMetadata[];
10
+ get size(): number;
11
+ }
12
+ //# sourceMappingURL=skill-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-registry.d.ts","sourceRoot":"","sources":["../../src/core/skill-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,qBAAa,aAAa;;IAGxB,QAAQ,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI;IAOvC,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;IAI5C,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI1B,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAIjC,KAAK,IAAI,IAAI;IAIb,MAAM,IAAI,aAAa,EAAE;IAIzB,IAAI,IAAI,IAAI,MAAM,CAEjB;CACF"}
@@ -0,0 +1,28 @@
1
+ export class SkillRegistry {
2
+ #store = new Map();
3
+ register(metadata) {
4
+ if (!metadata.name) {
5
+ throw new Error('Skill name must be a non-empty string');
6
+ }
7
+ this.#store.set(metadata.name, metadata);
8
+ }
9
+ get(name) {
10
+ return this.#store.get(name);
11
+ }
12
+ has(name) {
13
+ return this.#store.has(name);
14
+ }
15
+ unregister(name) {
16
+ return this.#store.delete(name);
17
+ }
18
+ clear() {
19
+ this.#store.clear();
20
+ }
21
+ getAll() {
22
+ return [...this.#store.values()].sort((a, b) => a.name.localeCompare(b.name));
23
+ }
24
+ get size() {
25
+ return this.#store.size;
26
+ }
27
+ }
28
+ //# sourceMappingURL=skill-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-registry.js","sourceRoot":"","sources":["../../src/core/skill-registry.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,aAAa;IACf,MAAM,GAAG,IAAI,GAAG,EAAyB,CAAC;IAEnD,QAAQ,CAAC,QAAuB;QAC9B,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;QAC3D,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAC3C,CAAC;IAED,GAAG,CAAC,IAAY;QACd,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;IAED,GAAG,CAAC,IAAY;QACd,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;IAED,UAAU,CAAC,IAAY;QACrB,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC;IAED,KAAK;QACH,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;IACtB,CAAC;IAED,MAAM;QACJ,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAChF,CAAC;IAED,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;IAC1B,CAAC;CACF"}
@@ -0,0 +1,6 @@
1
+ import type { SkillMetadata } from './types.js';
2
+ export declare class SkillResolver {
3
+ #private;
4
+ resolve(candidates: SkillMetadata[], folderPriority: string[]): SkillMetadata;
5
+ }
6
+ //# sourceMappingURL=skill-resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-resolver.d.ts","sourceRoot":"","sources":["../../src/core/skill-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,qBAAa,aAAa;;IACxB,OAAO,CAAC,UAAU,EAAE,aAAa,EAAE,EAAE,cAAc,EAAE,MAAM,EAAE,GAAG,aAAa;CAkC9E"}
@@ -0,0 +1,32 @@
1
+ export class SkillResolver {
2
+ resolve(candidates, folderPriority) {
3
+ if (candidates.length === 0) {
4
+ throw new Error('SkillResolver.resolve: candidates must not be empty');
5
+ }
6
+ if (candidates.length === 1) {
7
+ return candidates[0];
8
+ }
9
+ const priorityIndex = new Map();
10
+ for (let i = 0; i < folderPriority.length; i++) {
11
+ const folder = folderPriority[i];
12
+ if (!priorityIndex.has(folder)) {
13
+ priorityIndex.set(folder, i);
14
+ }
15
+ }
16
+ let best = candidates[0];
17
+ let bestRank = this.#rankOf(best.folder, priorityIndex);
18
+ for (let i = 1; i < candidates.length; i++) {
19
+ const candidate = candidates[i];
20
+ const rank = this.#rankOf(candidate.folder, priorityIndex);
21
+ if (rank < bestRank) {
22
+ best = candidate;
23
+ bestRank = rank;
24
+ }
25
+ }
26
+ return best;
27
+ }
28
+ #rankOf(folder, priorityIndex) {
29
+ return priorityIndex.get(folder) ?? Number.MAX_SAFE_INTEGER;
30
+ }
31
+ }
32
+ //# sourceMappingURL=skill-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-resolver.js","sourceRoot":"","sources":["../../src/core/skill-resolver.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,aAAa;IACxB,OAAO,CAAC,UAA2B,EAAE,cAAwB;QAC3D,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;QACzE,CAAC;QACD,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5B,OAAO,UAAU,CAAC,CAAC,CAAE,CAAC;QACxB,CAAC;QAED,MAAM,aAAa,GAAG,IAAI,GAAG,EAAkB,CAAC;QAChD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,cAAc,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC/C,MAAM,MAAM,GAAG,cAAc,CAAC,CAAC,CAAE,CAAC;YAClC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC/B,aAAa,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;YAC/B,CAAC;QACH,CAAC;QAED,IAAI,IAAI,GAAG,UAAU,CAAC,CAAC,CAAE,CAAC;QAC1B,IAAI,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;QAExD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3C,MAAM,SAAS,GAAG,UAAU,CAAC,CAAC,CAAE,CAAC;YACjC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;YAC3D,IAAI,IAAI,GAAG,QAAQ,EAAE,CAAC;gBACpB,IAAI,GAAG,SAAS,CAAC;gBACjB,QAAQ,GAAG,IAAI,CAAC;YAClB,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,CAAC,MAAc,EAAE,aAA0C;QAChE,OAAO,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,gBAAgB,CAAC;IAC9D,CAAC;CACF"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Shared core types for SkillForge MCP.
3
+ *
4
+ * SkillSummary — lightweight metadata returned by `skills__list`.
5
+ * SkillMetadata — normalized frontmatter (Adapter target for FrontmatterParser).
6
+ * SkillContent — metadata + full SKILL.md body (returned by `skills__get`).
7
+ * InvocationContext / InvocationResult — IInvocationStrategy.invoke() I/O.
8
+ */
9
+ export type SkillFormat = 'claude' | 'codex' | 'persona' | 'custom';
10
+ export type StrategyKind = 'prompt' | 'script' | 'hybrid';
11
+ export interface SkillSummary {
12
+ /** Unique identifier — primary key in SkillRegistry. */
13
+ name: string;
14
+ /** One-line description (frontmatter `description`), optional. */
15
+ description?: string;
16
+ /** Absolute path to the SKILL.md (or equivalent) file on disk. */
17
+ sourcePath: string;
18
+ /** Absolute path to the configured root folder this skill was discovered under. */
19
+ folder: string;
20
+ /** Free-form tags from frontmatter `tags`. */
21
+ tags?: string[];
22
+ /** Detected frontmatter dialect — drives the Adapter selection in FrontmatterParser. */
23
+ format: SkillFormat;
24
+ }
25
+ export interface SkillMetadata extends SkillSummary {
26
+ /** Explicit strategy hint from frontmatter; otherwise inferred by StrategyFactory. */
27
+ strategy?: StrategyKind;
28
+ /** Opt-in flag: allow ScriptStrategy to spawn subprocesses for this skill. */
29
+ allowScripts?: boolean;
30
+ /** Opt-in flag: allow ScriptStrategy network access in sandbox. */
31
+ allowNetwork?: boolean;
32
+ /** Composite skill — names of skills to invoke before/around this one. */
33
+ skills?: string[];
34
+ /** Per-skill invocation timeout in ms; falls back to TimeoutDecorator default. */
35
+ timeoutMs?: number;
36
+ /** Opt-in: cache InvocationResult per (skillName + input) hash, TTL-based. */
37
+ cacheable?: boolean;
38
+ /** Per-skill TTL override (ms). Falls back to global cache config if absent. */
39
+ cacheTtlMs?: number;
40
+ /** Frontmatter passthrough for fields SkillForge does not interpret. */
41
+ extra?: Record<string, unknown>;
42
+ /** Filenames within sibling scripts/ directory, in interpreter-resolvable form
43
+ * (`main.py`, `entry.sh`, `app.mjs`). Current implementation supports single-entry only —
44
+ * index 0 is used by ScriptStrategy; multi-entry semantics deferred. */
45
+ scripts?: string[];
46
+ }
47
+ export interface SkillContent extends SkillMetadata {
48
+ /** SKILL.md body (everything after the frontmatter block). */
49
+ body: string;
50
+ /** Full SKILL.md file content including frontmatter. */
51
+ raw: string;
52
+ /** Absolute path to the sibling `scripts/` directory next to SKILL.md,
53
+ * populated by ScriptsDirDetector when present. Undefined when no scripts/
54
+ * directory exists. */
55
+ scriptsDir?: string;
56
+ }
57
+ export interface InvocationContext {
58
+ /** Which MCP tool initiated the invocation. */
59
+ callerTool: 'invoke';
60
+ /** User-supplied input forwarded to the skill. */
61
+ input: string;
62
+ /** AbortSignal injected by TimeoutDecorator. Strategies that spawn subprocess
63
+ * or perform long I/O should propagate this signal to honor cancellation. */
64
+ signal?: AbortSignal;
65
+ /** Optional per-call overrides (e.g. timeoutMs). */
66
+ options?: {
67
+ timeoutMs?: number;
68
+ };
69
+ }
70
+ export interface InvocationResult {
71
+ /** True on success, false on caught error. */
72
+ ok: boolean;
73
+ /** Skill output (prompt body for PromptStrategy, stdout for ScriptStrategy). */
74
+ output: string;
75
+ /** Populated when `ok` is false. */
76
+ error?: string;
77
+ /** Wall-clock duration of the invocation in ms. */
78
+ durationMs: number;
79
+ }
80
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEpE,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAE1D,MAAM,WAAW,YAAY;IAC3B,wDAAwD;IACxD,IAAI,EAAE,MAAM,CAAC;IACb,kEAAkE;IAClE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kEAAkE;IAClE,UAAU,EAAE,MAAM,CAAC;IACnB,mFAAmF;IACnF,MAAM,EAAE,MAAM,CAAC;IACf,8CAA8C;IAC9C,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,wFAAwF;IACxF,MAAM,EAAE,WAAW,CAAC;CACrB;AAED,MAAM,WAAW,aAAc,SAAQ,YAAY;IACjD,sFAAsF;IACtF,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,8EAA8E;IAC9E,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,mEAAmE;IACnE,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,0EAA0E;IAC1E,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,kFAAkF;IAClF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8EAA8E;IAC9E,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gFAAgF;IAChF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wEAAwE;IACxE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC;;6EAEyE;IACzE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,YAAa,SAAQ,aAAa;IACjD,8DAA8D;IAC9D,IAAI,EAAE,MAAM,CAAC;IACb,wDAAwD;IACxD,GAAG,EAAE,MAAM,CAAC;IACZ;;4BAEwB;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAChC,+CAA+C;IAC/C,UAAU,EAAE,QAAQ,CAAC;IACrB,kDAAkD;IAClD,KAAK,EAAE,MAAM,CAAC;IACd;kFAC8E;IAC9E,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,oDAAoD;IACpD,OAAO,CAAC,EAAE;QACR,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;CACH;AAED,MAAM,WAAW,gBAAgB;IAC/B,8CAA8C;IAC9C,EAAE,EAAE,OAAO,CAAC;IACZ,gFAAgF;IAChF,MAAM,EAAE,MAAM,CAAC;IACf,oCAAoC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mDAAmD;IACnD,UAAU,EAAE,MAAM,CAAC;CACpB"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Shared core types for SkillForge MCP.
3
+ *
4
+ * SkillSummary — lightweight metadata returned by `skills__list`.
5
+ * SkillMetadata — normalized frontmatter (Adapter target for FrontmatterParser).
6
+ * SkillContent — metadata + full SKILL.md body (returned by `skills__get`).
7
+ * InvocationContext / InvocationResult — IInvocationStrategy.invoke() I/O.
8
+ */
9
+ export {};
10
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
@@ -0,0 +1,10 @@
1
+ import type { InvocationStrategy } from '../handlers/invocation-strategy.js';
2
+ import type { InvocationContext, InvocationResult, StrategyKind, SkillContent } from '../core/types.js';
3
+ export declare abstract class BaseDecorator implements InvocationStrategy {
4
+ protected readonly inner: InvocationStrategy;
5
+ constructor(inner: InvocationStrategy);
6
+ get kind(): StrategyKind;
7
+ canHandle(skill: SkillContent): boolean;
8
+ abstract invoke(skill: SkillContent, context: InvocationContext): Promise<InvocationResult>;
9
+ }
10
+ //# sourceMappingURL=base-decorator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-decorator.d.ts","sourceRoot":"","sources":["../../src/decorators/base-decorator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAC7E,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAExG,8BAAsB,aAAc,YAAW,kBAAkB;IAC/D,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,kBAAkB,CAAC;gBAEjC,KAAK,EAAE,kBAAkB;IAIrC,IAAI,IAAI,IAAI,YAAY,CAEvB;IAED,SAAS,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO;IAIvC,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC;CAC5F"}
@@ -0,0 +1,13 @@
1
+ export class BaseDecorator {
2
+ inner;
3
+ constructor(inner) {
4
+ this.inner = inner;
5
+ }
6
+ get kind() {
7
+ return this.inner.kind;
8
+ }
9
+ canHandle(skill) {
10
+ return this.inner.canHandle(skill);
11
+ }
12
+ }
13
+ //# sourceMappingURL=base-decorator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-decorator.js","sourceRoot":"","sources":["../../src/decorators/base-decorator.ts"],"names":[],"mappings":"AAGA,MAAM,OAAgB,aAAa;IACd,KAAK,CAAqB;IAE7C,YAAY,KAAyB;QACnC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;IAED,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;IACzB,CAAC;IAED,SAAS,CAAC,KAAmB;QAC3B,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACrC,CAAC;CAGF"}
@@ -0,0 +1,33 @@
1
+ import { BaseDecorator } from './base-decorator.js';
2
+ import type { InvocationContext, InvocationResult, SkillContent } from '../core/types.js';
3
+ import type { InvocationStrategy } from '../handlers/invocation-strategy.js';
4
+ export interface CacheDecoratorDeps {
5
+ /** Default TTL in ms applied when skill.metadata.cacheTtlMs absent. */
6
+ ttlMs: number;
7
+ /** Max cached entries; oldest evicted (LRU via Map insertion order). */
8
+ maxEntries: number;
9
+ /** Injectable clock for deterministic tests. Defaults to Date.now(). */
10
+ clock?: () => number;
11
+ }
12
+ /**
13
+ * Decorator that caches successful InvocationResults per (skillName, input) pair.
14
+ *
15
+ * Caching is opt-in: enabled only when `skill.cacheable === true` or
16
+ * `skill.cacheTtlMs > 0`. Disabled skills pass through with zero overhead.
17
+ *
18
+ * Only `ok: true` results are cached. Caching failures would pin bad outputs
19
+ * for the entire TTL window — better to let the inner strategy retry each time.
20
+ *
21
+ * LRU eviction uses Map insertion-order: on a cache hit the entry is
22
+ * deleted and re-inserted so it becomes the most-recently-used position.
23
+ */
24
+ export declare class CacheDecorator extends BaseDecorator {
25
+ #private;
26
+ constructor(inner: InvocationStrategy, deps: CacheDecoratorDeps);
27
+ invoke(skill: SkillContent, context: InvocationContext): Promise<InvocationResult>;
28
+ /** Number of entries currently in the cache (including potentially stale). */
29
+ size(): number;
30
+ /** Remove all cached entries. */
31
+ clear(): void;
32
+ }
33
+ //# sourceMappingURL=cache-decorator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache-decorator.d.ts","sourceRoot":"","sources":["../../src/decorators/cache-decorator.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAC1F,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAE7E,MAAM,WAAW,kBAAkB;IACjC,uEAAuE;IACvE,KAAK,EAAE,MAAM,CAAC;IACd,wEAAwE;IACxE,UAAU,EAAE,MAAM,CAAC;IACnB,wEAAwE;IACxE,KAAK,CAAC,EAAE,MAAM,MAAM,CAAC;CACtB;AAeD;;;;;;;;;;;GAWG;AACH,qBAAa,cAAe,SAAQ,aAAa;;gBAMnC,KAAK,EAAE,kBAAkB,EAAE,IAAI,EAAE,kBAAkB;IAOzD,MAAM,CAAC,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAgCxF,8EAA8E;IAC9E,IAAI,IAAI,MAAM;IAId,iCAAiC;IACjC,KAAK,IAAI,IAAI;CAwBd"}
@@ -0,0 +1,89 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { BaseDecorator } from './base-decorator.js';
3
+ function hashKey(name, input) {
4
+ const h = createHash('sha256');
5
+ h.update(name);
6
+ h.update('\x00');
7
+ h.update(input);
8
+ return h.digest('hex').slice(0, 16);
9
+ }
10
+ /**
11
+ * Decorator that caches successful InvocationResults per (skillName, input) pair.
12
+ *
13
+ * Caching is opt-in: enabled only when `skill.cacheable === true` or
14
+ * `skill.cacheTtlMs > 0`. Disabled skills pass through with zero overhead.
15
+ *
16
+ * Only `ok: true` results are cached. Caching failures would pin bad outputs
17
+ * for the entire TTL window — better to let the inner strategy retry each time.
18
+ *
19
+ * LRU eviction uses Map insertion-order: on a cache hit the entry is
20
+ * deleted and re-inserted so it becomes the most-recently-used position.
21
+ */
22
+ export class CacheDecorator extends BaseDecorator {
23
+ #ttlMs;
24
+ #maxEntries;
25
+ #clock;
26
+ #store = new Map();
27
+ constructor(inner, deps) {
28
+ super(inner);
29
+ this.#ttlMs = deps.ttlMs;
30
+ this.#maxEntries = deps.maxEntries;
31
+ this.#clock = deps.clock ?? (() => Date.now());
32
+ }
33
+ async invoke(skill, context) {
34
+ if (!this.#isCacheable(skill)) {
35
+ return await this.inner.invoke(skill, context);
36
+ }
37
+ const key = hashKey(skill.name ?? '<unknown>', context.input);
38
+ const now = this.#clock();
39
+ const hit = this.#store.get(key);
40
+ if (hit !== undefined) {
41
+ if (hit.expiresAt > now) {
42
+ // Refresh LRU position: delete + reinsert moves key to newest slot.
43
+ this.#store.delete(key);
44
+ this.#store.set(key, hit);
45
+ return hit.result;
46
+ }
47
+ // Expired — evict stale entry before delegating.
48
+ this.#store.delete(key);
49
+ }
50
+ const result = await this.inner.invoke(skill, context);
51
+ // Only cache successful results to avoid pinning bad outputs across TTL.
52
+ if (result.ok) {
53
+ const ttl = this.#resolveTtl(skill);
54
+ this.#store.set(key, { result, expiresAt: now + ttl });
55
+ this.#evictIfFull();
56
+ }
57
+ return result;
58
+ }
59
+ /** Number of entries currently in the cache (including potentially stale). */
60
+ size() {
61
+ return this.#store.size;
62
+ }
63
+ /** Remove all cached entries. */
64
+ clear() {
65
+ this.#store.clear();
66
+ }
67
+ #isCacheable(skill) {
68
+ if (skill.cacheable === true)
69
+ return true;
70
+ if (typeof skill.cacheTtlMs === 'number' && skill.cacheTtlMs > 0)
71
+ return true;
72
+ return false;
73
+ }
74
+ #resolveTtl(skill) {
75
+ if (typeof skill.cacheTtlMs === 'number' && skill.cacheTtlMs > 0) {
76
+ return skill.cacheTtlMs;
77
+ }
78
+ return this.#ttlMs;
79
+ }
80
+ #evictIfFull() {
81
+ while (this.#store.size > this.#maxEntries) {
82
+ const oldestKey = this.#store.keys().next().value;
83
+ if (oldestKey === undefined)
84
+ break;
85
+ this.#store.delete(oldestKey);
86
+ }
87
+ }
88
+ }
89
+ //# sourceMappingURL=cache-decorator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache-decorator.js","sourceRoot":"","sources":["../../src/decorators/cache-decorator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAkBpD,SAAS,OAAO,CAAC,IAAY,EAAE,KAAa;IAC1C,MAAM,CAAC,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;IAC/B,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACf,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACjB,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAChB,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACtC,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,OAAO,cAAe,SAAQ,aAAa;IACtC,MAAM,CAAS;IACf,WAAW,CAAS;IACpB,MAAM,CAAe;IACrB,MAAM,GAAG,IAAI,GAAG,EAAsB,CAAC;IAEhD,YAAY,KAAyB,EAAE,IAAwB;QAC7D,KAAK,CAAC,KAAK,CAAC,CAAC;QACb,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC;QACzB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,UAAU,CAAC;QACnC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IACjD,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,KAAmB,EAAE,OAA0B;QAC1D,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;YAC9B,OAAO,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QACjD,CAAC;QAED,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,IAAI,WAAW,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;QAC9D,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAEjC,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YACtB,IAAI,GAAG,CAAC,SAAS,GAAG,GAAG,EAAE,CAAC;gBACxB,oEAAoE;gBACpE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBACxB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;gBAC1B,OAAO,GAAG,CAAC,MAAM,CAAC;YACpB,CAAC;YACD,iDAAiD;YACjD,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAEvD,yEAAyE;QACzE,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;YACd,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;YACpC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,GAAG,GAAG,EAAE,CAAC,CAAC;YACvD,IAAI,CAAC,YAAY,EAAE,CAAC;QACtB,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,8EAA8E;IAC9E,IAAI;QACF,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;IAC1B,CAAC;IAED,iCAAiC;IACjC,KAAK;QACH,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;IACtB,CAAC;IAED,YAAY,CAAC,KAAmB;QAC9B,IAAI,KAAK,CAAC,SAAS,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC;QAC1C,IAAI,OAAO,KAAK,CAAC,UAAU,KAAK,QAAQ,IAAI,KAAK,CAAC,UAAU,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC;QAC9E,OAAO,KAAK,CAAC;IACf,CAAC;IAED,WAAW,CAAC,KAAmB;QAC7B,IAAI,OAAO,KAAK,CAAC,UAAU,KAAK,QAAQ,IAAI,KAAK,CAAC,UAAU,GAAG,CAAC,EAAE,CAAC;YACjE,OAAO,KAAK,CAAC,UAAU,CAAC;QAC1B,CAAC;QACD,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED,YAAY;QACV,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;YAC3C,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC;YAClD,IAAI,SAAS,KAAK,SAAS;gBAAE,MAAM;YACnC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,16 @@
1
+ import type { Logger } from './logging-decorator.js';
2
+ import type { InvocationStrategy } from '../handlers/invocation-strategy.js';
3
+ export interface DecoratorChainDeps {
4
+ logger: Logger;
5
+ defaultTimeoutMs: number;
6
+ cacheTtlMs: number;
7
+ cacheMaxEntries: number;
8
+ clock?: () => number;
9
+ }
10
+ /** Composes Logging → Timeout → Cache → strategy (outermost-in). */
11
+ export declare class DecoratorChain {
12
+ #private;
13
+ constructor(deps: DecoratorChainDeps);
14
+ wrap(strategy: InvocationStrategy): InvocationStrategy;
15
+ }
16
+ //# sourceMappingURL=decorator-chain.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decorator-chain.d.ts","sourceRoot":"","sources":["../../src/decorators/decorator-chain.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAE7E,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,MAAM,CAAC;CACtB;AAED,oEAAoE;AACpE,qBAAa,cAAc;;gBAOb,IAAI,EAAE,kBAAkB;IAQpC,IAAI,CAAC,QAAQ,EAAE,kBAAkB,GAAG,kBAAkB;CAYvD"}
@@ -0,0 +1,31 @@
1
+ import { LoggingDecorator } from './logging-decorator.js';
2
+ import { TimeoutDecorator } from './timeout-decorator.js';
3
+ import { CacheDecorator } from './cache-decorator.js';
4
+ /** Composes Logging → Timeout → Cache → strategy (outermost-in). */
5
+ export class DecoratorChain {
6
+ #logger;
7
+ #defaultTimeoutMs;
8
+ #cacheTtlMs;
9
+ #cacheMaxEntries;
10
+ #clock;
11
+ constructor(deps) {
12
+ this.#logger = deps.logger;
13
+ this.#defaultTimeoutMs = deps.defaultTimeoutMs;
14
+ this.#cacheTtlMs = deps.cacheTtlMs;
15
+ this.#cacheMaxEntries = deps.cacheMaxEntries;
16
+ this.#clock = deps.clock;
17
+ }
18
+ wrap(strategy) {
19
+ const cached = new CacheDecorator(strategy, {
20
+ ttlMs: this.#cacheTtlMs,
21
+ maxEntries: this.#cacheMaxEntries,
22
+ clock: this.#clock,
23
+ });
24
+ const timed = new TimeoutDecorator(cached, {
25
+ defaultMs: this.#defaultTimeoutMs,
26
+ clock: this.#clock,
27
+ });
28
+ return new LoggingDecorator(timed, this.#logger, this.#clock);
29
+ }
30
+ }
31
+ //# sourceMappingURL=decorator-chain.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decorator-chain.js","sourceRoot":"","sources":["../../src/decorators/decorator-chain.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAYtD,oEAAoE;AACpE,MAAM,OAAO,cAAc;IAChB,OAAO,CAAS;IAChB,iBAAiB,CAAS;IAC1B,WAAW,CAAS;IACpB,gBAAgB,CAAS;IACzB,MAAM,CAAgB;IAE/B,YAAY,IAAwB;QAClC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC;QAC3B,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,gBAAgB,CAAC;QAC/C,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,UAAU,CAAC;QACnC,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,eAAe,CAAC;QAC7C,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC;IAC3B,CAAC;IAED,IAAI,CAAC,QAA4B;QAC/B,MAAM,MAAM,GAAG,IAAI,cAAc,CAAC,QAAQ,EAAE;YAC1C,KAAK,EAAE,IAAI,CAAC,WAAW;YACvB,UAAU,EAAE,IAAI,CAAC,gBAAgB;YACjC,KAAK,EAAE,IAAI,CAAC,MAAM;SACnB,CAAC,CAAC;QACH,MAAM,KAAK,GAAG,IAAI,gBAAgB,CAAC,MAAM,EAAE;YACzC,SAAS,EAAE,IAAI,CAAC,iBAAiB;YACjC,KAAK,EAAE,IAAI,CAAC,MAAM;SACnB,CAAC,CAAC;QACH,OAAO,IAAI,gBAAgB,CAAC,KAAK,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAChE,CAAC;CACF"}
@@ -0,0 +1,10 @@
1
+ export { BaseDecorator } from './base-decorator.js';
2
+ export { LoggingDecorator, stderrLogger } from './logging-decorator.js';
3
+ export type { Logger } from './logging-decorator.js';
4
+ export { TimeoutDecorator } from './timeout-decorator.js';
5
+ export type { TimeoutDecoratorDeps } from './timeout-decorator.js';
6
+ export { CacheDecorator } from './cache-decorator.js';
7
+ export type { CacheDecoratorDeps } from './cache-decorator.js';
8
+ export { DecoratorChain } from './decorator-chain.js';
9
+ export type { DecoratorChainDeps } from './decorator-chain.js';
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/decorators/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACxE,YAAY,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,YAAY,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,YAAY,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,YAAY,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,6 @@
1
+ export { BaseDecorator } from './base-decorator.js';
2
+ export { LoggingDecorator, stderrLogger } from './logging-decorator.js';
3
+ export { TimeoutDecorator } from './timeout-decorator.js';
4
+ export { CacheDecorator } from './cache-decorator.js';
5
+ export { DecoratorChain } from './decorator-chain.js';
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/decorators/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAExE,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE1D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { BaseDecorator } from './base-decorator.js';
2
+ import type { InvocationStrategy } from '../handlers/invocation-strategy.js';
3
+ import type { InvocationContext, InvocationResult, SkillContent } from '../core/types.js';
4
+ export interface Logger {
5
+ info(message: string): void;
6
+ warn(message: string): void;
7
+ error(message: string): void;
8
+ }
9
+ export declare const stderrLogger: Logger;
10
+ export declare class LoggingDecorator extends BaseDecorator {
11
+ #private;
12
+ constructor(inner: InvocationStrategy, logger?: Logger, clock?: () => number);
13
+ invoke(skill: SkillContent, context: InvocationContext): Promise<InvocationResult>;
14
+ }
15
+ //# sourceMappingURL=logging-decorator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logging-decorator.d.ts","sourceRoot":"","sources":["../../src/decorators/logging-decorator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAC7E,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAE1F,MAAM,WAAW,MAAM;IACrB,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,eAAO,MAAM,YAAY,EAAE,MAI1B,CAAC;AAEF,qBAAa,gBAAiB,SAAQ,aAAa;;gBAIrC,KAAK,EAAE,kBAAkB,EAAE,MAAM,GAAE,MAAqB,EAAE,KAAK,GAAE,MAAM,MAAgC;IAM7G,MAAM,CAAC,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC;CAiBzF"}
@@ -0,0 +1,34 @@
1
+ import { BaseDecorator } from './base-decorator.js';
2
+ export const stderrLogger = {
3
+ info: (m) => process.stderr.write(m + '\n'),
4
+ warn: (m) => process.stderr.write(m + '\n'),
5
+ error: (m) => process.stderr.write(m + '\n'),
6
+ };
7
+ export class LoggingDecorator extends BaseDecorator {
8
+ #logger;
9
+ #clock;
10
+ constructor(inner, logger = stderrLogger, clock = () => performance.now()) {
11
+ super(inner);
12
+ this.#logger = logger;
13
+ this.#clock = clock;
14
+ }
15
+ async invoke(skill, context) {
16
+ const name = skill.name ?? '<unknown>';
17
+ const kind = this.inner.kind;
18
+ this.#logger.info(`[skillforge] invoke skill=${name} kind=${kind}`);
19
+ const start = this.#clock();
20
+ try {
21
+ const result = await this.inner.invoke(skill, context);
22
+ const ms = Math.round(this.#clock() - start);
23
+ this.#logger.info(`[skillforge] result skill=${name} ok=${result.ok} ms=${ms}`);
24
+ return result;
25
+ }
26
+ catch (err) {
27
+ const ms = Math.round(this.#clock() - start);
28
+ const errMsg = err instanceof Error ? err.message : String(err);
29
+ this.#logger.error(`[skillforge] error skill=${name} ms=${ms} reason=${errMsg}`);
30
+ throw err;
31
+ }
32
+ }
33
+ }
34
+ //# sourceMappingURL=logging-decorator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logging-decorator.js","sourceRoot":"","sources":["../../src/decorators/logging-decorator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAUpD,MAAM,CAAC,MAAM,YAAY,GAAW;IAClC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC;IAC3C,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC;IAC3C,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC;CAC7C,CAAC;AAEF,MAAM,OAAO,gBAAiB,SAAQ,aAAa;IACxC,OAAO,CAAS;IAChB,MAAM,CAAe;IAE9B,YAAY,KAAyB,EAAE,SAAiB,YAAY,EAAE,QAAsB,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE;QACjH,KAAK,CAAC,KAAK,CAAC,CAAC;QACb,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;QACtB,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;IACtB,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,KAAmB,EAAE,OAA0B;QAC1D,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,IAAI,WAAW,CAAC;QACvC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;QAC7B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,6BAA6B,IAAI,SAAS,IAAI,EAAE,CAAC,CAAC;QACpE,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC5B,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;YACvD,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC;YAC7C,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,6BAA6B,IAAI,OAAO,MAAM,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC;YAChF,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC;YAC7C,MAAM,MAAM,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAChE,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,4BAA4B,IAAI,OAAO,EAAE,WAAW,MAAM,EAAE,CAAC,CAAC;YACjF,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,19 @@
1
+ import { BaseDecorator } from './base-decorator.js';
2
+ import type { InvocationStrategy } from '../handlers/invocation-strategy.js';
3
+ import type { InvocationContext, InvocationResult, SkillContent } from '../core/types.js';
4
+ export interface TimeoutDecoratorDeps {
5
+ /** Default timeout ms applied when skill.metadata.timeoutMs absent. */
6
+ defaultMs: number;
7
+ /** Injectable setTimeout for deterministic tests. */
8
+ setTimeoutFn?: typeof setTimeout;
9
+ /** Injectable clearTimeout for deterministic tests. */
10
+ clearTimeoutFn?: typeof clearTimeout;
11
+ /** Injectable clock for durationMs measurement. */
12
+ clock?: () => number;
13
+ }
14
+ export declare class TimeoutDecorator extends BaseDecorator {
15
+ #private;
16
+ constructor(inner: InvocationStrategy, deps: TimeoutDecoratorDeps);
17
+ invoke(skill: SkillContent, context: InvocationContext): Promise<InvocationResult>;
18
+ }
19
+ //# sourceMappingURL=timeout-decorator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timeout-decorator.d.ts","sourceRoot":"","sources":["../../src/decorators/timeout-decorator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAC7E,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAE1F,MAAM,WAAW,oBAAoB;IACnC,uEAAuE;IACvE,SAAS,EAAE,MAAM,CAAC;IAClB,qDAAqD;IACrD,YAAY,CAAC,EAAE,OAAO,UAAU,CAAC;IACjC,uDAAuD;IACvD,cAAc,CAAC,EAAE,OAAO,YAAY,CAAC;IACrC,mDAAmD;IACnD,KAAK,CAAC,EAAE,MAAM,MAAM,CAAC;CACtB;AAED,qBAAa,gBAAiB,SAAQ,aAAa;;gBAMrC,KAAK,EAAE,kBAAkB,EAAE,IAAI,EAAE,oBAAoB;IAQ3D,MAAM,CAAC,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC;CA+CzF"}