@decaf-ts/mcp-server 0.0.4 → 0.3.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 (210) hide show
  1. package/README.md +18 -2
  2. package/dist/mcp-server.cjs +1986 -340
  3. package/dist/mcp-server.esm.cjs +1960 -337
  4. package/lib/McpWrapper.cjs +9 -9
  5. package/lib/McpWrapper.d.ts +1 -1
  6. package/lib/bin/validate-modules.cjs +24 -0
  7. package/lib/bin/validate-modules.d.ts +2 -0
  8. package/lib/constants.cjs +22 -2
  9. package/lib/constants.d.ts +16 -0
  10. package/lib/esm/McpWrapper.d.ts +1 -1
  11. package/lib/esm/McpWrapper.js +9 -9
  12. package/lib/esm/bin/validate-modules.d.ts +2 -0
  13. package/lib/esm/bin/validate-modules.js +22 -0
  14. package/lib/esm/constants.d.ts +16 -0
  15. package/lib/esm/constants.js +21 -1
  16. package/lib/esm/mcp/aggregateModules.d.ts +26 -0
  17. package/lib/esm/mcp/aggregateModules.js +185 -0
  18. package/lib/esm/mcp/code.d.ts +23 -0
  19. package/lib/esm/mcp/code.js +70 -0
  20. package/lib/esm/mcp/decorator-tools.js +237 -0
  21. package/lib/esm/mcp/fastmcp-wiring.d.ts +14 -0
  22. package/lib/esm/mcp/fastmcp-wiring.js +56 -0
  23. package/lib/esm/mcp/index.d.ts +7 -1
  24. package/lib/esm/mcp/index.js +26 -2
  25. package/lib/esm/mcp/mcp-module.d.ts +11 -0
  26. package/lib/esm/mcp/mcp-module.js +31 -0
  27. package/lib/esm/mcp/moduleRegistry.d.ts +12 -0
  28. package/lib/esm/mcp/moduleRegistry.js +46 -0
  29. package/lib/esm/mcp/prompts/index.d.ts +4 -0
  30. package/lib/esm/mcp/prompts/index.js +7 -0
  31. package/lib/esm/mcp/prompts/prompts.d.ts +22 -0
  32. package/lib/esm/mcp/prompts/prompts.js +197 -0
  33. package/lib/esm/mcp/resources/index.d.ts +1 -0
  34. package/lib/esm/mcp/resources/index.js +2 -0
  35. package/lib/esm/mcp/resources/resources.d.ts +2 -0
  36. package/lib/esm/mcp/resources/resources.js +69 -0
  37. package/lib/esm/mcp/schemas.d.ts +53 -0
  38. package/lib/esm/mcp/schemas.js +97 -0
  39. package/lib/esm/mcp/templates/codex-templates.d.ts +3 -0
  40. package/lib/esm/mcp/templates/codex-templates.js +33 -0
  41. package/lib/esm/mcp/templates/index.d.ts +71 -0
  42. package/lib/esm/mcp/templates/index.js +66 -0
  43. package/lib/esm/mcp/templates/resource-templates.d.ts +3 -0
  44. package/lib/esm/mcp/templates/resource-templates.js +60 -0
  45. package/lib/esm/mcp/templates/workspace-templates.d.ts +3 -0
  46. package/lib/esm/mcp/templates/workspace-templates.js +66 -0
  47. package/lib/esm/mcp/tools/codex-tools.d.ts +5 -0
  48. package/lib/esm/mcp/tools/codex-tools.js +244 -0
  49. package/lib/esm/mcp/tools/generateMcpModule.d.ts +9 -0
  50. package/lib/esm/mcp/tools/generateMcpModule.js +133 -0
  51. package/lib/esm/mcp/tools/index.d.ts +321 -0
  52. package/lib/esm/mcp/tools/index.js +29 -0
  53. package/lib/esm/mcp/tools/tools.d.ts +10 -0
  54. package/lib/esm/mcp/tools/tools.js +273 -0
  55. package/lib/esm/mcp/types.d.ts +66 -0
  56. package/lib/esm/mcp/types.js +2 -0
  57. package/lib/esm/mcp/utils.d.ts +4 -0
  58. package/lib/esm/mcp/utils.js +46 -0
  59. package/lib/esm/mcp/validation/index.d.ts +13 -0
  60. package/lib/esm/mcp/validation/index.js +116 -0
  61. package/lib/esm/mcp/validation/scaffoldModule.d.ts +9 -0
  62. package/lib/esm/mcp/validation/scaffoldModule.js +88 -0
  63. package/lib/esm/mcp/workspace.d.ts +9 -0
  64. package/lib/esm/mcp/workspace.js +73 -0
  65. package/lib/esm/metadata.d.ts +1 -1
  66. package/lib/esm/metadata.js +1 -1
  67. package/lib/esm/modules/_template/index.d.ts +32 -0
  68. package/lib/esm/modules/_template/index.js +16 -0
  69. package/lib/esm/modules/_template/prompts/index.d.ts +6 -0
  70. package/lib/esm/modules/_template/prompts/index.js +9 -0
  71. package/lib/esm/modules/_template/resources/index.d.ts +6 -0
  72. package/lib/esm/modules/_template/resources/index.js +9 -0
  73. package/lib/esm/modules/_template/templates/index.d.ts +7 -0
  74. package/lib/esm/modules/_template/templates/index.js +10 -0
  75. package/lib/esm/modules/_template/tools/index.d.ts +6 -0
  76. package/lib/esm/modules/_template/tools/index.js +15 -0
  77. package/lib/esm/modules/decoration/index.d.ts +46 -0
  78. package/lib/esm/modules/decoration/index.js +10 -2
  79. package/lib/esm/modules/decoration/prompts/index.d.ts +1 -0
  80. package/lib/esm/modules/decoration/prompts/index.js +2 -0
  81. package/lib/esm/modules/decoration/resources/index.d.ts +7 -0
  82. package/lib/esm/modules/decoration/resources/index.js +10 -0
  83. package/lib/esm/modules/decoration/templates/index.d.ts +6 -0
  84. package/lib/esm/modules/decoration/templates/index.js +9 -0
  85. package/lib/esm/modules/decoration/tools/index.d.ts +26 -0
  86. package/lib/esm/modules/decoration/tools/index.js +7 -0
  87. package/lib/esm/modules/index.d.ts +2 -0
  88. package/lib/esm/modules/index.js +10 -0
  89. package/lib/esm/modules/mcp/decoration-assist.d.ts +3 -38
  90. package/lib/esm/modules/mcp/decoration-assist.js +5 -352
  91. package/lib/esm/modules/mcp/index.d.ts +6 -2
  92. package/lib/esm/modules/mcp/index.js +16 -3
  93. package/lib/esm/modules/mcp/prompts/index.d.ts +2 -0
  94. package/lib/esm/modules/mcp/prompts/index.js +9 -0
  95. package/lib/esm/modules/mcp/resources/index.d.ts +2 -0
  96. package/lib/esm/modules/mcp/resources/index.js +24 -0
  97. package/lib/esm/modules/mcp/templates/index.d.ts +2 -0
  98. package/lib/esm/modules/mcp/templates/index.js +28 -0
  99. package/lib/esm/modules/mcp/tools/index.d.ts +6 -0
  100. package/lib/esm/modules/mcp/tools/index.js +15 -0
  101. package/lib/esm/types.d.ts +41 -1
  102. package/lib/esm/types.js +1 -1
  103. package/lib/esm/utils/modulePaths.d.ts +6 -0
  104. package/lib/esm/utils/modulePaths.js +33 -0
  105. package/lib/esm/utils/moduleValidator.d.ts +14 -0
  106. package/lib/esm/utils/moduleValidator.js +176 -0
  107. package/lib/esm/utils.d.ts +1 -0
  108. package/lib/esm/utils.js +2 -1
  109. package/lib/mcp/aggregateModules.cjs +225 -0
  110. package/lib/mcp/aggregateModules.d.ts +26 -0
  111. package/lib/mcp/code.cjs +81 -0
  112. package/lib/mcp/code.d.ts +23 -0
  113. package/lib/mcp/decorator-tools.cjs +243 -0
  114. package/lib/mcp/fastmcp-wiring.cjs +59 -0
  115. package/lib/mcp/fastmcp-wiring.d.ts +14 -0
  116. package/lib/mcp/index.cjs +47 -12
  117. package/lib/mcp/index.d.ts +7 -1
  118. package/lib/mcp/mcp-module.cjs +53 -0
  119. package/lib/mcp/mcp-module.d.ts +11 -0
  120. package/lib/mcp/moduleRegistry.cjs +50 -0
  121. package/lib/mcp/moduleRegistry.d.ts +12 -0
  122. package/lib/mcp/prompts/index.cjs +25 -0
  123. package/lib/mcp/prompts/index.d.ts +4 -0
  124. package/lib/mcp/prompts/prompts.cjs +211 -0
  125. package/lib/mcp/prompts/prompts.d.ts +22 -0
  126. package/lib/mcp/resources/index.cjs +18 -0
  127. package/lib/mcp/resources/index.d.ts +1 -0
  128. package/lib/mcp/resources/resources.cjs +72 -0
  129. package/lib/mcp/resources/resources.d.ts +2 -0
  130. package/lib/mcp/schemas.cjs +100 -0
  131. package/lib/mcp/schemas.d.ts +53 -0
  132. package/lib/mcp/templates/codex-templates.cjs +40 -0
  133. package/lib/mcp/templates/codex-templates.d.ts +3 -0
  134. package/lib/mcp/templates/index.cjs +76 -0
  135. package/lib/mcp/templates/index.d.ts +71 -0
  136. package/lib/mcp/templates/resource-templates.cjs +67 -0
  137. package/lib/mcp/templates/resource-templates.d.ts +3 -0
  138. package/lib/mcp/templates/workspace-templates.cjs +70 -0
  139. package/lib/mcp/templates/workspace-templates.d.ts +3 -0
  140. package/lib/mcp/tools/codex-tools.cjs +250 -0
  141. package/lib/mcp/tools/codex-tools.d.ts +5 -0
  142. package/lib/mcp/tools/generateMcpModule.cjs +139 -0
  143. package/lib/mcp/tools/generateMcpModule.d.ts +9 -0
  144. package/lib/mcp/tools/index.cjs +46 -0
  145. package/lib/mcp/tools/index.d.ts +321 -0
  146. package/lib/mcp/tools/tools.cjs +282 -0
  147. package/lib/mcp/tools/tools.d.ts +10 -0
  148. package/lib/mcp/types.cjs +3 -0
  149. package/lib/mcp/types.d.ts +66 -0
  150. package/lib/mcp/utils.cjs +54 -0
  151. package/lib/mcp/utils.d.ts +4 -0
  152. package/lib/mcp/validation/index.cjs +123 -0
  153. package/lib/mcp/validation/index.d.ts +13 -0
  154. package/lib/mcp/validation/scaffoldModule.cjs +94 -0
  155. package/lib/mcp/validation/scaffoldModule.d.ts +9 -0
  156. package/lib/mcp/workspace.cjs +119 -0
  157. package/lib/mcp/workspace.d.ts +9 -0
  158. package/lib/metadata.cjs +1 -1
  159. package/lib/metadata.d.ts +1 -1
  160. package/lib/modules/_template/index.cjs +23 -0
  161. package/lib/modules/_template/index.d.ts +32 -0
  162. package/lib/modules/_template/prompts/index.cjs +12 -0
  163. package/lib/modules/_template/prompts/index.d.ts +6 -0
  164. package/lib/modules/_template/resources/index.cjs +12 -0
  165. package/lib/modules/_template/resources/index.d.ts +6 -0
  166. package/lib/modules/_template/templates/index.cjs +13 -0
  167. package/lib/modules/_template/templates/index.d.ts +7 -0
  168. package/lib/modules/_template/tools/index.cjs +18 -0
  169. package/lib/modules/_template/tools/index.d.ts +6 -0
  170. package/lib/modules/decoration/index.cjs +16 -1
  171. package/lib/modules/decoration/index.d.ts +46 -0
  172. package/lib/modules/decoration/prompts/index.cjs +5 -0
  173. package/lib/modules/decoration/prompts/index.d.ts +1 -0
  174. package/lib/modules/decoration/resources/index.cjs +13 -0
  175. package/lib/modules/decoration/resources/index.d.ts +7 -0
  176. package/lib/modules/decoration/templates/index.cjs +12 -0
  177. package/lib/modules/decoration/templates/index.d.ts +6 -0
  178. package/lib/modules/decoration/tools/index.cjs +10 -0
  179. package/lib/modules/decoration/tools/index.d.ts +26 -0
  180. package/lib/modules/index.cjs +13 -0
  181. package/lib/modules/index.d.ts +2 -0
  182. package/lib/modules/mcp/decoration-assist.cjs +8 -355
  183. package/lib/modules/mcp/decoration-assist.d.ts +3 -38
  184. package/lib/modules/mcp/index.cjs +21 -22
  185. package/lib/modules/mcp/index.d.ts +6 -2
  186. package/lib/modules/mcp/prompts/index.cjs +12 -0
  187. package/lib/modules/mcp/prompts/index.d.ts +2 -0
  188. package/lib/modules/mcp/resources/index.cjs +27 -0
  189. package/lib/modules/mcp/resources/index.d.ts +2 -0
  190. package/lib/modules/mcp/templates/index.cjs +31 -0
  191. package/lib/modules/mcp/templates/index.d.ts +2 -0
  192. package/lib/modules/mcp/tools/index.cjs +18 -0
  193. package/lib/modules/mcp/tools/index.d.ts +6 -0
  194. package/lib/types.cjs +1 -1
  195. package/lib/types.d.ts +41 -1
  196. package/lib/utils/modulePaths.cjs +43 -0
  197. package/lib/utils/modulePaths.d.ts +6 -0
  198. package/lib/utils/moduleValidator.cjs +184 -0
  199. package/lib/utils/moduleValidator.d.ts +14 -0
  200. package/lib/utils.cjs +5 -1
  201. package/lib/utils.d.ts +1 -0
  202. package/package.json +14 -13
  203. package/lib/esm/modules/mcp/decorator-tools.js +0 -237
  204. package/lib/esm/modules/mcp/mcp-module.d.ts +0 -230
  205. package/lib/esm/modules/mcp/mcp-module.js +0 -406
  206. package/lib/modules/mcp/decorator-tools.cjs +0 -243
  207. package/lib/modules/mcp/mcp-module.cjs +0 -452
  208. package/lib/modules/mcp/mcp-module.d.ts +0 -230
  209. /package/lib/esm/{modules/mcp → mcp}/decorator-tools.d.ts +0 -0
  210. /package/lib/{modules/mcp → mcp}/decorator-tools.d.ts +0 -0
@@ -0,0 +1,185 @@
1
+ // Aggregator: import module index files and merge exported arrays with provenance + duplicate detection
2
+ import path from "path";
3
+ import fs from "fs";
4
+ import { pathToFileURL } from "url";
5
+ import { findModuleDirs } from "./validation";
6
+ const SUBFOLDERS = ["prompts", "resources", "templates", "tools"];
7
+ const INDEX_CANDIDATES = [
8
+ "index.ts",
9
+ "index.tsx",
10
+ "index.js",
11
+ "index.cjs",
12
+ "index.mjs",
13
+ ];
14
+ function findIndexFile(folder) {
15
+ for (const c of INDEX_CANDIDATES) {
16
+ const f = path.join(folder, c);
17
+ if (fs.existsSync(f))
18
+ return f;
19
+ }
20
+ return undefined;
21
+ }
22
+ function makeKeyForItem(item) {
23
+ if (!item)
24
+ return JSON.stringify(item);
25
+ if (typeof item === "string")
26
+ return `str:${item}`;
27
+ if (typeof item === "number")
28
+ return `num:${item}`;
29
+ if (item.id)
30
+ return `id:${item.id}`;
31
+ if (item.name)
32
+ return `name:${item.name}`;
33
+ // fallback to stable string
34
+ try {
35
+ return `obj:${JSON.stringify(item)}`;
36
+ }
37
+ catch (e) {
38
+ return `obj:${String(item)}`;
39
+ }
40
+ }
41
+ async function loadArrayFromIndex(filePath) {
42
+ // Prefer a fast, static parse of the first array literal found in the file.
43
+ try {
44
+ const content = fs.readFileSync(filePath, "utf8");
45
+ const start = content.indexOf("[");
46
+ if (start !== -1) {
47
+ let depth = 0;
48
+ let end = -1;
49
+ for (let i = start; i < content.length; i++) {
50
+ const ch = content[i];
51
+ if (ch === "[")
52
+ depth++;
53
+ else if (ch === "]") {
54
+ depth--;
55
+ if (depth === 0) {
56
+ end = i;
57
+ break;
58
+ }
59
+ }
60
+ }
61
+ if (end !== -1) {
62
+ const arrText = content.slice(start, end + 1);
63
+ try {
64
+ return JSON.parse(arrText);
65
+ }
66
+ catch (e) {
67
+ // Normalize TS object literals to JSON:
68
+ // - convert single quotes to double quotes
69
+ // - quote unquoted object keys
70
+ // - strip trailing commas
71
+ const normalized = arrText
72
+ // unify quotes in string literals
73
+ .replace(/'(?:\\'|[^'])*'/g, (m) => m.replace(/'/g, '"'))
74
+ // quote unquoted keys after { or ,
75
+ .replace(/([\{,]\s*)([A-Za-z_$][\w$]*)(\s*:)/g, '$1"$2"$3')
76
+ // remove trailing commas before ] or }
77
+ .replace(/,(\s*[\}\]])/g, '$1');
78
+ try {
79
+ return JSON.parse(normalized);
80
+ }
81
+ catch (e2) {
82
+ // fallthrough to import attempt below
83
+ }
84
+ }
85
+ }
86
+ }
87
+ }
88
+ catch (e) {
89
+ // ignore static parse errors and fall back to import
90
+ }
91
+ try {
92
+ const fileUrl = pathToFileURL(filePath).href;
93
+ const mod = await import(fileUrl);
94
+ // Find first export that is an array
95
+ for (const key of Object.keys(mod)) {
96
+ const val = mod[key];
97
+ if (Array.isArray(val))
98
+ return val;
99
+ }
100
+ // default export check
101
+ if (Array.isArray(mod.default))
102
+ return mod.default;
103
+ return undefined;
104
+ }
105
+ catch (err) {
106
+ // fallback: if import fails, try to static-parse again (already attempted) and finally return undefined
107
+ return undefined;
108
+ }
109
+ }
110
+ export async function aggregateModules(repoRoot) {
111
+ const dirs = findModuleDirs(repoRoot);
112
+ const master = {
113
+ prompts: [],
114
+ resources: [],
115
+ templates: [],
116
+ tools: [],
117
+ conflicts: [],
118
+ };
119
+ // maps to detect duplicates per type
120
+ const maps = {
121
+ prompts: new Map(),
122
+ resources: new Map(),
123
+ templates: new Map(),
124
+ tools: new Map(),
125
+ };
126
+ for (const moduleDir of dirs) {
127
+ const moduleName = path.basename(moduleDir);
128
+ for (const sub of SUBFOLDERS) {
129
+ const folder = path.join(moduleDir, sub);
130
+ const indexFile = findIndexFile(folder);
131
+ if (!indexFile)
132
+ continue;
133
+ let arr;
134
+ try {
135
+ arr = await loadArrayFromIndex(indexFile);
136
+ }
137
+ catch (err) {
138
+ // skip module on import error but record as conflict-like issue
139
+ master.conflicts.push({
140
+ key: `import-error:${moduleName}:${sub}`,
141
+ existing: { moduleName, modulePath: moduleDir },
142
+ incoming: { moduleName, modulePath: moduleDir },
143
+ });
144
+ continue;
145
+ }
146
+ if (!arr || !Array.isArray(arr))
147
+ continue;
148
+ for (const item of arr) {
149
+ const key = makeKeyForItem(item);
150
+ const provenance = { moduleName, modulePath: moduleDir };
151
+ const map = maps[sub];
152
+ if (map.has(key)) {
153
+ // record conflict deterministically (existing vs incoming)
154
+ const existing = map.get(key);
155
+ master.conflicts.push({ key, existing, incoming: provenance });
156
+ // skip adding duplicate
157
+ continue;
158
+ }
159
+ map.set(key, provenance);
160
+ master[sub].push({ ...item, provenance });
161
+ }
162
+ }
163
+ }
164
+ return master;
165
+ }
166
+ // For compatibility with CommonJS call sites (not exported by ESM), provide a sync wrapper
167
+ export function aggregateModulesSync(repoRoot) {
168
+ // synchronous wrapper that runs the async function and blocks — suitable for small module sets
169
+ const p = aggregateModules(repoRoot);
170
+ let result;
171
+ let done = false;
172
+ p.then((r) => {
173
+ result = r;
174
+ done = true;
175
+ }).catch((e) => {
176
+ throw e;
177
+ });
178
+ // spin-wait (acceptable in small dev scripts)
179
+ const until = Date.now() + 5000;
180
+ while (!done && Date.now() < until) { }
181
+ if (!done)
182
+ throw new Error("aggregateModulesSync: timeout waiting for async aggregation");
183
+ return result;
184
+ }
185
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWdncmVnYXRlTW9kdWxlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9tY3AvYWdncmVnYXRlTW9kdWxlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSx3R0FBd0c7QUFDeEcsT0FBTyxJQUFJLE1BQU0sTUFBTSxDQUFDO0FBQ3hCLE9BQU8sRUFBRSxNQUFNLElBQUksQ0FBQztBQUNwQixPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sS0FBSyxDQUFDO0FBQ3BDLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFpQjlDLE1BQU0sVUFBVSxHQUFHLENBQUMsU0FBUyxFQUFFLFdBQVcsRUFBRSxXQUFXLEVBQUUsT0FBTyxDQUFDLENBQUM7QUFDbEUsTUFBTSxnQkFBZ0IsR0FBRztJQUN2QixVQUFVO0lBQ1YsV0FBVztJQUNYLFVBQVU7SUFDVixXQUFXO0lBQ1gsV0FBVztDQUNaLENBQUM7QUFFRixTQUFTLGFBQWEsQ0FBQyxNQUFjO0lBQ25DLEtBQUssTUFBTSxDQUFDLElBQUksZ0JBQWdCLEVBQUUsQ0FBQztRQUNqQyxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQztRQUMvQixJQUFJLEVBQUUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO1lBQUUsT0FBTyxDQUFDLENBQUM7SUFDakMsQ0FBQztJQUNELE9BQU8sU0FBUyxDQUFDO0FBQ25CLENBQUM7QUFFRCxTQUFTLGNBQWMsQ0FBQyxJQUFTO0lBQy9CLElBQUksQ0FBQyxJQUFJO1FBQUUsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3ZDLElBQUksT0FBTyxJQUFJLEtBQUssUUFBUTtRQUFFLE9BQU8sT0FBTyxJQUFJLEVBQUUsQ0FBQztJQUNuRCxJQUFJLE9BQU8sSUFBSSxLQUFLLFFBQVE7UUFBRSxPQUFPLE9BQU8sSUFBSSxFQUFFLENBQUM7SUFDbkQs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Q0FDOUQsQ0FBQztJQUNKLE9BQU8sTUFBMkIsQ0FBQztBQUNyQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQWdncmVnYXRvcjogaW1wb3J0IG1vZHVsZSBpbmRleCBmaWxlcyBhbmQgbWVyZ2UgZXhwb3J0ZWQgYXJyYXlzIHdpdGggcHJvdmVuYW5jZSArIGR1cGxpY2F0ZSBkZXRlY3Rpb25cbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XG5pbXBvcnQgZnMgZnJvbSBcImZzXCI7XG5pbXBvcnQgeyBwYXRoVG9GaWxlVVJMIH0gZnJvbSBcInVybFwiO1xuaW1wb3J0IHsgZmluZE1vZHVsZURpcnMgfSBmcm9tIFwiLi92YWxpZGF0aW9uXCI7XG5cbmV4cG9ydCB0eXBlIFByb3ZlbmFuY2UgPSB7IG1vZHVsZU5hbWU6IHN0cmluZzsgbW9kdWxlUGF0aDogc3RyaW5nIH07XG5leHBvcnQgdHlwZSBBZ2dyZWdhdGlvbkNvbmZsaWN0ID0ge1xuICBrZXk6IHN0cmluZztcbiAgZXhpc3Rpbmc6IFByb3ZlbmFuY2U7XG4gIGluY29taW5nOiBQcm92ZW5hbmNlO1xufTtcblxuZXhwb3J0IHR5cGUgQWdncmVnYXRpb25SZXN1bHQ8VCA9IGFueT4gPSB7XG4gIHByb21wdHM6IEFycmF5PFQgJiB7IHByb3ZlbmFuY2U6IFByb3ZlbmFuY2UgfT47XG4gIHJlc291cmNlczogQXJyYXk8VCAmIHsgcHJvdmVuYW5jZTogUHJvdmVuYW5jZSB9PjtcbiAgdGVtcGxhdGVzOiBBcnJheTxUICYgeyBwcm92ZW5hbmNlOiBQcm92ZW5hbmNlIH0+O1xuICB0b29sczogQXJyYXk8VCAmIHsgcHJvdmVuYW5jZTogUHJvdmVuYW5jZSB9PjtcbiAgY29uZmxpY3RzOiBBZ2dyZWdhdGlvbkNvbmZsaWN0W107XG59O1xuXG5jb25zdCBTVUJGT0xERVJTID0gW1wicHJvbXB0c1wiLCBcInJlc291cmNlc1wiLCBcInRlbXBsYXRlc1wiLCBcInRvb2xzXCJdO1xuY29uc3QgSU5ERVhfQ0FORElEQVRFUyA9IFtcbiAgXCJpbmRleC50c1wiLFxuICBcImluZGV4LnRzeFwiLFxuICBcImluZGV4LmpzXCIsXG4gIFwiaW5kZXguY2pzXCIsXG4gIFwiaW5kZXgubWpzXCIsXG5dO1xuXG5mdW5jdGlvbiBmaW5kSW5kZXhGaWxlKGZvbGRlcjogc3RyaW5nKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgZm9yIChjb25zdCBjIG9mIElOREVYX0NBTkRJREFURVMpIHtcbiAgICBjb25zdCBmID0gcGF0aC5qb2luKGZvbGRlciwgYyk7XG4gICAgaWYgKGZzLmV4aXN0c1N5bmMoZikpIHJldHVybiBmO1xuICB9XG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbmZ1bmN0aW9uIG1ha2VLZXlGb3JJdGVtKGl0ZW06IGFueSk6IHN0cmluZyB7XG4gIGlmICghaXRlbSkgcmV0dXJuIEpTT04uc3RyaW5naWZ5KGl0ZW0pO1xuICBpZiAodHlwZW9mIGl0ZW0gPT09IFwic3RyaW5nXCIpIHJldHVybiBgc3RyOiR7aXRlbX1gO1xuICBpZiAodHlwZW9mIGl0ZW0gPT09IFwibnVtYmVyXCIpIHJldHVybiBgbnVtOiR7aXRlbX1gO1xuICBpZiAoaXRlbS5pZCkgcmV0dXJuIGBpZDoke2l0ZW0uaWR9YDtcbiAgaWYgKGl0ZW0ubmFtZSkgcmV0dXJuIGBuYW1lOiR7aXRlbS5uYW1lfWA7XG4gIC8vIGZhbGxiYWNrIHRvIHN0YWJsZSBzdHJpbmdcbiAgdHJ5IHtcbiAgICByZXR1cm4gYG9iajoke0pTT04uc3RyaW5naWZ5KGl0ZW0pfWA7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4gYG9iajoke1N0cmluZyhpdGVtKX1gO1xuICB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGxvYWRBcnJheUZyb21JbmRleChcbiAgZmlsZVBhdGg6IHN0cmluZ1xuKTogUHJvbWlzZTxhbnlbXSB8IHVuZGVmaW5lZD4ge1xuICAvLyBQcmVmZXIgYSBmYXN0LCBzdGF0aWMgcGFyc2Ugb2YgdGhlIGZpcnN0IGFycmF5IGxpdGVyYWwgZm91bmQgaW4gdGhlIGZpbGUuXG4gIHRyeSB7XG4gICAgY29uc3QgY29udGVudCA9IGZzLnJlYWRGaWxlU3luYyhmaWxlUGF0aCwgXCJ1dGY4XCIpO1xuICAgIGNvbnN0IHN0YXJ0ID0gY29udGVudC5pbmRleE9mKFwiW1wiKTtcbiAgICBpZiAoc3RhcnQgIT09IC0xKSB7XG4gICAgICBsZXQgZGVwdGggPSAwO1xuICAgICAgbGV0IGVuZCA9IC0xO1xuICAgICAgZm9yIChsZXQgaSA9IHN0YXJ0OyBpIDwgY29udGVudC5sZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCBjaCA9IGNvbnRlbnRbaV07XG4gICAgICAgIGlmIChjaCA9PT0gXCJbXCIpIGRlcHRoKys7XG4gICAgICAgIGVsc2UgaWYgKGNoID09PSBcIl1cIikge1xuICAgICAgICAgIGRlcHRoLS07XG4gICAgICAgICAgaWYgKGRlcHRoID09PSAwKSB7XG4gICAgICAgICAgICBlbmQgPSBpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoZW5kICE9PSAtMSkge1xuICAgICAgICBjb25zdCBhcnJUZXh0ID0gY29udGVudC5zbGljZShzdGFydCwgZW5kICsgMSk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgcmV0dXJuIEpTT04ucGFyc2UoYXJyVGV4dCk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAvLyBOb3JtYWxpemUgVFMgb2JqZWN0IGxpdGVyYWxzIHRvIEpTT046XG4gICAgICAgICAgLy8gLSBjb252ZXJ0IHNpbmdsZSBxdW90ZXMgdG8gZG91YmxlIHF1b3Rlc1xuICAgICAgICAgIC8vIC0gcXVvdGUgdW5xdW90ZWQgb2JqZWN0IGtleXNcbiAgICAgICAgICAvLyAtIHN0cmlwIHRyYWlsaW5nIGNvbW1hc1xuICAgICAgICAgIGNvbnN0IG5vcm1hbGl6ZWQgPSBhcnJUZXh0XG4gICAgICAgICAgICAvLyB1bmlmeSBxdW90ZXMgaW4gc3RyaW5nIGxpdGVyYWxzXG4gICAgICAgICAgICAucmVwbGFjZSgvJyg/OlxcXFwnfFteJ10pKicvZywgKG0pID0+IG0ucmVwbGFjZSgvJy9nLCAnXCInKSlcbiAgICAgICAgICAgIC8vIHF1b3RlIHVucXVvdGVkIGtleXMgYWZ0ZXIgeyBvciAsXG4gICAgICAgICAgICAucmVwbGFjZSgvKFtcXHssXVxccyopKFtBLVphLXpfJF1bXFx3JF0qKShcXHMqOikvZywgJyQxXCIkMlwiJDMnKVxuICAgICAgICAgICAgLy8gcmVtb3ZlIHRyYWlsaW5nIGNvbW1hcyBiZWZvcmUgXSBvciB9XG4gICAgICAgICAgICAucmVwbGFjZSgvLChcXHMqW1xcfVxcXV0pL2csICckMScpO1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gSlNPTi5wYXJzZShub3JtYWxpemVkKTtcbiAgICAgICAgICB9IGNhdGNoIChlMikge1xuICAgICAgICAgICAgLy8gZmFsbHRocm91Z2ggdG8gaW1wb3J0IGF0dGVtcHQgYmVsb3dcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICAvLyBpZ25vcmUgc3RhdGljIHBhcnNlIGVycm9ycyBhbmQgZmFsbCBiYWNrIHRvIGltcG9ydFxuICB9XG5cbiAgdHJ5IHtcbiAgICBjb25zdCBmaWxlVXJsID0gcGF0aFRvRmlsZVVSTChmaWxlUGF0aCkuaHJlZjtcbiAgICBjb25zdCBtb2QgPSBhd2FpdCBpbXBvcnQoZmlsZVVybCk7XG4gICAgLy8gRmluZCBmaXJzdCBleHBvcnQgdGhhdCBpcyBhbiBhcnJheVxuICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKG1vZCkpIHtcbiAgICAgIGNvbnN0IHZhbCA9IChtb2QgYXMgYW55KVtrZXldO1xuICAgICAgaWYgKEFycmF5LmlzQXJyYXkodmFsKSkgcmV0dXJuIHZhbDtcbiAgICB9XG4gICAgLy8gZGVmYXVsdCBleHBvcnQgY2hlY2tcbiAgICBpZiAoQXJyYXkuaXNBcnJheSgobW9kIGFzIGFueSkuZGVmYXVsdCkpIHJldHVybiAobW9kIGFzIGFueSkuZGVmYXVsdDtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICAvLyBmYWxsYmFjazogaWYgaW1wb3J0IGZhaWxzLCB0cnkgdG8gc3RhdGljLXBhcnNlIGFnYWluIChhbHJlYWR5IGF0dGVtcHRlZCkgYW5kIGZpbmFsbHkgcmV0dXJuIHVuZGVmaW5lZFxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGFnZ3JlZ2F0ZU1vZHVsZXMoXG4gIHJlcG9Sb290OiBzdHJpbmdcbik6IFByb21pc2U8QWdncmVnYXRpb25SZXN1bHQ+IHtcbiAgY29uc3QgZGlycyA9IGZpbmRNb2R1bGVEaXJzKHJlcG9Sb290KTtcbiAgY29uc3QgbWFzdGVyID0ge1xuICAgIHByb21wdHM6IFtdIGFzIGFueVtdLFxuICAgIHJlc291cmNlczogW10gYXMgYW55W10sXG4gICAgdGVtcGxhdGVzOiBbXSBhcyBhbnlbXSxcbiAgICB0b29sczogW10gYXMgYW55W10sXG4gICAgY29uZmxpY3RzOiBbXSBhcyBBZ2dyZWdhdGlvbkNvbmZsaWN0W10sXG4gIH07XG5cbiAgLy8gbWFwcyB0byBkZXRlY3QgZHVwbGljYXRlcyBwZXIgdHlwZVxuICBjb25zdCBtYXBzOiBSZWNvcmQ8c3RyaW5nLCBNYXA8c3RyaW5nLCBQcm92ZW5hbmNlPj4gPSB7XG4gICAgcHJvbXB0czogbmV3IE1hcCgpLFxuICAgIHJlc291cmNlczogbmV3IE1hcCgpLFxuICAgIHRlbXBsYXRlczogbmV3IE1hcCgpLFxuICAgIHRvb2xzOiBuZXcgTWFwKCksXG4gIH07XG5cbiAgZm9yIChjb25zdCBtb2R1bGVEaXIgb2YgZGlycykge1xuICAgIGNvbnN0IG1vZHVsZU5hbWUgPSBwYXRoLmJhc2VuYW1lKG1vZHVsZURpcik7XG4gICAgZm9yIChjb25zdCBzdWIgb2YgU1VCRk9MREVSUykge1xuICAgICAgY29uc3QgZm9sZGVyID0gcGF0aC5qb2luKG1vZHVsZURpciwgc3ViKTtcbiAgICAgIGNvbnN0IGluZGV4RmlsZSA9IGZpbmRJbmRleEZpbGUoZm9sZGVyKTtcbiAgICAgIGlmICghaW5kZXhGaWxlKSBjb250aW51ZTtcbiAgICAgIGxldCBhcnI6IGFueVtdIHwgdW5kZWZpbmVkO1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXJyID0gYXdhaXQgbG9hZEFycmF5RnJvbUluZGV4KGluZGV4RmlsZSk7XG4gICAgICB9IGNhdGNoIChlcnI6IGFueSkge1xuICAgICAgICAvLyBza2lwIG1vZHVsZSBvbiBpbXBvcnQgZXJyb3IgYnV0IHJlY29yZCBhcyBjb25mbGljdC1saWtlIGlzc3VlXG4gICAgICAgIG1hc3Rlci5jb25mbGljdHMucHVzaCh7XG4gICAgICAgICAga2V5OiBgaW1wb3J0LWVycm9yOiR7bW9kdWxlTmFtZX06JHtzdWJ9YCxcbiAgICAgICAgICBleGlzdGluZzogeyBtb2R1bGVOYW1lLCBtb2R1bGVQYXRoOiBtb2R1bGVEaXIgfSxcbiAgICAgICAgICBpbmNvbWluZzogeyBtb2R1bGVOYW1lLCBtb2R1bGVQYXRoOiBtb2R1bGVEaXIgfSxcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgaWYgKCFhcnIgfHwgIUFycmF5LmlzQXJyYXkoYXJyKSkgY29udGludWU7XG5cbiAgICAgIGZvciAoY29uc3QgaXRlbSBvZiBhcnIpIHtcbiAgICAgICAgY29uc3Qga2V5ID0gbWFrZUtleUZvckl0ZW0oaXRlbSk7XG4gICAgICAgIGNvbnN0IHByb3ZlbmFuY2UgPSB7IG1vZHVsZU5hbWUsIG1vZHVsZVBhdGg6IG1vZHVsZURpciB9O1xuICAgICAgICBjb25zdCBtYXAgPSBtYXBzW3N1Yl07XG4gICAgICAgIGlmIChtYXAuaGFzKGtleSkpIHtcbiAgICAgICAgICAvLyByZWNvcmQgY29uZmxpY3QgZGV0ZXJtaW5pc3RpY2FsbHkgKGV4aXN0aW5nIHZzIGluY29taW5nKVxuICAgICAgICAgIGNvbnN0IGV4aXN0aW5nID0gbWFwLmdldChrZXkpITtcbiAgICAgICAgICBtYXN0ZXIuY29uZmxpY3RzLnB1c2goeyBrZXksIGV4aXN0aW5nLCBpbmNvbWluZzogcHJvdmVuYW5jZSB9KTtcbiAgICAgICAgICAvLyBza2lwIGFkZGluZyBkdXBsaWNhdGVcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBtYXAuc2V0KGtleSwgcHJvdmVuYW5jZSk7XG4gICAgICAgIChtYXN0ZXIgYXMgYW55KVtzdWJdLnB1c2goeyAuLi5pdGVtLCBwcm92ZW5hbmNlIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBtYXN0ZXI7XG59XG5cbi8vIEZvciBjb21wYXRpYmlsaXR5IHdpdGggQ29tbW9uSlMgY2FsbCBzaXRlcyAobm90IGV4cG9ydGVkIGJ5IEVTTSksIHByb3ZpZGUgYSBzeW5jIHdyYXBwZXJcbmV4cG9ydCBmdW5jdGlvbiBhZ2dyZWdhdGVNb2R1bGVzU3luYyhyZXBvUm9vdDogc3RyaW5nKSB7XG4gIC8vIHN5bmNocm9ub3VzIHdyYXBwZXIgdGhhdCBydW5zIHRoZSBhc3luYyBmdW5jdGlvbiBhbmQgYmxvY2tzIOKAlCBzdWl0YWJsZSBmb3Igc21hbGwgbW9kdWxlIHNldHNcbiAgY29uc3QgcCA9IGFnZ3JlZ2F0ZU1vZHVsZXMocmVwb1Jvb3QpO1xuICBsZXQgcmVzdWx0OiBhbnk7XG4gIGxldCBkb25lID0gZmFsc2U7XG4gIHAudGhlbigocikgPT4ge1xuICAgIHJlc3VsdCA9IHI7XG4gICAgZG9uZSA9IHRydWU7XG4gIH0pLmNhdGNoKChlKSA9PiB7XG4gICAgdGhyb3cgZTtcbiAgfSk7XG4gIC8vIHNwaW4td2FpdCAoYWNjZXB0YWJsZSBpbiBzbWFsbCBkZXYgc2NyaXB0cylcbiAgY29uc3QgdW50aWwgPSBEYXRlLm5vdygpICsgNTAwMDtcbiAgd2hpbGUgKCFkb25lICYmIERhdGUubm93KCkgPCB1bnRpbCkge31cbiAgaWYgKCFkb25lKVxuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIFwiYWdncmVnYXRlTW9kdWxlc1N5bmM6IHRpbWVvdXQgd2FpdGluZyBmb3IgYXN5bmMgYWdncmVnYXRpb25cIlxuICAgICk7XG4gIHJldHVybiByZXN1bHQgYXMgQWdncmVnYXRpb25SZXN1bHQ7XG59XG4iXX0=
@@ -0,0 +1,23 @@
1
+ export declare function isSourceFile(p: string): boolean;
2
+ export declare function isTestFile(p: string): boolean;
3
+ export declare function extractExports(fileContent: string): string[];
4
+ export declare function extractDecorators(fileContent: string): string[];
5
+ export declare function summarizeReadme(readme?: string): {
6
+ title: string;
7
+ bullets: string[];
8
+ } | undefined;
9
+ export declare function analyzeRepo(root: string): {
10
+ files: string[];
11
+ testFiles: string[];
12
+ api: Record<string, {
13
+ exports: string[];
14
+ decorators: string[];
15
+ }>;
16
+ tests: Record<string, {
17
+ mentions: string[];
18
+ }>;
19
+ readme: {
20
+ title: string;
21
+ bullets: string[];
22
+ } | undefined;
23
+ };
@@ -0,0 +1,70 @@
1
+ // Analysis helpers (minimal yet effective, text-based to avoid heavy AST deps)
2
+ import path from "path";
3
+ import fs from "fs";
4
+ import { listFilesRecursive, readFileSafe } from "./utils";
5
+ export function isSourceFile(p) {
6
+ return /\.(ts|tsx|js|jsx)$/.test(p) && !p.endsWith(".d.ts");
7
+ }
8
+ export function isTestFile(p) {
9
+ return /(\.test\.|\.spec\.)/.test(p);
10
+ }
11
+ export function extractExports(fileContent) {
12
+ const names = new Set();
13
+ const exportRe = /(export\s+(?:default\s+)?(?:class|function|const|let|var|interface|type|enum)\s+)([A-Za-z0-9_]+)/g;
14
+ const namedRe = /export\s*\{([^}]+)\}/g;
15
+ let m;
16
+ while ((m = exportRe.exec(fileContent)))
17
+ names.add(m[2]);
18
+ while ((m = namedRe.exec(fileContent))) {
19
+ m[1]
20
+ .split(",")
21
+ .map((s) => s.trim().split(" as ")[0].trim())
22
+ .forEach((n) => {
23
+ if (n)
24
+ names.add(n);
25
+ });
26
+ }
27
+ return [...names].sort();
28
+ }
29
+ export function extractDecorators(fileContent) {
30
+ const decs = new Set();
31
+ const decRe = /@([A-Za-z_][A-Za-z0-9_]*)/g;
32
+ let m;
33
+ while ((m = decRe.exec(fileContent)))
34
+ decs.add(m[1]);
35
+ return [...decs].sort();
36
+ }
37
+ export function summarizeReadme(readme) {
38
+ if (!readme)
39
+ return undefined;
40
+ const lines = readme.split(/\r?\n/).filter(Boolean);
41
+ const title = lines.find((l) => /^#\s+/.test(l))?.replace(/^#\s+/, "") || "README";
42
+ const bullets = lines.filter((l) => /^[-*]\s+/.test(l)).slice(0, 20);
43
+ return { title, bullets };
44
+ }
45
+ export function analyzeRepo(root) {
46
+ const src = path.join(root, "src");
47
+ const testDir = path.join(root, "tests");
48
+ const readmePath = path.join(root, "README.md");
49
+ const readme = readFileSafe(readmePath);
50
+ const files = fs.existsSync(src) ? listFilesRecursive(src, isSourceFile) : [];
51
+ const testFiles = fs.existsSync(testDir)
52
+ ? listFilesRecursive(testDir, (f) => isSourceFile(f) && isTestFile(f))
53
+ : [];
54
+ const api = {};
55
+ for (const f of files) {
56
+ const content = readFileSafe(f) || "";
57
+ api[path.relative(root, f)] = {
58
+ exports: extractExports(content),
59
+ decorators: extractDecorators(content),
60
+ };
61
+ }
62
+ const tests = {};
63
+ for (const f of testFiles) {
64
+ const content = readFileSafe(f) || "";
65
+ const mentions = Array.from(new Set([...extractExports(content), ...extractDecorators(content)])).sort();
66
+ tests[path.relative(root, f)] = { mentions };
67
+ }
68
+ return { files, testFiles, api, tests, readme: summarizeReadme(readme) };
69
+ }
70
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29kZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9tY3AvY29kZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwrRUFBK0U7QUFDL0UsT0FBTyxJQUFJLE1BQU0sTUFBTSxDQUFDO0FBQ3hCLE9BQU8sRUFBRSxNQUFNLElBQUksQ0FBQztBQUNwQixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsWUFBWSxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBRTNELE1BQU0sVUFBVSxZQUFZLENBQUMsQ0FBUztJQUNwQyxPQUFPLG9CQUFvQixDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUM7QUFDOUQsQ0FBQztBQUNELE1BQU0sVUFBVSxVQUFVLENBQUMsQ0FBUztJQUNsQyxPQUFPLHFCQUFxQixDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN2QyxDQUFDO0FBRUQsTUFBTSxVQUFVLGNBQWMsQ0FBQyxXQUFtQjtJQUNoRCxNQUFNLEtBQUssR0FBRyxJQUFJLEdBQUcsRUFBVSxDQUFDO0lBQ2hDLE1BQU0sUUFBUSxHQUNaLG1HQUFtRyxDQUFDO0lBQ3RHLE1BQU0sT0FBTyxHQUFHLHVCQUF1QixDQUFDO0lBQ3hDLElBQUksQ0FBeUIsQ0FBQztJQUM5QixPQUFPLENBQUMsQ0FBQyxHQUFHLFFBQVEsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7UUFBRSxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3pELE9BQU8sQ0FBQyxDQUFDLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDdkMsQ0FBQyxDQUFDLENBQUMsQ0FBQzthQUNELEtBQUssQ0FBQyxHQUFHLENBQUM7YUFDVixHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FB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UUFBUSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHO1lBQzVCLE9BQU8sRUFBRSxjQUFjLENBQUMsT0FBTyxDQUFDO1lBQ2hDLFVBQVUsRUFBRSxpQkFBaUIsQ0FBQyxPQUFPLENBQUM7U0FDdkMsQ0FBQztJQUNKLENBQUM7SUFDRCxNQUFNLEtBQUssR0FBMkMsRUFBRSxDQUFDO0lBQ3pELEtBQUssTUFBTSxDQUFDLElBQUksU0FBUyxFQUFFLENBQUM7UUFDMUIsTUFBTSxPQUFPLEdBQUcsWUFBWSxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUN0QyxNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUN6QixJQUFJLEdBQUcsQ0FBQyxDQUFDLEdBQUcsY0FBYyxDQUFDLE9BQU8sQ0FBQyxFQUFFLEdBQUcsaUJBQWlCLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUNyRSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ1QsS0FBSyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxRQUFRLEVBQUUsQ0FBQztJQUMvQyxDQUFDO0lBQ0QsT0FBTyxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsZUFBZSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7QUFDM0UsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIEFuYWx5c2lzIGhlbHBlcnMgKG1pbmltYWwgeWV0IGVmZmVjdGl2ZSwgdGV4dC1iYXNlZCB0byBhdm9pZCBoZWF2eSBBU1QgZGVwcylcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XG5pbXBvcnQgZnMgZnJvbSBcImZzXCI7XG5pbXBvcnQgeyBsaXN0RmlsZXNSZWN1cnNpdmUsIHJlYWRGaWxlU2FmZSB9IGZyb20gXCIuL3V0aWxzXCI7XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1NvdXJjZUZpbGUocDogc3RyaW5nKSB7XG4gIHJldHVybiAvXFwuKHRzfHRzeHxqc3xqc3gpJC8udGVzdChwKSAmJiAhcC5lbmRzV2l0aChcIi5kLnRzXCIpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGlzVGVzdEZpbGUocDogc3RyaW5nKSB7XG4gIHJldHVybiAvKFxcLnRlc3RcXC58XFwuc3BlY1xcLikvLnRlc3QocCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBleHRyYWN0RXhwb3J0cyhmaWxlQ29udGVudDogc3RyaW5nKTogc3RyaW5nW10ge1xuICBjb25zdCBuYW1lcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICBjb25zdCBleHBvcnRSZSA9XG4gICAgLyhleHBvcnRcXHMrKD86ZGVmYXVsdFxccyspPyg/OmNsYXNzfGZ1bmN0aW9ufGNvbnN0fGxldHx2YXJ8aW50ZXJmYWNlfHR5cGV8ZW51bSlcXHMrKShbQS1aYS16MC05X10rKS9nO1xuICBjb25zdCBuYW1lZFJlID0gL2V4cG9ydFxccypcXHsoW159XSspXFx9L2c7XG4gIGxldCBtOiBSZWdFeHBFeGVjQXJyYXkgfCBudWxsO1xuICB3aGlsZSAoKG0gPSBleHBvcnRSZS5leGVjKGZpbGVDb250ZW50KSkpIG5hbWVzLmFkZChtWzJdKTtcbiAgd2hpbGUgKChtID0gbmFtZWRSZS5leGVjKGZpbGVDb250ZW50KSkpIHtcbiAgICBtWzFdXG4gICAgICAuc3BsaXQoXCIsXCIpXG4gICAgICAubWFwKChzKSA9PiBzLnRyaW0oKS5zcGxpdChcIiBhcyBcIilbMF0udHJpbSgpKVxuICAgICAgLmZvckVhY2goKG4pID0+IHtcbiAgICAgICAgaWYgKG4pIG5hbWVzLmFkZChuKTtcbiAgICAgIH0pO1xuICB9XG4gIHJldHVybiBbLi4ubmFtZXNdLnNvcnQoKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGV4dHJhY3REZWNvcmF0b3JzKGZpbGVDb250ZW50OiBzdHJpbmcpOiBzdHJpbmdbXSB7XG4gIGNvbnN0IGRlY3MgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgY29uc3QgZGVjUmUgPSAvQChbQS1aYS16X11bQS1aYS16MC05X10qKS9nO1xuICBsZXQgbTogUmVnRXhwRXhlY0FycmF5IHwgbnVsbDtcbiAgd2hpbGUgKChtID0gZGVjUmUuZXhlYyhmaWxlQ29udGVudCkpKSBkZWNzLmFkZChtWzFdKTtcbiAgcmV0dXJuIFsuLi5kZWNzXS5zb3J0KCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzdW1tYXJpemVSZWFkbWUocmVhZG1lPzogc3RyaW5nKSB7XG4gIGlmICghcmVhZG1lKSByZXR1cm4gdW5kZWZpbmVkO1xuICBjb25zdCBsaW5lcyA9IHJlYWRtZS5zcGxpdCgvXFxyP1xcbi8pLmZpbHRlcihCb29sZWFuKTtcbiAgY29uc3QgdGl0bGUgPVxuICAgIGxpbmVzLmZpbmQoKGwpID0+IC9eI1xccysvLnRlc3QobCkpPy5yZXBsYWNlKC9eI1xccysvLCBcIlwiKSB8fCBcIlJFQURNRVwiO1xuICBjb25zdCBidWxsZXRzID0gbGluZXMuZmlsdGVyKChsKSA9PiAvXlstKl1cXHMrLy50ZXN0KGwpKS5zbGljZSgwLCAyMCk7XG4gIHJldHVybiB7IHRpdGxlLCBidWxsZXRzIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhbmFseXplUmVwbyhyb290OiBzdHJpbmcpIHtcbiAgY29uc3Qgc3JjID0gcGF0aC5qb2luKHJvb3QsIFwic3JjXCIpO1xuICBjb25zdCB0ZXN0RGlyID0gcGF0aC5qb2luKHJvb3QsIFwidGVzdHNcIik7XG4gIGNvbnN0IHJlYWRtZVBhdGggPSBwYXRoLmpvaW4ocm9vdCwgXCJSRUFETUUubWRcIik7XG4gIGNvbnN0IHJlYWRtZSA9IHJlYWRGaWxlU2FmZShyZWFkbWVQYXRoKTtcblxuICBjb25zdCBmaWxlcyA9IGZzLmV4aXN0c1N5bmMoc3JjKSA/IGxpc3RGaWxlc1JlY3Vyc2l2ZShzcmMsIGlzU291cmNlRmlsZSkgOiBbXTtcbiAgY29uc3QgdGVzdEZpbGVzID0gZnMuZXhpc3RzU3luYyh0ZXN0RGlyKVxuICAgID8gbGlzdEZpbGVzUmVjdXJzaXZlKHRlc3REaXIsIChmKSA9PiBpc1NvdXJjZUZpbGUoZikgJiYgaXNUZXN0RmlsZShmKSlcbiAgICA6IFtdO1xuXG4gIGNvbnN0IGFwaTogUmVjb3JkPHN0cmluZywgeyBleHBvcnRzOiBzdHJpbmdbXTsgZGVjb3JhdG9yczogc3RyaW5nW10gfT4gPSB7fTtcbiAgZm9yIChjb25zdCBmIG9mIGZpbGVzKSB7XG4gICAgY29uc3QgY29udGVudCA9IHJlYWRGaWxlU2FmZShmKSB8fCBcIlwiO1xuICAgIGFwaVtwYXRoLnJlbGF0aXZlKHJvb3QsIGYpXSA9IHtcbiAgICAgIGV4cG9ydHM6IGV4dHJhY3RFeHBvcnRzKGNvbnRlbnQpLFxuICAgICAgZGVjb3JhdG9yczogZXh0cmFjdERlY29yYXRvcnMoY29udGVudCksXG4gICAgfTtcbiAgfVxuICBjb25zdCB0ZXN0czogUmVjb3JkPHN0cmluZywgeyBtZW50aW9uczogc3RyaW5nW10gfT4gPSB7fTtcbiAgZm9yIChjb25zdCBmIG9mIHRlc3RGaWxlcykge1xuICAgIGNvbnN0IGNvbnRlbnQgPSByZWFkRmlsZVNhZmUoZikgfHwgXCJcIjtcbiAgICBjb25zdCBtZW50aW9ucyA9IEFycmF5LmZyb20oXG4gICAgICBuZXcgU2V0KFsuLi5leHRyYWN0RXhwb3J0cyhjb250ZW50KSwgLi4uZXh0cmFjdERlY29yYXRvcnMoY29udGVudCldKVxuICAgICkuc29ydCgpO1xuICAgIHRlc3RzW3BhdGgucmVsYXRpdmUocm9vdCwgZildID0geyBtZW50aW9ucyB9O1xuICB9XG4gIHJldHVybiB7IGZpbGVzLCB0ZXN0RmlsZXMsIGFwaSwgdGVzdHMsIHJlYWRtZTogc3VtbWFyaXplUmVhZG1lKHJlYWRtZSkgfTtcbn1cbiJdfQ==
@@ -0,0 +1,237 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+ function escapeRegExp(value) {
4
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
5
+ }
6
+ function formatDecorator(spec) {
7
+ const args = (spec.args || []).map((arg) => JSON.stringify(arg)).join(", ");
8
+ return `@${spec.name}(${args})`;
9
+ }
10
+ function ensureDirectory(filePath) {
11
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
12
+ }
13
+ function collectDecoratorNames(classDecorators, properties) {
14
+ const names = new Set();
15
+ names.add("model");
16
+ for (const decorator of classDecorators || []) {
17
+ names.add(decorator.name);
18
+ }
19
+ for (const property of properties || []) {
20
+ for (const decorator of property.decorators || []) {
21
+ names.add(decorator.name);
22
+ }
23
+ }
24
+ return names;
25
+ }
26
+ function ensureImport(content, importsFrom, decorators) {
27
+ /* istanbul ignore next */
28
+ if (!decorators.size)
29
+ return content;
30
+ const importRegex = new RegExp(`import\\s+\\{([^}]+)\\}\\s+from\\s+["']${escapeRegExp(importsFrom)}["'];`);
31
+ const match = content.match(importRegex);
32
+ const sorted = Array.from(decorators).sort();
33
+ if (match) {
34
+ const existing = match[1]
35
+ .split(",")
36
+ .map((name) => name.trim())
37
+ .filter(Boolean);
38
+ const merged = Array.from(new Set([...existing, ...sorted])).sort();
39
+ return content.replace(importRegex, `import { ${merged.join(", ")} } from "${importsFrom}";`);
40
+ }
41
+ const importLine = `import { ${sorted.join(", ")} } from "${importsFrom}";`;
42
+ return `${importLine}\n\n${content}`;
43
+ }
44
+ function addPropertyBlock(property) {
45
+ const decorators = (property.decorators || [])
46
+ .map(formatDecorator)
47
+ .join("\n ");
48
+ const decoratorBlock = decorators ? ` ${decorators}\n` : "";
49
+ return `${decoratorBlock} ${property.name}: ${property.type};`;
50
+ }
51
+ function removePropertyBlock(content, propertyName) {
52
+ const lines = content.split(/\r?\n/);
53
+ const result = [];
54
+ for (let i = 0; i < lines.length; i++) {
55
+ const line = lines[i];
56
+ if (line.trim().startsWith(`@`) &&
57
+ lines[i + 1]?.includes(`${propertyName}:`)) {
58
+ continue;
59
+ }
60
+ if (line.includes(`${propertyName}:`)) {
61
+ // skip this line and any trailing blank line
62
+ continue;
63
+ }
64
+ result.push(line);
65
+ }
66
+ return result.join("\n");
67
+ }
68
+ function insertDecorator(content, decorator, target) {
69
+ const decoratorLine = formatDecorator(decorator);
70
+ if (target.kind === "class") {
71
+ const classRegex = /(export\s+class\s+[^\s{]+\s*\{)/;
72
+ if (content.includes(decoratorLine))
73
+ return content;
74
+ return content.replace(classRegex, `${decoratorLine}\n$1`);
75
+ }
76
+ if (!target.name)
77
+ return content;
78
+ const propertyRegex = new RegExp(`(^\\s*)(?:@.*\\n\\1)*${escapeRegExp(target.name)}:`, "m");
79
+ const match = propertyRegex.exec(content);
80
+ if (!match)
81
+ return content;
82
+ const indent = match[1] || " ";
83
+ if (content.includes(`${indent}${decoratorLine}`))
84
+ return content;
85
+ return (content.slice(0, match.index) +
86
+ `${indent}${decoratorLine}\n` +
87
+ content.slice(match.index));
88
+ }
89
+ function removeDecorator(content, decoratorName, target) {
90
+ const decoratorRegex = new RegExp(`^\\s*@${escapeRegExp(decoratorName)}\\([^)]*\\)`, "m");
91
+ if (target.kind === "class") {
92
+ return content.replace(decoratorRegex, "");
93
+ }
94
+ if (target.name) {
95
+ const pattern = new RegExp(`(^\\s*@${escapeRegExp(decoratorName)}\\([^)]*\\)\\s*$\\n)(?=\\s*${escapeRegExp(target.name)}:)`, "m");
96
+ return content.replace(pattern, "");
97
+ }
98
+ return content;
99
+ }
100
+ function writeIfChanged(filePath, content) {
101
+ ensureDirectory(filePath);
102
+ fs.writeFileSync(filePath, content);
103
+ }
104
+ export const decoratorTools = {
105
+ createOrUpdateModelTool: {
106
+ name: "create-or-update-model",
107
+ description: "Create or update a validation-ready model class",
108
+ execute: async (args) => {
109
+ if (!args.overwrite && fs.existsSync(args.filePath)) {
110
+ throw new Error(`File already exists at ${args.filePath}`);
111
+ }
112
+ const decorators = collectDecoratorNames(args.classDecorators, args.properties);
113
+ let content = `@model()`;
114
+ for (const decorator of args.classDecorators || []) {
115
+ content += `\n${formatDecorator(decorator)}`;
116
+ }
117
+ const properties = (args.properties || [])
118
+ .map(addPropertyBlock)
119
+ .join("\n\n");
120
+ content += `\nexport class ${args.className} {\n${properties ? `${properties}\n` : ""}}\n`;
121
+ content = ensureImport(content, args.importsFrom, decorators);
122
+ writeIfChanged(args.filePath, content);
123
+ return { filePath: args.filePath };
124
+ },
125
+ },
126
+ addAttributeTool: {
127
+ name: "add-attribute",
128
+ description: "Add a decorated attribute to an existing model",
129
+ execute: async (args) => {
130
+ if (!fs.existsSync(args.filePath)) {
131
+ throw new Error(`Model file not found at ${args.filePath}`);
132
+ }
133
+ let content = fs.readFileSync(args.filePath, "utf8");
134
+ if (content.includes(`${args.attribute.name}:`)) {
135
+ return { filePath: args.filePath };
136
+ }
137
+ const decorators = collectDecoratorNames(undefined, [args.attribute]);
138
+ content = ensureImport(content, args.importsFrom, decorators);
139
+ const insertionPoint = content.lastIndexOf("}");
140
+ const block = addPropertyBlock(args.attribute);
141
+ const before = content.slice(0, insertionPoint).replace(/\s*$/, "");
142
+ const after = content.slice(insertionPoint);
143
+ const updated = `${before}\n${block}\n${after}`;
144
+ writeIfChanged(args.filePath, updated);
145
+ return { filePath: args.filePath };
146
+ },
147
+ },
148
+ removeAttributeTool: {
149
+ name: "remove-attribute",
150
+ description: "Remove an attribute from a model class",
151
+ execute: async (args) => {
152
+ if (!fs.existsSync(args.filePath))
153
+ return { filePath: args.filePath };
154
+ const content = fs.readFileSync(args.filePath, "utf8");
155
+ const updated = removePropertyBlock(content, args.attributeName);
156
+ writeIfChanged(args.filePath, updated);
157
+ return { filePath: args.filePath };
158
+ },
159
+ },
160
+ applyDecoratorTool: {
161
+ name: "apply-decorator",
162
+ description: "Apply a decorator to a class or property",
163
+ execute: async (args) => {
164
+ if (!fs.existsSync(args.filePath)) {
165
+ throw new Error(`Model file not found at ${args.filePath}`);
166
+ }
167
+ let content = fs.readFileSync(args.filePath, "utf8");
168
+ const decorators = new Set([args.decorator.name]);
169
+ content = ensureImport(content, args.importsFrom, decorators);
170
+ content = insertDecorator(content, args.decorator, args.target);
171
+ writeIfChanged(args.filePath, content);
172
+ return { filePath: args.filePath };
173
+ },
174
+ },
175
+ removeDecoratorTool: {
176
+ name: "remove-decorator",
177
+ description: "Remove a decorator from a class or property",
178
+ execute: async (args) => {
179
+ if (!fs.existsSync(args.filePath))
180
+ return { filePath: args.filePath };
181
+ let content = fs.readFileSync(args.filePath, "utf8");
182
+ content = removeDecorator(content, args.decoratorName, args.target);
183
+ writeIfChanged(args.filePath, content);
184
+ return { filePath: args.filePath };
185
+ },
186
+ },
187
+ scaffoldValidatorTool: {
188
+ name: "scaffold-validator",
189
+ description: "Scaffold a validator class and optional decorator",
190
+ execute: async (args) => {
191
+ const classFile = path.join(args.validatorsDir, `${args.name}.ts`);
192
+ ensureDirectory(classFile);
193
+ const classContent = `export class ${args.name} {\n validate(value: unknown): boolean {\n return value !== undefined;\n }\n}\n`;
194
+ fs.writeFileSync(classFile, classContent);
195
+ let decoratorFile;
196
+ if (args.decoratorDir) {
197
+ decoratorFile = path.join(args.decoratorDir, `${args.name}Decorator.ts`);
198
+ ensureDirectory(decoratorFile);
199
+ fs.writeFileSync(decoratorFile, `export function ${args.name}Decorator() {\n return () => void 0;\n}\n`);
200
+ }
201
+ return { classFile, decoratorFile };
202
+ },
203
+ },
204
+ scaffoldSerializerTool: {
205
+ name: "scaffold-serializer",
206
+ description: "Scaffold a serializer class and optional registry",
207
+ execute: async (args) => {
208
+ const classFile = path.join(args.dir, `${args.name}.ts`);
209
+ ensureDirectory(classFile);
210
+ fs.writeFileSync(classFile, `export class ${args.name} {\n serialize(value: unknown): string {\n return JSON.stringify(value);\n }\n}\n`);
211
+ let registerFile;
212
+ if (args.registerDir) {
213
+ registerFile = path.join(args.registerDir, `${args.name}Register.ts`);
214
+ ensureDirectory(registerFile);
215
+ fs.writeFileSync(registerFile, `export function register${args.name}() {\n return ${args.setDefault ? "'default'" : "'optional'"};\n}\n`);
216
+ }
217
+ return { classFile, registerFile };
218
+ },
219
+ },
220
+ scaffoldHashingTool: {
221
+ name: "scaffold-hashing",
222
+ description: "Scaffold a hashing function and optional registry",
223
+ execute: async (args) => {
224
+ const functionFile = path.join(args.dir, `${args.name}.ts`);
225
+ ensureDirectory(functionFile);
226
+ fs.writeFileSync(functionFile, `export function ${args.name}(value: string): string {\n return value.split('').reverse().join('');\n}\n`);
227
+ let registerFile;
228
+ if (args.registerDir) {
229
+ registerFile = path.join(args.registerDir, `${args.name}Register.ts`);
230
+ ensureDirectory(registerFile);
231
+ fs.writeFileSync(registerFile, `export function register${args.name}() {\n return ${args.setDefault ? "'default'" : "'optional'"};\n}\n`);
232
+ }
233
+ return { functionFile, registerFile };
234
+ },
235
+ },
236
+ };
237
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVjb3JhdG9yLXRvb2xzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL21jcC9kZWNvcmF0b3ItdG9vbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE1BQU0sSUFBSSxDQUFDO0FBQ3BCLE9BQU8sSUFBSSxNQUFNLE1BQU0sQ0FBQztBQWF4QixTQUFTLFlBQVksQ0FBQyxLQUFhO0lBQ2pDLE9BQU8sS0FBSyxDQUFDLE9BQU8sQ0FBQyxxQkFBcUIsRUFBRSxNQUFNLENBQUMsQ0FBQztBQUN0RCxDQUFDO0FBRUQsU0FBUyxlQUFlLENBQUMsSUFBbUI7SUFDMUMsTUFBTSxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUM1RSxPQUFPLElBQUksSUFBSSxDQUFDLElBQUksSUFBSSxJQUFJLEdBQUcsQ0FBQztBQUNsQyxDQUFDO0FBRUQsU0FBUyxlQUFlLENBQUMsUUFBZ0I7SUFDdkMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7QUFDNUQsQ0FBQztBQUVELFNBQVMscUJBQXFCLENBQzVCLGVBQTRDLEVBQzVDLFVBQXVDO0lBRXZDLE1BQU0sS0FBSyxHQUFHLElBQUksR0FBRyxFQUFVLENBQUM7SUFDaEMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNuQixLQUFLLE1BQU0sU0FBUyxJQUFJLGVBQWUsSUFBSSxFQUFFLEVBQUUsQ0FBQztRQUM5QyxLQUFLLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUM1QixD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MkJBQTJCLElBQUksQ0FBQyxJQUFJLGtCQUFrQixJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLFlBQVksUUFBUSxDQUMzRyxDQUFDO1lBQ0osQ0FBQztZQUNELE9BQU8sRUFBRSxZQUFZLEVBQUUsWUFBWSxFQUFFLENBQUM7UUFDeEMsQ0FBQztLQUNGO0NBQ08sQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBmcyBmcm9tIFwiZnNcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XG5cbmV4cG9ydCB0eXBlIERlY29yYXRvclNwZWMgPSB7XG4gIG5hbWU6IHN0cmluZztcbiAgYXJncz86IHVua25vd25bXTtcbn07XG5cbmV4cG9ydCB0eXBlIEF0dHJpYnV0ZVNwZWMgPSB7XG4gIG5hbWU6IHN0cmluZztcbiAgdHlwZTogc3RyaW5nO1xuICBkZWNvcmF0b3JzPzogRGVjb3JhdG9yU3BlY1tdO1xufTtcblxuZnVuY3Rpb24gZXNjYXBlUmVnRXhwKHZhbHVlOiBzdHJpbmcpIHtcbiAgcmV0dXJuIHZhbHVlLnJlcGxhY2UoL1suKis/XiR7fSgpfFtcXF1cXFxcXS9nLCBcIlxcXFwkJlwiKTtcbn1cblxuZnVuY3Rpb24gZm9ybWF0RGVjb3JhdG9yKHNwZWM6IERlY29yYXRvclNwZWMpOiBzdHJpbmcge1xuICBjb25zdCBhcmdzID0gKHNwZWMuYXJncyB8fCBbXSkubWFwKChhcmcpID0+IEpTT04uc3RyaW5naWZ5KGFyZykpLmpvaW4oXCIsIFwiKTtcbiAgcmV0dXJuIGBAJHtzcGVjLm5hbWV9KCR7YXJnc30pYDtcbn1cblxuZnVuY3Rpb24gZW5zdXJlRGlyZWN0b3J5KGZpbGVQYXRoOiBzdHJpbmcpIHtcbiAgZnMubWtkaXJTeW5jKHBhdGguZGlybmFtZShmaWxlUGF0aCksIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xufVxuXG5mdW5jdGlvbiBjb2xsZWN0RGVjb3JhdG9yTmFtZXMoXG4gIGNsYXNzRGVjb3JhdG9yczogRGVjb3JhdG9yU3BlY1tdIHwgdW5kZWZpbmVkLFxuICBwcm9wZXJ0aWVzOiBBdHRyaWJ1dGVTcGVjW10gfCB1bmRlZmluZWRcbikge1xuICBjb25zdCBuYW1lcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICBuYW1lcy5hZGQoXCJtb2RlbFwiKTtcbiAgZm9yIChjb25zdCBkZWNvcmF0b3Igb2YgY2xhc3NEZWNvcmF0b3JzIHx8IFtdKSB7XG4gICAgbmFtZXMuYWRkKGRlY29yYXRvci5uYW1lKTtcbiAgfVxuICBmb3IgKGNvbnN0IHByb3BlcnR5IG9mIHByb3BlcnRpZXMgfHwgW10pIHtcbiAgICBmb3IgKGNvbnN0IGRlY29yYXRvciBvZiBwcm9wZXJ0eS5kZWNvcmF0b3JzIHx8IFtdKSB7XG4gICAgICBuYW1lcy5hZGQoZGVjb3JhdG9yLm5hbWUpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gbmFtZXM7XG59XG5cbmZ1bmN0aW9uIGVuc3VyZUltcG9ydChcbiAgY29udGVudDogc3RyaW5nLFxuICBpbXBvcnRzRnJvbTogc3RyaW5nLFxuICBkZWNvcmF0b3JzOiBTZXQ8c3RyaW5nPlxuKSB7XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gIGlmICghZGVjb3JhdG9ycy5zaXplKSByZXR1cm4gY29udGVudDtcbiAgY29uc3QgaW1wb3J0UmVnZXggPSBuZXcgUmVnRXhwKFxuICAgIGBpbXBvcnRcXFxccytcXFxceyhbXn1dKylcXFxcfVxcXFxzK2Zyb21cXFxccytbXCInXSR7ZXNjYXBlUmVnRXhwKGltcG9ydHNGcm9tKX1bXCInXTtgXG4gICk7XG4gIGNvbnN0IG1hdGNoID0gY29udGVudC5tYXRjaChpbXBvcnRSZWdleCk7XG4gIGNvbnN0IHNvcnRlZCA9IEFycmF5LmZyb20oZGVjb3JhdG9ycykuc29ydCgpO1xuXG4gIGlmIChtYXRjaCkge1xuICAgIGNvbnN0IGV4aXN0aW5nID0gbWF0Y2hbMV1cbiAgICAgIC5zcGxpdChcIixcIilcbiAgICAgIC5tYXAoKG5hbWUpID0+IG5hbWUudHJpbSgpKVxuICAgICAgLmZpbHRlcihCb29sZWFuKTtcbiAgICBjb25zdCBtZXJnZWQgPSBBcnJheS5mcm9tKG5ldyBTZXQoWy4uLmV4aXN0aW5nLCAuLi5zb3J0ZWRdKSkuc29ydCgpO1xuICAgIHJldHVybiBjb250ZW50LnJlcGxhY2UoXG4gICAgICBpbXBvcnRSZWdleCxcbiAgICAgIGBpbXBvcnQgeyAke21lcmdlZC5qb2luKFwiLCBcIil9IH0gZnJvbSBcIiR7aW1wb3J0c0Zyb219XCI7YFxuICAgICk7XG4gIH1cblxuICBjb25zdCBpbXBvcnRMaW5lID0gYGltcG9ydCB7ICR7c29ydGVkLmpvaW4oXCIsIFwiKX0gfSBmcm9tIFwiJHtpbXBvcnRzRnJvbX1cIjtgO1xuICByZXR1cm4gYCR7aW1wb3J0TGluZX1cXG5cXG4ke2NvbnRlbnR9YDtcbn1cblxuZnVuY3Rpb24gYWRkUHJvcGVydHlCbG9jayhwcm9wZXJ0eTogQXR0cmlidXRlU3BlYykge1xuICBjb25zdCBkZWNvcmF0b3JzID0gKHByb3BlcnR5LmRlY29yYXRvcnMgfHwgW10pXG4gICAgLm1hcChmb3JtYXREZWNvcmF0b3IpXG4gICAgLmpvaW4oXCJcXG4gIFwiKTtcbiAgY29uc3QgZGVjb3JhdG9yQmxvY2sgPSBkZWNvcmF0b3JzID8gYCAgJHtkZWNvcmF0b3JzfVxcbmAgOiBcIlwiO1xuICByZXR1cm4gYCR7ZGVjb3JhdG9yQmxvY2t9ICAke3Byb3BlcnR5Lm5hbWV9OiAke3Byb3BlcnR5LnR5cGV9O2A7XG59XG5cbmZ1bmN0aW9uIHJlbW92ZVByb3BlcnR5QmxvY2soY29udGVudDogc3RyaW5nLCBwcm9wZXJ0eU5hbWU6IHN0cmluZykge1xuICBjb25zdCBsaW5lcyA9IGNvbnRlbnQuc3BsaXQoL1xccj9cXG4vKTtcbiAgY29uc3QgcmVzdWx0OiBzdHJpbmdbXSA9IFtdO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGxpbmVzLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3QgbGluZSA9IGxpbmVzW2ldO1xuICAgIGlmIChcbiAgICAgIGxpbmUudHJpbSgpLnN0YXJ0c1dpdGgoYEBgKSAmJlxuICAgICAgbGluZXNbaSArIDFdPy5pbmNsdWRlcyhgJHtwcm9wZXJ0eU5hbWV9OmApXG4gICAgKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgaWYgKGxpbmUuaW5jbHVkZXMoYCR7cHJvcGVydHlOYW1lfTpgKSkge1xuICAgICAgLy8gc2tpcCB0aGlzIGxpbmUgYW5kIGFueSB0cmFpbGluZyBibGFuayBsaW5lXG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgcmVzdWx0LnB1c2gobGluZSk7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdC5qb2luKFwiXFxuXCIpO1xufVxuXG5mdW5jdGlvbiBpbnNlcnREZWNvcmF0b3IoXG4gIGNvbnRlbnQ6IHN0cmluZyxcbiAgZGVjb3JhdG9yOiBEZWNvcmF0b3JTcGVjLFxuICB0YXJnZXQ6IHtcbiAgICBraW5kOiBcImNsYXNzXCIgfCBcInByb3BlcnR5XCI7XG4gICAgbmFtZT86IHN0cmluZztcbiAgfVxuKSB7XG4gIGNvbnN0IGRlY29yYXRvckxpbmUgPSBmb3JtYXREZWNvcmF0b3IoZGVjb3JhdG9yKTtcbiAgaWYgKHRhcmdldC5raW5kID09PSBcImNsYXNzXCIpIHtcbiAgICBjb25zdCBjbGFzc1JlZ2V4ID0gLyhleHBvcnRcXHMrY2xhc3NcXHMrW15cXHN7XStcXHMqXFx7KS87XG4gICAgaWYgKGNvbnRlbnQuaW5jbHVkZXMoZGVjb3JhdG9yTGluZSkpIHJldHVybiBjb250ZW50O1xuICAgIHJldHVybiBjb250ZW50LnJlcGxhY2UoY2xhc3NSZWdleCwgYCR7ZGVjb3JhdG9yTGluZX1cXG4kMWApO1xuICB9XG4gIGlmICghdGFyZ2V0Lm5hbWUpIHJldHVybiBjb250ZW50O1xuICBjb25zdCBwcm9wZXJ0eVJlZ2V4ID0gbmV3IFJlZ0V4cChcbiAgICBgKF5cXFxccyopKD86QC4qXFxcXG5cXFxcMSkqJHtlc2NhcGVSZWdFeHAodGFyZ2V0Lm5hbWUpfTpgLFxuICAgIFwibVwiXG4gICk7XG4gIGNvbnN0IG1hdGNoID0gcHJvcGVydHlSZWdleC5leGVjKGNvbnRlbnQpO1xuICBpZiAoIW1hdGNoKSByZXR1cm4gY29udGVudDtcbiAgY29uc3QgaW5kZW50ID0gbWF0Y2hbMV0gfHwgXCIgIFwiO1xuICBpZiAoY29udGVudC5pbmNsdWRlcyhgJHtpbmRlbnR9JHtkZWNvcmF0b3JMaW5lfWApKSByZXR1cm4gY29udGVudDtcbiAgcmV0dXJuIChcbiAgICBjb250ZW50LnNsaWNlKDAsIG1hdGNoLmluZGV4KSArXG4gICAgYCR7aW5kZW50fSR7ZGVjb3JhdG9yTGluZX1cXG5gICtcbiAgICBjb250ZW50LnNsaWNlKG1hdGNoLmluZGV4KVxuICApO1xufVxuXG5mdW5jdGlvbiByZW1vdmVEZWNvcmF0b3IoXG4gIGNvbnRlbnQ6IHN0cmluZyxcbiAgZGVjb3JhdG9yTmFtZTogc3RyaW5nLFxuICB0YXJnZXQ6IHtcbiAgICBraW5kOiBcImNsYXNzXCIgfCBcInByb3BlcnR5XCI7XG4gICAgbmFtZT86IHN0cmluZztcbiAgfVxuKSB7XG4gIGNvbnN0IGRlY29yYXRvclJlZ2V4ID0gbmV3IFJlZ0V4cChcbiAgICBgXlxcXFxzKkAke2VzY2FwZVJlZ0V4cChkZWNvcmF0b3JOYW1lKX1cXFxcKFteKV0qXFxcXClgLFxuICAgIFwibVwiXG4gICk7XG4gIGlmICh0YXJnZXQua2luZCA9PT0gXCJjbGFzc1wiKSB7XG4gICAgcmV0dXJuIGNvbnRlbnQucmVwbGFjZShkZWNvcmF0b3JSZWdleCwgXCJcIik7XG4gIH1cbiAgaWYgKHRhcmdldC5uYW1lKSB7XG4gICAgY29uc3QgcGF0dGVybiA9IG5ldyBSZWdFeHAoXG4gICAgICBgKF5cXFxccypAJHtlc2NhcGVSZWdFeHAoZGVjb3JhdG9yTmFtZSl9XFxcXChbXildKlxcXFwpXFxcXHMqJFxcXFxuKSg/PVxcXFxzKiR7ZXNjYXBlUmVnRXhwKHRhcmdldC5uYW1lKX06KWAsXG4gICAgICBcIm1cIlxuICAgICk7XG4gICAgcmV0dXJuIGNvbnRlbnQucmVwbGFjZShwYXR0ZXJuLCBcIlwiKTtcbiAgfVxuICByZXR1cm4gY29udGVudDtcbn1cblxuZnVuY3Rpb24gd3JpdGVJZkNoYW5nZWQoZmlsZVBhdGg6IHN0cmluZywgY29udGVudDogc3RyaW5nKSB7XG4gIGVuc3VyZURpcmVjdG9yeShmaWxlUGF0aCk7XG4gIGZzLndyaXRlRmlsZVN5bmMoZmlsZVBhdGgsIGNvbnRlbnQpO1xufVxuXG5leHBvcnQgY29uc3QgZGVjb3JhdG9yVG9vbHMgPSB7XG4gIGNyZWF0ZU9yVXBkYXRlTW9kZWxUb29sOiB7XG4gICAgbmFtZTogXCJjcmVhdGUtb3ItdXBkYXRlLW1vZGVsXCIsXG4gICAgZGVzY3JpcHRpb246IFwiQ3JlYXRlIG9yIHVwZGF0ZSBhIHZhbGlkYXRpb24tcmVhZHkgbW9kZWwgY2xhc3NcIixcbiAgICBleGVjdXRlOiBhc3luYyAoYXJnczoge1xuICAgICAgZmlsZVBhdGg6IHN0cmluZztcbiAgICAgIGNsYXNzTmFtZTogc3RyaW5nO1xuICAgICAgY2xhc3NEZWNvcmF0b3JzPzogRGVjb3JhdG9yU3BlY1tdO1xuICAgICAgcHJvcGVydGllczogQXR0cmlidXRlU3BlY1tdO1xuICAgICAgaW1wb3J0c0Zyb206IHN0cmluZztcbiAgICAgIG92ZXJ3cml0ZT86IGJvb2xlYW47XG4gICAgfSkgPT4ge1xuICAgICAgaWYgKCFhcmdzLm92ZXJ3cml0ZSAmJiBmcy5leGlzdHNTeW5jKGFyZ3MuZmlsZVBhdGgpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgRmlsZSBhbHJlYWR5IGV4aXN0cyBhdCAke2FyZ3MuZmlsZVBhdGh9YCk7XG4gICAgICB9XG4gICAgICBjb25zdCBkZWNvcmF0b3JzID0gY29sbGVjdERlY29yYXRvck5hbWVzKFxuICAgICAgICBhcmdzLmNsYXNzRGVjb3JhdG9ycyxcbiAgICAgICAgYXJncy5wcm9wZXJ0aWVzXG4gICAgICApO1xuICAgICAgbGV0IGNvbnRlbnQgPSBgQG1vZGVsKClgO1xuICAgICAgZm9yIChjb25zdCBkZWNvcmF0b3Igb2YgYXJncy5jbGFzc0RlY29yYXRvcnMgfHwgW10pIHtcbiAgICAgICAgY29udGVudCArPSBgXFxuJHtmb3JtYXREZWNvcmF0b3IoZGVjb3JhdG9yKX1gO1xuICAgICAgfVxuICAgICAgY29uc3QgcHJvcGVydGllcyA9IChhcmdzLnByb3BlcnRpZXMgfHwgW10pXG4gICAgICAgIC5tYXAoYWRkUHJvcGVydHlCbG9jaylcbiAgICAgICAgLmpvaW4oXCJcXG5cXG5cIik7XG4gICAgICBjb250ZW50ICs9IGBcXG5leHBvcnQgY2xhc3MgJHthcmdzLmNsYXNzTmFtZX0ge1xcbiR7cHJvcGVydGllcyA/IGAke3Byb3BlcnRpZXN9XFxuYCA6IFwiXCJ9fVxcbmA7XG4gICAgICBjb250ZW50ID0gZW5zdXJlSW1wb3J0KGNvbnRlbnQsIGFyZ3MuaW1wb3J0c0Zyb20sIGRlY29yYXRvcnMpO1xuICAgICAgd3JpdGVJZkNoYW5nZWQoYXJncy5maWxlUGF0aCwgY29udGVudCk7XG4gICAgICByZXR1cm4geyBmaWxlUGF0aDogYXJncy5maWxlUGF0aCB9O1xuICAgIH0sXG4gIH0sXG4gIGFkZEF0dHJpYnV0ZVRvb2w6IHtcbiAgICBuYW1lOiBcImFkZC1hdHRyaWJ1dGVcIixcbiAgICBkZXNjcmlwdGlvbjogXCJBZGQgYSBkZWNvcmF0ZWQgYXR0cmlidXRlIHRvIGFuIGV4aXN0aW5nIG1vZGVsXCIsXG4gICAgZXhlY3V0ZTogYXN5bmMgKGFyZ3M6IHtcbiAgICAgIGZpbGVQYXRoOiBzdHJpbmc7XG4gICAgICBjbGFzc05hbWU6IHN0cmluZztcbiAgICAgIGF0dHJpYnV0ZTogQXR0cmlidXRlU3BlYztcbiAgICAgIGltcG9ydHNGcm9tOiBzdHJpbmc7XG4gICAgfSkgPT4ge1xuICAgICAgaWYgKCFmcy5leGlzdHNTeW5jKGFyZ3MuZmlsZVBhdGgpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgTW9kZWwgZmlsZSBub3QgZm91bmQgYXQgJHthcmdzLmZpbGVQYXRofWApO1xuICAgICAgfVxuICAgICAgbGV0IGNvbnRlbnQgPSBmcy5yZWFkRmlsZVN5bmMoYXJncy5maWxlUGF0aCwgXCJ1dGY4XCIpO1xuICAgICAgaWYgKGNvbnRlbnQuaW5jbHVkZXMoYCR7YXJncy5hdHRyaWJ1dGUubmFtZX06YCkpIHtcbiAgICAgICAgcmV0dXJuIHsgZmlsZVBhdGg6IGFyZ3MuZmlsZVBhdGggfTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGRlY29yYXRvcnMgPSBjb2xsZWN0RGVjb3JhdG9yTmFtZXModW5kZWZpbmVkLCBbYXJncy5hdHRyaWJ1dGVdKTtcbiAgICAgIGNvbnRlbnQgPSBlbnN1cmVJbXBvcnQoY29udGVudCwgYXJncy5pbXBvcnRzRnJvbSwgZGVjb3JhdG9ycyk7XG4gICAgICBjb25zdCBpbnNlcnRpb25Qb2ludCA9IGNvbnRlbnQubGFzdEluZGV4T2YoXCJ9XCIpO1xuICAgICAgY29uc3QgYmxvY2sgPSBhZGRQcm9wZXJ0eUJsb2NrKGFyZ3MuYXR0cmlidXRlKTtcbiAgICAgIGNvbnN0IGJlZm9yZSA9IGNvbnRlbnQuc2xpY2UoMCwgaW5zZXJ0aW9uUG9pbnQpLnJlcGxhY2UoL1xccyokLywgXCJcIik7XG4gICAgICBjb25zdCBhZnRlciA9IGNvbnRlbnQuc2xpY2UoaW5zZXJ0aW9uUG9pbnQpO1xuICAgICAgY29uc3QgdXBkYXRlZCA9IGAke2JlZm9yZX1cXG4ke2Jsb2NrfVxcbiR7YWZ0ZXJ9YDtcbiAgICAgIHdyaXRlSWZDaGFuZ2VkKGFyZ3MuZmlsZVBhdGgsIHVwZGF0ZWQpO1xuICAgICAgcmV0dXJuIHsgZmlsZVBhdGg6IGFyZ3MuZmlsZVBhdGggfTtcbiAgICB9LFxuICB9LFxuICByZW1vdmVBdHRyaWJ1dGVUb29sOiB7XG4gICAgbmFtZTogXCJyZW1vdmUtYXR0cmlidXRlXCIsXG4gICAgZGVzY3JpcHRpb246IFwiUmVtb3ZlIGFuIGF0dHJpYnV0ZSBmcm9tIGEgbW9kZWwgY2xhc3NcIixcbiAgICBleGVjdXRlOiBhc3luYyAoYXJnczoge1xuICAgICAgZmlsZVBhdGg6IHN0cmluZztcbiAgICAgIGNsYXNzTmFtZTogc3RyaW5nO1xuICAgICAgYXR0cmlidXRlTmFtZTogc3RyaW5nO1xuICAgIH0pID0+IHtcbiAgICAgIGlmICghZnMuZXhpc3RzU3luYyhhcmdzLmZpbGVQYXRoKSkgcmV0dXJuIHsgZmlsZVBhdGg6IGFyZ3MuZmlsZVBhdGggfTtcbiAgICAgIGNvbnN0IGNvbnRlbnQgPSBmcy5yZWFkRmlsZVN5bmMoYXJncy5maWxlUGF0aCwgXCJ1dGY4XCIpO1xuICAgICAgY29uc3QgdXBkYXRlZCA9IHJlbW92ZVByb3BlcnR5QmxvY2soY29udGVudCwgYXJncy5hdHRyaWJ1dGVOYW1lKTtcbiAgICAgIHdyaXRlSWZDaGFuZ2VkKGFyZ3MuZmlsZVBhdGgsIHVwZGF0ZWQpO1xuICAgICAgcmV0dXJuIHsgZmlsZVBhdGg6IGFyZ3MuZmlsZVBhdGggfTtcbiAgICB9LFxuICB9LFxuICBhcHBseURlY29yYXRvclRvb2w6IHtcbiAgICBuYW1lOiBcImFwcGx5LWRlY29yYXRvclwiLFxuICAgIGRlc2NyaXB0aW9uOiBcIkFwcGx5IGEgZGVjb3JhdG9yIHRvIGEgY2xhc3Mgb3IgcHJvcGVydHlcIixcbiAgICBleGVjdXRlOiBhc3luYyAoYXJnczoge1xuICAgICAgZmlsZVBhdGg6IHN0cmluZztcbiAgICAgIGNsYXNzTmFtZTogc3RyaW5nO1xuICAgICAgdGFyZ2V0OiB7IGtpbmQ6IFwiY2xhc3NcIiB8IFwicHJvcGVydHlcIjsgbmFtZT86IHN0cmluZyB9O1xuICAgICAgZGVjb3JhdG9yOiBEZWNvcmF0b3JTcGVjO1xuICAgICAgaW1wb3J0c0Zyb206IHN0cmluZztcbiAgICB9KSA9PiB7XG4gICAgICBpZiAoIWZzLmV4aXN0c1N5bmMoYXJncy5maWxlUGF0aCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBNb2RlbCBmaWxlIG5vdCBmb3VuZCBhdCAke2FyZ3MuZmlsZVBhdGh9YCk7XG4gICAgICB9XG4gICAgICBsZXQgY29udGVudCA9IGZzLnJlYWRGaWxlU3luYyhhcmdzLmZpbGVQYXRoLCBcInV0ZjhcIik7XG4gICAgICBjb25zdCBkZWNvcmF0b3JzID0gbmV3IFNldDxzdHJpbmc+KFthcmdzLmRlY29yYXRvci5uYW1lXSk7XG4gICAgICBjb250ZW50ID0gZW5zdXJlSW1wb3J0KGNvbnRlbnQsIGFyZ3MuaW1wb3J0c0Zyb20sIGRlY29yYXRvcnMpO1xuICAgICAgY29udGVudCA9IGluc2VydERlY29yYXRvcihjb250ZW50LCBhcmdzLmRlY29yYXRvciwgYXJncy50YXJnZXQpO1xuICAgICAgd3JpdGVJZkNoYW5nZWQoYXJncy5maWxlUGF0aCwgY29udGVudCk7XG4gICAgICByZXR1cm4geyBmaWxlUGF0aDogYXJncy5maWxlUGF0aCB9O1xuICAgIH0sXG4gIH0sXG4gIHJlbW92ZURlY29yYXRvclRvb2w6IHtcbiAgICBuYW1lOiBcInJlbW92ZS1kZWNvcmF0b3JcIixcbiAgICBkZXNjcmlwdGlvbjogXCJSZW1vdmUgYSBkZWNvcmF0b3IgZnJvbSBhIGNsYXNzIG9yIHByb3BlcnR5XCIsXG4gICAgZXhlY3V0ZTogYXN5bmMgKGFyZ3M6IHtcbiAgICAgIGZpbGVQYXRoOiBzdHJpbmc7XG4gICAgICBjbGFzc05hbWU6IHN0cmluZztcbiAgICAgIHRhcmdldDogeyBraW5kOiBcImNsYXNzXCIgfCBcInByb3BlcnR5XCI7IG5hbWU/OiBzdHJpbmcgfTtcbiAgICAgIGRlY29yYXRvck5hbWU6IHN0cmluZztcbiAgICB9KSA9PiB7XG4gICAgICBpZiAoIWZzLmV4aXN0c1N5bmMoYXJncy5maWxlUGF0aCkpIHJldHVybiB7IGZpbGVQYXRoOiBhcmdzLmZpbGVQYXRoIH07XG4gICAgICBsZXQgY29udGVudCA9IGZzLnJlYWRGaWxlU3luYyhhcmdzLmZpbGVQYXRoLCBcInV0ZjhcIik7XG4gICAgICBjb250ZW50ID0gcmVtb3ZlRGVjb3JhdG9yKGNvbnRlbnQsIGFyZ3MuZGVjb3JhdG9yTmFtZSwgYXJncy50YXJnZXQpO1xuICAgICAgd3JpdGVJZkNoYW5nZWQoYXJncy5maWxlUGF0aCwgY29udGVudCk7XG4gICAgICByZXR1cm4geyBmaWxlUGF0aDogYXJncy5maWxlUGF0aCB9O1xuICAgIH0sXG4gIH0sXG4gIHNjYWZmb2xkVmFsaWRhdG9yVG9vbDoge1xuICAgIG5hbWU6IFwic2NhZmZvbGQtdmFsaWRhdG9yXCIsXG4gICAgZGVzY3JpcHRpb246IFwiU2NhZmZvbGQgYSB2YWxpZGF0b3IgY2xhc3MgYW5kIG9wdGlvbmFsIGRlY29yYXRvclwiLFxuICAgIGV4ZWN1dGU6IGFzeW5jIChhcmdzOiB7XG4gICAgICB2YWxpZGF0b3JzRGlyOiBzdHJpbmc7XG4gICAgICBkZWNvcmF0b3JEaXI/OiBzdHJpbmc7XG4gICAgICBuYW1lOiBzdHJpbmc7XG4gICAgfSkgPT4ge1xuICAgICAgY29uc3QgY2xhc3NGaWxlID0gcGF0aC5qb2luKGFyZ3MudmFsaWRhdG9yc0RpciwgYCR7YXJncy5uYW1lfS50c2ApO1xuICAgICAgZW5zdXJlRGlyZWN0b3J5KGNsYXNzRmlsZSk7XG4gICAgICBjb25zdCBjbGFzc0NvbnRlbnQgPSBgZXhwb3J0IGNsYXNzICR7YXJncy5uYW1lfSB7XFxuICB2YWxpZGF0ZSh2YWx1ZTogdW5rbm93bik6IGJvb2xlYW4ge1xcbiAgICByZXR1cm4gdmFsdWUgIT09IHVuZGVmaW5lZDtcXG4gIH1cXG59XFxuYDtcbiAgICAgIGZzLndyaXRlRmlsZVN5bmMoY2xhc3NGaWxlLCBjbGFzc0NvbnRlbnQpO1xuICAgICAgbGV0IGRlY29yYXRvckZpbGU6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgICAgIGlmIChhcmdzLmRlY29yYXRvckRpcikge1xuICAgICAgICBkZWNvcmF0b3JGaWxlID0gcGF0aC5qb2luKFxuICAgICAgICAgIGFyZ3MuZGVjb3JhdG9yRGlyLFxuICAgICAgICAgIGAke2FyZ3MubmFtZX1EZWNvcmF0b3IudHNgXG4gICAgICAgICk7XG4gICAgICAgIGVuc3VyZURpcmVjdG9yeShkZWNvcmF0b3JGaWxlKTtcbiAgICAgICAgZnMud3JpdGVGaWxlU3luYyhcbiAgICAgICAgICBkZWNvcmF0b3JGaWxlLFxuICAgICAgICAgIGBleHBvcnQgZnVuY3Rpb24gJHthcmdzLm5hbWV9RGVjb3JhdG9yKCkge1xcbiAgcmV0dXJuICgpID0+IHZvaWQgMDtcXG59XFxuYFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHsgY2xhc3NGaWxlLCBkZWNvcmF0b3JGaWxlIH07XG4gICAgfSxcbiAgfSxcbiAgc2NhZmZvbGRTZXJpYWxpemVyVG9vbDoge1xuICAgIG5hbWU6IFwic2NhZmZvbGQtc2VyaWFsaXplclwiLFxuICAgIGRlc2NyaXB0aW9uOiBcIlNjYWZmb2xkIGEgc2VyaWFsaXplciBjbGFzcyBhbmQgb3B0aW9uYWwgcmVnaXN0cnlcIixcbiAgICBleGVjdXRlOiBhc3luYyAoYXJnczoge1xuICAgICAgZGlyOiBzdHJpbmc7XG4gICAgICBuYW1lOiBzdHJpbmc7XG4gICAgICByZWdpc3RlckRpcj86IHN0cmluZztcbiAgICAgIHNldERlZmF1bHQ/OiBib29sZWFuO1xuICAgIH0pID0+IHtcbiAgICAgIGNvbnN0IGNsYXNzRmlsZSA9IHBhdGguam9pbihhcmdzLmRpciwgYCR7YXJncy5uYW1lfS50c2ApO1xuICAgICAgZW5zdXJlRGlyZWN0b3J5KGNsYXNzRmlsZSk7XG4gICAgICBmcy53cml0ZUZpbGVTeW5jKFxuICAgICAgICBjbGFzc0ZpbGUsXG4gICAgICAgIGBleHBvcnQgY2xhc3MgJHthcmdzLm5hbWV9IHtcXG4gIHNlcmlhbGl6ZSh2YWx1ZTogdW5rbm93bik6IHN0cmluZyB7XFxuICAgIHJldHVybiBKU09OLnN0cmluZ2lmeSh2YWx1ZSk7XFxuICB9XFxufVxcbmBcbiAgICAgICk7XG4gICAgICBsZXQgcmVnaXN0ZXJGaWxlOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICAgICBpZiAoYXJncy5yZWdpc3RlckRpcikge1xuICAgICAgICByZWdpc3RlckZpbGUgPSBwYXRoLmpvaW4oYXJncy5yZWdpc3RlckRpciwgYCR7YXJncy5uYW1lfVJlZ2lzdGVyLnRzYCk7XG4gICAgICAgIGVuc3VyZURpcmVjdG9yeShyZWdpc3RlckZpbGUpO1xuICAgICAgICBmcy53cml0ZUZpbGVTeW5jKFxuICAgICAgICAgIHJlZ2lzdGVyRmlsZSxcbiAgICAgICAgICBgZXhwb3J0IGZ1bmN0aW9uIHJlZ2lzdGVyJHthcmdzLm5hbWV9KCkge1xcbiAgcmV0dXJuICR7YXJncy5zZXREZWZhdWx0ID8gXCInZGVmYXVsdCdcIiA6IFwiJ29wdGlvbmFsJ1wifTtcXG59XFxuYFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHsgY2xhc3NGaWxlLCByZWdpc3RlckZpbGUgfTtcbiAgICB9LFxuICB9LFxuICBzY2FmZm9sZEhhc2hpbmdUb29sOiB7XG4gICAgbmFtZTogXCJzY2FmZm9sZC1oYXNoaW5nXCIsXG4gICAgZGVzY3JpcHRpb246IFwiU2NhZmZvbGQgYSBoYXNoaW5nIGZ1bmN0aW9uIGFuZCBvcHRpb25hbCByZWdpc3RyeVwiLFxuICAgIGV4ZWN1dGU6IGFzeW5jIChhcmdzOiB7XG4gICAgICBkaXI6IHN0cmluZztcbiAgICAgIG5hbWU6IHN0cmluZztcbiAgICAgIHJlZ2lzdGVyRGlyPzogc3RyaW5nO1xuICAgICAgc2V0RGVmYXVsdD86IGJvb2xlYW47XG4gICAgfSkgPT4ge1xuICAgICAgY29uc3QgZnVuY3Rpb25GaWxlID0gcGF0aC5qb2luKGFyZ3MuZGlyLCBgJHthcmdzLm5hbWV9LnRzYCk7XG4gICAgICBlbnN1cmVEaXJlY3RvcnkoZnVuY3Rpb25GaWxlKTtcbiAgICAgIGZzLndyaXRlRmlsZVN5bmMoXG4gICAgICAgIGZ1bmN0aW9uRmlsZSxcbiAgICAgICAgYGV4cG9ydCBmdW5jdGlvbiAke2FyZ3MubmFtZX0odmFsdWU6IHN0cmluZyk6IHN0cmluZyB7XFxuICByZXR1cm4gdmFsdWUuc3BsaXQoJycpLnJldmVyc2UoKS5qb2luKCcnKTtcXG59XFxuYFxuICAgICAgKTtcbiAgICAgIGxldCByZWdpc3RlckZpbGU6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgICAgIGlmIChhcmdzLnJlZ2lzdGVyRGlyKSB7XG4gICAgICAgIHJlZ2lzdGVyRmlsZSA9IHBhdGguam9pbihhcmdzLnJlZ2lzdGVyRGlyLCBgJHthcmdzLm5hbWV9UmVnaXN0ZXIudHNgKTtcbiAgICAgICAgZW5zdXJlRGlyZWN0b3J5KHJlZ2lzdGVyRmlsZSk7XG4gICAgICAgIGZzLndyaXRlRmlsZVN5bmMoXG4gICAgICAgICAgcmVnaXN0ZXJGaWxlLFxuICAgICAgICAgIGBleHBvcnQgZnVuY3Rpb24gcmVnaXN0ZXIke2FyZ3MubmFtZX0oKSB7XFxuICByZXR1cm4gJHthcmdzLnNldERlZmF1bHQgPyBcIidkZWZhdWx0J1wiIDogXCInb3B0aW9uYWwnXCJ9O1xcbn1cXG5gXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICByZXR1cm4geyBmdW5jdGlvbkZpbGUsIHJlZ2lzdGVyRmlsZSB9O1xuICAgIH0sXG4gIH0sXG59IGFzIGNvbnN0O1xuXG5leHBvcnQgdHlwZSBEZWNvcmF0b3JUb29scyA9IHR5cGVvZiBkZWNvcmF0b3JUb29scztcbiJdfQ==
@@ -0,0 +1,14 @@
1
+ export type FastMCPLike = {
2
+ addPrompt: (p: any) => void;
3
+ addTool: (t: any) => void;
4
+ addResource: (r: any) => void;
5
+ addResourceTemplate: (t: any) => void;
6
+ };
7
+ /**
8
+ * Aggregate module assets and register them on the provided FastMCP-like server.
9
+ * Falls back to built-in lists if aggregation yields none.
10
+ */
11
+ export declare function EnrichCoreWithAggregation(server: FastMCPLike, repoRoot?: string): Promise<{
12
+ modulesChecked: number;
13
+ conflicts: import("./aggregateModules").AggregationConflict[];
14
+ }>;