@frontmcp/plugins 0.4.1 → 0.5.1

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 (98) hide show
  1. package/package.json +8 -3
  2. package/src/cache/cache.plugin.js +27 -25
  3. package/src/cache/cache.plugin.js.map +1 -1
  4. package/src/cache/providers/cache-memory.provider.js +2 -1
  5. package/src/cache/providers/cache-memory.provider.js.map +1 -1
  6. package/src/cache/providers/cache-redis.provider.js +1 -0
  7. package/src/cache/providers/cache-redis.provider.js.map +1 -1
  8. package/src/codecall/README.md +999 -0
  9. package/src/codecall/codecall.plugin.d.ts +41 -0
  10. package/src/codecall/codecall.plugin.js +152 -0
  11. package/src/codecall/codecall.plugin.js.map +1 -0
  12. package/src/codecall/codecall.symbol.d.ts +106 -0
  13. package/src/codecall/codecall.symbol.js +4 -0
  14. package/src/codecall/codecall.symbol.js.map +1 -0
  15. package/src/codecall/codecall.types.d.ts +289 -0
  16. package/src/codecall/codecall.types.js +258 -0
  17. package/src/codecall/codecall.types.js.map +1 -0
  18. package/src/codecall/errors/index.d.ts +1 -0
  19. package/src/codecall/errors/index.js +6 -0
  20. package/src/codecall/errors/index.js.map +1 -0
  21. package/src/codecall/errors/tool-call.errors.d.ts +79 -0
  22. package/src/codecall/errors/tool-call.errors.js +119 -0
  23. package/src/codecall/errors/tool-call.errors.js.map +1 -0
  24. package/src/codecall/index.d.ts +2 -0
  25. package/src/codecall/index.js +8 -0
  26. package/src/codecall/index.js.map +1 -0
  27. package/src/codecall/providers/code-call.config.d.ts +29 -0
  28. package/src/codecall/providers/code-call.config.js +120 -0
  29. package/src/codecall/providers/code-call.config.js.map +1 -0
  30. package/src/codecall/security/index.d.ts +2 -0
  31. package/src/codecall/security/index.js +7 -0
  32. package/src/codecall/security/index.js.map +1 -0
  33. package/src/codecall/security/self-reference-guard.d.ts +32 -0
  34. package/src/codecall/security/self-reference-guard.js +70 -0
  35. package/src/codecall/security/self-reference-guard.js.map +1 -0
  36. package/src/codecall/security/tool-access-control.service.d.ts +104 -0
  37. package/src/codecall/security/tool-access-control.service.js +170 -0
  38. package/src/codecall/security/tool-access-control.service.js.map +1 -0
  39. package/src/codecall/services/audit-logger.service.d.ts +186 -0
  40. package/src/codecall/services/audit-logger.service.js +322 -0
  41. package/src/codecall/services/audit-logger.service.js.map +1 -0
  42. package/src/codecall/services/enclave.service.d.ts +62 -0
  43. package/src/codecall/services/enclave.service.js +214 -0
  44. package/src/codecall/services/enclave.service.js.map +1 -0
  45. package/src/codecall/services/error-enrichment.service.d.ts +94 -0
  46. package/src/codecall/services/error-enrichment.service.js +387 -0
  47. package/src/codecall/services/error-enrichment.service.js.map +1 -0
  48. package/src/codecall/services/index.d.ts +6 -0
  49. package/src/codecall/services/index.js +13 -0
  50. package/src/codecall/services/index.js.map +1 -0
  51. package/src/codecall/services/output-sanitizer.d.ts +86 -0
  52. package/src/codecall/services/output-sanitizer.js +260 -0
  53. package/src/codecall/services/output-sanitizer.js.map +1 -0
  54. package/src/codecall/services/synonym-expansion.service.d.ts +66 -0
  55. package/src/codecall/services/synonym-expansion.service.js +374 -0
  56. package/src/codecall/services/synonym-expansion.service.js.map +1 -0
  57. package/src/codecall/services/tool-search.service.d.ts +175 -0
  58. package/src/codecall/services/tool-search.service.js +587 -0
  59. package/src/codecall/services/tool-search.service.js.map +1 -0
  60. package/src/codecall/tools/describe.schema.d.ts +28 -0
  61. package/src/codecall/tools/describe.schema.js +67 -0
  62. package/src/codecall/tools/describe.schema.js.map +1 -0
  63. package/src/codecall/tools/describe.tool.d.ts +35 -0
  64. package/src/codecall/tools/describe.tool.js +207 -0
  65. package/src/codecall/tools/describe.tool.js.map +1 -0
  66. package/src/codecall/tools/execute.schema.d.ts +115 -0
  67. package/src/codecall/tools/execute.schema.js +116 -0
  68. package/src/codecall/tools/execute.schema.js.map +1 -0
  69. package/src/codecall/tools/execute.tool.d.ts +5 -0
  70. package/src/codecall/tools/execute.tool.js +238 -0
  71. package/src/codecall/tools/execute.tool.js.map +1 -0
  72. package/src/codecall/tools/index.d.ts +4 -0
  73. package/src/codecall/tools/index.js +13 -0
  74. package/src/codecall/tools/index.js.map +1 -0
  75. package/src/codecall/tools/invoke.schema.d.ts +99 -0
  76. package/src/codecall/tools/invoke.schema.js +27 -0
  77. package/src/codecall/tools/invoke.schema.js.map +1 -0
  78. package/src/codecall/tools/invoke.tool.d.ts +13 -0
  79. package/src/codecall/tools/invoke.tool.js +70 -0
  80. package/src/codecall/tools/invoke.tool.js.map +1 -0
  81. package/src/codecall/tools/search.schema.d.ts +30 -0
  82. package/src/codecall/tools/search.schema.js +60 -0
  83. package/src/codecall/tools/search.schema.js.map +1 -0
  84. package/src/codecall/tools/search.tool.d.ts +5 -0
  85. package/src/codecall/tools/search.tool.js +108 -0
  86. package/src/codecall/tools/search.tool.js.map +1 -0
  87. package/src/codecall/utils/describe.utils.d.ts +86 -0
  88. package/src/codecall/utils/describe.utils.js +531 -0
  89. package/src/codecall/utils/describe.utils.js.map +1 -0
  90. package/src/codecall/utils/index.d.ts +2 -0
  91. package/src/codecall/utils/index.js +7 -0
  92. package/src/codecall/utils/index.js.map +1 -0
  93. package/src/codecall/utils/mcp-result.d.ts +6 -0
  94. package/src/codecall/utils/mcp-result.js +36 -0
  95. package/src/codecall/utils/mcp-result.js.map +1 -0
  96. package/src/index.d.ts +2 -0
  97. package/src/index.js +3 -1
  98. package/src/index.js.map +1 -1
@@ -0,0 +1,260 @@
1
+ "use strict";
2
+ // file: libs/plugins/src/codecall/services/output-sanitizer.ts
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.DEFAULT_SANITIZER_CONFIG = void 0;
5
+ exports.sanitizeOutput = sanitizeOutput;
6
+ exports.needsSanitization = needsSanitization;
7
+ exports.sanitizeLogMessage = sanitizeLogMessage;
8
+ /**
9
+ * Default sanitization configuration.
10
+ */
11
+ exports.DEFAULT_SANITIZER_CONFIG = Object.freeze({
12
+ maxDepth: 10,
13
+ maxStringLength: 10000,
14
+ maxObjectKeys: 100,
15
+ maxArrayLength: 1000,
16
+ maxTotalSize: 1024 * 1024, // 1MB
17
+ removeStackTraces: true,
18
+ removeFilePaths: true,
19
+ });
20
+ /**
21
+ * Sanitize output from CodeCall script execution.
22
+ *
23
+ * @param output - Raw output from script
24
+ * @param config - Sanitization configuration
25
+ * @returns Sanitized output with metadata
26
+ */
27
+ function sanitizeOutput(output, config = {}) {
28
+ const cfg = { ...exports.DEFAULT_SANITIZER_CONFIG, ...config };
29
+ const warnings = [];
30
+ const seen = new WeakSet();
31
+ const result = sanitizeValue(output, cfg, warnings, seen, 0);
32
+ // Check total size
33
+ try {
34
+ const serialized = JSON.stringify(result);
35
+ if (serialized && serialized.length > cfg.maxTotalSize) {
36
+ warnings.push(`Output truncated: exceeded max size of ${cfg.maxTotalSize} bytes`);
37
+ return {
38
+ value: { _truncated: true, _reason: 'Output exceeded maximum size' },
39
+ wasModified: true,
40
+ warnings,
41
+ };
42
+ }
43
+ }
44
+ catch {
45
+ // If we can't serialize, return a safe placeholder
46
+ warnings.push('Output could not be serialized');
47
+ return {
48
+ value: { _error: 'Output could not be serialized' },
49
+ wasModified: true,
50
+ warnings,
51
+ };
52
+ }
53
+ return {
54
+ value: result,
55
+ wasModified: warnings.length > 0,
56
+ warnings,
57
+ };
58
+ }
59
+ /**
60
+ * Recursively sanitize a value.
61
+ */
62
+ function sanitizeValue(value, config, warnings, seen, depth) {
63
+ // Check depth
64
+ if (depth > config.maxDepth) {
65
+ warnings.push(`Max depth of ${config.maxDepth} exceeded`);
66
+ return '[max depth exceeded]';
67
+ }
68
+ // Handle null/undefined
69
+ if (value === null || value === undefined) {
70
+ return value;
71
+ }
72
+ // Handle primitives
73
+ if (typeof value === 'string') {
74
+ return sanitizeString(value, config, warnings);
75
+ }
76
+ if (typeof value === 'number' || typeof value === 'boolean') {
77
+ return value;
78
+ }
79
+ if (typeof value === 'bigint') {
80
+ return value.toString();
81
+ }
82
+ if (typeof value === 'symbol') {
83
+ return value.toString();
84
+ }
85
+ if (typeof value === 'function') {
86
+ warnings.push('Function removed from output');
87
+ return '[function]';
88
+ }
89
+ // Handle objects
90
+ if (typeof value === 'object') {
91
+ // Check for circular references
92
+ if (seen.has(value)) {
93
+ warnings.push('Circular reference detected');
94
+ return '[circular]';
95
+ }
96
+ seen.add(value);
97
+ // Handle arrays
98
+ if (Array.isArray(value)) {
99
+ return sanitizeArray(value, config, warnings, seen, depth);
100
+ }
101
+ // Handle Error objects
102
+ if (value instanceof Error) {
103
+ return sanitizeError(value, config, warnings);
104
+ }
105
+ // Handle Date objects
106
+ if (value instanceof Date) {
107
+ return value.toISOString();
108
+ }
109
+ // Handle RegExp objects
110
+ if (value instanceof RegExp) {
111
+ return value.toString();
112
+ }
113
+ // Handle Map
114
+ if (value instanceof Map) {
115
+ const obj = {};
116
+ let count = 0;
117
+ for (const [k, v] of value) {
118
+ if (count >= config.maxObjectKeys) {
119
+ warnings.push(`Map truncated: exceeded ${config.maxObjectKeys} keys`);
120
+ break;
121
+ }
122
+ obj[String(k)] = sanitizeValue(v, config, warnings, seen, depth + 1);
123
+ count++;
124
+ }
125
+ return obj;
126
+ }
127
+ // Handle Set
128
+ if (value instanceof Set) {
129
+ const arr = [];
130
+ let count = 0;
131
+ for (const item of value) {
132
+ if (count >= config.maxArrayLength) {
133
+ warnings.push(`Set truncated: exceeded ${config.maxArrayLength} items`);
134
+ break;
135
+ }
136
+ arr.push(sanitizeValue(item, config, warnings, seen, depth + 1));
137
+ count++;
138
+ }
139
+ return arr;
140
+ }
141
+ // Handle plain objects
142
+ return sanitizeObject(value, config, warnings, seen, depth);
143
+ }
144
+ // Unknown type - return safe string representation
145
+ return String(value);
146
+ }
147
+ /**
148
+ * Sanitize a string value.
149
+ */
150
+ function sanitizeString(value, config, warnings) {
151
+ let result = value;
152
+ // Remove file paths if configured
153
+ if (config.removeFilePaths) {
154
+ const pathRegex = /(?:\/[\w.-]+)+|(?:[A-Za-z]:\\[\w\\.-]+)+/g;
155
+ if (pathRegex.test(result)) {
156
+ result = result.replace(pathRegex, '[path]');
157
+ warnings.push('File paths removed from string');
158
+ }
159
+ }
160
+ // Truncate if too long
161
+ if (result.length > config.maxStringLength) {
162
+ result = result.substring(0, config.maxStringLength) + '...[truncated]';
163
+ warnings.push(`String truncated: exceeded ${config.maxStringLength} characters`);
164
+ }
165
+ return result;
166
+ }
167
+ /**
168
+ * Sanitize an array.
169
+ */
170
+ function sanitizeArray(value, config, warnings, seen, depth) {
171
+ const result = [];
172
+ const limit = Math.min(value.length, config.maxArrayLength);
173
+ for (let i = 0; i < limit; i++) {
174
+ result.push(sanitizeValue(value[i], config, warnings, seen, depth + 1));
175
+ }
176
+ if (value.length > config.maxArrayLength) {
177
+ warnings.push(`Array truncated: ${value.length} items reduced to ${config.maxArrayLength}`);
178
+ }
179
+ return result;
180
+ }
181
+ /**
182
+ * Sanitize a plain object.
183
+ */
184
+ function sanitizeObject(value, config, warnings, seen, depth) {
185
+ const result = {};
186
+ const keys = Object.keys(value);
187
+ const limit = Math.min(keys.length, config.maxObjectKeys);
188
+ for (let i = 0; i < limit; i++) {
189
+ const key = keys[i];
190
+ // Skip prototype pollution vectors
191
+ if (key === '__proto__' || key === 'constructor' || key === 'prototype') {
192
+ warnings.push(`Dangerous key "${key}" removed`);
193
+ continue;
194
+ }
195
+ result[key] = sanitizeValue(value[key], config, warnings, seen, depth + 1);
196
+ }
197
+ if (keys.length > config.maxObjectKeys) {
198
+ warnings.push(`Object truncated: ${keys.length} keys reduced to ${config.maxObjectKeys}`);
199
+ }
200
+ return result;
201
+ }
202
+ /**
203
+ * Sanitize an Error object.
204
+ */
205
+ function sanitizeError(error, config, warnings) {
206
+ const result = {
207
+ name: error.name,
208
+ message: sanitizeString(error.message, config, warnings),
209
+ };
210
+ // Include stack only if configured
211
+ if (!config.removeStackTraces && error.stack) {
212
+ result['stack'] = sanitizeString(error.stack, config, warnings);
213
+ }
214
+ else if (error.stack) {
215
+ warnings.push('Stack trace removed');
216
+ }
217
+ // Include error code if present
218
+ if ('code' in error) {
219
+ result['code'] = error.code;
220
+ }
221
+ return result;
222
+ }
223
+ /**
224
+ * Quick check if a value needs sanitization.
225
+ * Used for optimization - skip sanitization for simple values.
226
+ */
227
+ function needsSanitization(value) {
228
+ if (value === null || value === undefined) {
229
+ return false;
230
+ }
231
+ if (typeof value === 'number' || typeof value === 'boolean') {
232
+ return false;
233
+ }
234
+ if (typeof value === 'string') {
235
+ // Quick heuristic: check if string might contain paths
236
+ return value.length > 100 || value.includes('/') || value.includes('\\');
237
+ }
238
+ // Objects and arrays always need checking
239
+ return true;
240
+ }
241
+ /**
242
+ * Sanitize a log message (less aggressive than output sanitization).
243
+ */
244
+ function sanitizeLogMessage(message, maxLength = 500) {
245
+ if (!message)
246
+ return '';
247
+ let result = message;
248
+ // Remove file paths
249
+ result = result.replace(/(?:\/[\w.-]+)+|(?:[A-Za-z]:\\[\w\\.-]+)+/g, '[path]');
250
+ // Remove line numbers
251
+ result = result.replace(/:\d+:\d+/g, '');
252
+ // Remove stack trace lines
253
+ result = result.replace(/\n\s*at .*/g, '');
254
+ // Truncate
255
+ if (result.length > maxLength) {
256
+ result = result.substring(0, maxLength) + '...';
257
+ }
258
+ return result.trim();
259
+ }
260
+ //# sourceMappingURL=output-sanitizer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output-sanitizer.js","sourceRoot":"","sources":["../../../../src/codecall/services/output-sanitizer.ts"],"names":[],"mappings":";AAAA,+DAA+D;;;AAgG/D,wCAoCC;AA6ND,8CAgBC;AAKD,gDAoBC;AA1UD;;GAEG;AACU,QAAA,wBAAwB,GAA0B,MAAM,CAAC,MAAM,CAAC;IAC3E,QAAQ,EAAE,EAAE;IACZ,eAAe,EAAE,KAAK;IACtB,aAAa,EAAE,GAAG;IAClB,cAAc,EAAE,IAAI;IACpB,YAAY,EAAE,IAAI,GAAG,IAAI,EAAE,MAAM;IACjC,iBAAiB,EAAE,IAAI;IACvB,eAAe,EAAE,IAAI;CACtB,CAAC,CAAC;AAcH;;;;;;GAMG;AACH,SAAgB,cAAc,CAC5B,MAAe,EACf,SAAyC,EAAE;IAE3C,MAAM,GAAG,GAAG,EAAE,GAAG,gCAAwB,EAAE,GAAG,MAAM,EAAE,CAAC;IACvD,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,IAAI,GAAG,IAAI,OAAO,EAAU,CAAC;IAEnC,MAAM,MAAM,GAAG,aAAa,CAAC,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAE7D,mBAAmB;IACnB,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC1C,IAAI,UAAU,IAAI,UAAU,CAAC,MAAM,GAAG,GAAG,CAAC,YAAY,EAAE,CAAC;YACvD,QAAQ,CAAC,IAAI,CAAC,0CAA0C,GAAG,CAAC,YAAY,QAAQ,CAAC,CAAC;YAClF,OAAO;gBACL,KAAK,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,8BAA8B,EAAO;gBACzE,WAAW,EAAE,IAAI;gBACjB,QAAQ;aACT,CAAC;QACJ,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,mDAAmD;QACnD,QAAQ,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;QAChD,OAAO;YACL,KAAK,EAAE,EAAE,MAAM,EAAE,gCAAgC,EAAO;YACxD,WAAW,EAAE,IAAI;YACjB,QAAQ;SACT,CAAC;IACJ,CAAC;IAED,OAAO;QACL,KAAK,EAAE,MAAW;QAClB,WAAW,EAAE,QAAQ,CAAC,MAAM,GAAG,CAAC;QAChC,QAAQ;KACT,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,aAAa,CACpB,KAAc,EACd,MAA6B,EAC7B,QAAkB,EAClB,IAAqB,EACrB,KAAa;IAEb,cAAc;IACd,IAAI,KAAK,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;QAC5B,QAAQ,CAAC,IAAI,CAAC,gBAAgB,MAAM,CAAC,QAAQ,WAAW,CAAC,CAAC;QAC1D,OAAO,sBAAsB,CAAC;IAChC,CAAC;IAED,wBAAwB;IACxB,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QAC1C,OAAO,KAAK,CAAC;IACf,CAAC;IAED,oBAAoB;IACpB,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;IACjD,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,SAAS,EAAE,CAAC;QAC5D,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC,QAAQ,EAAE,CAAC;IAC1B,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC,QAAQ,EAAE,CAAC;IAC1B,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,UAAU,EAAE,CAAC;QAChC,QAAQ,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;QAC9C,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,iBAAiB;IACjB,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,gCAAgC;QAChC,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YACpB,QAAQ,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;YAC7C,OAAO,YAAY,CAAC;QACtB,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAEhB,gBAAgB;QAChB,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACzB,OAAO,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;QAC7D,CAAC;QAED,uBAAuB;QACvB,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;YAC3B,OAAO,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;QAChD,CAAC;QAED,sBAAsB;QACtB,IAAI,KAAK,YAAY,IAAI,EAAE,CAAC;YAC1B,OAAO,KAAK,CAAC,WAAW,EAAE,CAAC;QAC7B,CAAC;QAED,wBAAwB;QACxB,IAAI,KAAK,YAAY,MAAM,EAAE,CAAC;YAC5B,OAAO,KAAK,CAAC,QAAQ,EAAE,CAAC;QAC1B,CAAC;QAED,aAAa;QACb,IAAI,KAAK,YAAY,GAAG,EAAE,CAAC;YACzB,MAAM,GAAG,GAA4B,EAAE,CAAC;YACxC,IAAI,KAAK,GAAG,CAAC,CAAC;YACd,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC;gBAC3B,IAAI,KAAK,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;oBAClC,QAAQ,CAAC,IAAI,CAAC,2BAA2B,MAAM,CAAC,aAAa,OAAO,CAAC,CAAC;oBACtE,MAAM;gBACR,CAAC;gBACD,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;gBACrE,KAAK,EAAE,CAAC;YACV,CAAC;YACD,OAAO,GAAG,CAAC;QACb,CAAC;QAED,aAAa;QACb,IAAI,KAAK,YAAY,GAAG,EAAE,CAAC;YACzB,MAAM,GAAG,GAAc,EAAE,CAAC;YAC1B,IAAI,KAAK,GAAG,CAAC,CAAC;YACd,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,IAAI,KAAK,IAAI,MAAM,CAAC,cAAc,EAAE,CAAC;oBACnC,QAAQ,CAAC,IAAI,CAAC,2BAA2B,MAAM,CAAC,cAAc,QAAQ,CAAC,CAAC;oBACxE,MAAM;gBACR,CAAC;gBACD,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;gBACjE,KAAK,EAAE,CAAC;YACV,CAAC;YACD,OAAO,GAAG,CAAC;QACb,CAAC;QAED,uBAAuB;QACvB,OAAO,cAAc,CAAC,KAAgC,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;IACzF,CAAC;IAED,mDAAmD;IACnD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC;AAED;;GAEG;AACH,SAAS,cAAc,CAAC,KAAa,EAAE,MAA6B,EAAE,QAAkB;IACtF,IAAI,MAAM,GAAG,KAAK,CAAC;IAEnB,kCAAkC;IAClC,IAAI,MAAM,CAAC,eAAe,EAAE,CAAC;QAC3B,MAAM,SAAS,GAAG,2CAA2C,CAAC;QAC9D,IAAI,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3B,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;YAC7C,QAAQ,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;IAED,uBAAuB;IACvB,IAAI,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,eAAe,EAAE,CAAC;QAC3C,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,eAAe,CAAC,GAAG,gBAAgB,CAAC;QACxE,QAAQ,CAAC,IAAI,CAAC,8BAA8B,MAAM,CAAC,eAAe,aAAa,CAAC,CAAC;IACnF,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,SAAS,aAAa,CACpB,KAAgB,EAChB,MAA6B,EAC7B,QAAkB,EAClB,IAAqB,EACrB,KAAa;IAEb,MAAM,MAAM,GAAc,EAAE,CAAC;IAC7B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,cAAc,CAAC,CAAC;IAE5D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;QAC/B,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;IAC1E,CAAC;IAED,IAAI,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,cAAc,EAAE,CAAC;QACzC,QAAQ,CAAC,IAAI,CAAC,oBAAoB,KAAK,CAAC,MAAM,qBAAqB,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC;IAC9F,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,SAAS,cAAc,CACrB,KAA8B,EAC9B,MAA6B,EAC7B,QAAkB,EAClB,IAAqB,EACrB,KAAa;IAEb,MAAM,MAAM,GAA4B,EAAE,CAAC;IAC3C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAChC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,aAAa,CAAC,CAAC;IAE1D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;QAC/B,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAEpB,mCAAmC;QACnC,IAAI,GAAG,KAAK,WAAW,IAAI,GAAG,KAAK,aAAa,IAAI,GAAG,KAAK,WAAW,EAAE,CAAC;YACxE,QAAQ,CAAC,IAAI,CAAC,kBAAkB,GAAG,WAAW,CAAC,CAAC;YAChD,SAAS;QACX,CAAC;QAED,MAAM,CAAC,GAAG,CAAC,GAAG,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;IAC7E,CAAC;IAED,IAAI,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,aAAa,EAAE,CAAC;QACvC,QAAQ,CAAC,IAAI,CAAC,qBAAqB,IAAI,CAAC,MAAM,oBAAoB,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC;IAC5F,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,SAAS,aAAa,CAAC,KAAY,EAAE,MAA6B,EAAE,QAAkB;IACpF,MAAM,MAAM,GAA4B;QACtC,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,OAAO,EAAE,cAAc,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC;KACzD,CAAC;IAEF,mCAAmC;IACnC,IAAI,CAAC,MAAM,CAAC,iBAAiB,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAC7C,MAAM,CAAC,OAAO,CAAC,GAAG,cAAc,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;IAClE,CAAC;SAAM,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QACvB,QAAQ,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;IACvC,CAAC;IAED,gCAAgC;IAChC,IAAI,MAAM,IAAI,KAAK,EAAE,CAAC;QACpB,MAAM,CAAC,MAAM,CAAC,GAAI,KAAa,CAAC,IAAI,CAAC;IACvC,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,SAAgB,iBAAiB,CAAC,KAAc;IAC9C,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QAC1C,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,SAAS,EAAE,CAAC;QAC5D,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,uDAAuD;QACvD,OAAO,KAAK,CAAC,MAAM,GAAG,GAAG,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC3E,CAAC;IAED,0CAA0C;IAC1C,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,SAAgB,kBAAkB,CAAC,OAAe,EAAE,SAAS,GAAG,GAAG;IACjE,IAAI,CAAC,OAAO;QAAE,OAAO,EAAE,CAAC;IAExB,IAAI,MAAM,GAAG,OAAO,CAAC;IAErB,oBAAoB;IACpB,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,2CAA2C,EAAE,QAAQ,CAAC,CAAC;IAE/E,sBAAsB;IACtB,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;IAEzC,2BAA2B;IAC3B,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;IAE3C,WAAW;IACX,IAAI,MAAM,CAAC,MAAM,GAAG,SAAS,EAAE,CAAC;QAC9B,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,SAAS,CAAC,GAAG,KAAK,CAAC;IAClD,CAAC;IAED,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC;AACvB,CAAC","sourcesContent":["// file: libs/plugins/src/codecall/services/output-sanitizer.ts\n\n/**\n * Output Sanitizer for CodeCall\n *\n * Sanitizes script outputs to prevent information leakage through:\n * - Error messages with stack traces or file paths\n * - Large outputs that could contain sensitive data\n * - Recursive structures that could cause DoS\n *\n * Security considerations:\n * - All sanitization is defensive (fail-safe)\n * - Outputs are truncated, not rejected\n * - Circular references are handled\n * - Prototype pollution is prevented\n */\n\n/**\n * Configuration for output sanitization.\n */\nexport interface OutputSanitizerConfig {\n /**\n * Maximum depth for nested objects/arrays.\n * @default 10\n */\n maxDepth: number;\n\n /**\n * Maximum length for string values.\n * @default 10000\n */\n maxStringLength: number;\n\n /**\n * Maximum number of keys in an object.\n * @default 100\n */\n maxObjectKeys: number;\n\n /**\n * Maximum number of items in an array.\n * @default 1000\n */\n maxArrayLength: number;\n\n /**\n * Maximum total size of serialized output in bytes.\n * @default 1MB\n */\n maxTotalSize: number;\n\n /**\n * Remove error stack traces.\n * @default true\n */\n removeStackTraces: boolean;\n\n /**\n * Remove file paths from strings.\n * @default true\n */\n removeFilePaths: boolean;\n}\n\n/**\n * Default sanitization configuration.\n */\nexport const DEFAULT_SANITIZER_CONFIG: OutputSanitizerConfig = Object.freeze({\n maxDepth: 10,\n maxStringLength: 10000,\n maxObjectKeys: 100,\n maxArrayLength: 1000,\n maxTotalSize: 1024 * 1024, // 1MB\n removeStackTraces: true,\n removeFilePaths: true,\n});\n\n/**\n * Result of sanitization.\n */\nexport interface SanitizationResult<T> {\n /** Sanitized value */\n value: T;\n /** Whether any sanitization was applied */\n wasModified: boolean;\n /** Warnings about what was sanitized */\n warnings: string[];\n}\n\n/**\n * Sanitize output from CodeCall script execution.\n *\n * @param output - Raw output from script\n * @param config - Sanitization configuration\n * @returns Sanitized output with metadata\n */\nexport function sanitizeOutput<T = unknown>(\n output: unknown,\n config: Partial<OutputSanitizerConfig> = {},\n): SanitizationResult<T> {\n const cfg = { ...DEFAULT_SANITIZER_CONFIG, ...config };\n const warnings: string[] = [];\n const seen = new WeakSet<object>();\n\n const result = sanitizeValue(output, cfg, warnings, seen, 0);\n\n // Check total size\n try {\n const serialized = JSON.stringify(result);\n if (serialized && serialized.length > cfg.maxTotalSize) {\n warnings.push(`Output truncated: exceeded max size of ${cfg.maxTotalSize} bytes`);\n return {\n value: { _truncated: true, _reason: 'Output exceeded maximum size' } as T,\n wasModified: true,\n warnings,\n };\n }\n } catch {\n // If we can't serialize, return a safe placeholder\n warnings.push('Output could not be serialized');\n return {\n value: { _error: 'Output could not be serialized' } as T,\n wasModified: true,\n warnings,\n };\n }\n\n return {\n value: result as T,\n wasModified: warnings.length > 0,\n warnings,\n };\n}\n\n/**\n * Recursively sanitize a value.\n */\nfunction sanitizeValue(\n value: unknown,\n config: OutputSanitizerConfig,\n warnings: string[],\n seen: WeakSet<object>,\n depth: number,\n): unknown {\n // Check depth\n if (depth > config.maxDepth) {\n warnings.push(`Max depth of ${config.maxDepth} exceeded`);\n return '[max depth exceeded]';\n }\n\n // Handle null/undefined\n if (value === null || value === undefined) {\n return value;\n }\n\n // Handle primitives\n if (typeof value === 'string') {\n return sanitizeString(value, config, warnings);\n }\n\n if (typeof value === 'number' || typeof value === 'boolean') {\n return value;\n }\n\n if (typeof value === 'bigint') {\n return value.toString();\n }\n\n if (typeof value === 'symbol') {\n return value.toString();\n }\n\n if (typeof value === 'function') {\n warnings.push('Function removed from output');\n return '[function]';\n }\n\n // Handle objects\n if (typeof value === 'object') {\n // Check for circular references\n if (seen.has(value)) {\n warnings.push('Circular reference detected');\n return '[circular]';\n }\n seen.add(value);\n\n // Handle arrays\n if (Array.isArray(value)) {\n return sanitizeArray(value, config, warnings, seen, depth);\n }\n\n // Handle Error objects\n if (value instanceof Error) {\n return sanitizeError(value, config, warnings);\n }\n\n // Handle Date objects\n if (value instanceof Date) {\n return value.toISOString();\n }\n\n // Handle RegExp objects\n if (value instanceof RegExp) {\n return value.toString();\n }\n\n // Handle Map\n if (value instanceof Map) {\n const obj: Record<string, unknown> = {};\n let count = 0;\n for (const [k, v] of value) {\n if (count >= config.maxObjectKeys) {\n warnings.push(`Map truncated: exceeded ${config.maxObjectKeys} keys`);\n break;\n }\n obj[String(k)] = sanitizeValue(v, config, warnings, seen, depth + 1);\n count++;\n }\n return obj;\n }\n\n // Handle Set\n if (value instanceof Set) {\n const arr: unknown[] = [];\n let count = 0;\n for (const item of value) {\n if (count >= config.maxArrayLength) {\n warnings.push(`Set truncated: exceeded ${config.maxArrayLength} items`);\n break;\n }\n arr.push(sanitizeValue(item, config, warnings, seen, depth + 1));\n count++;\n }\n return arr;\n }\n\n // Handle plain objects\n return sanitizeObject(value as Record<string, unknown>, config, warnings, seen, depth);\n }\n\n // Unknown type - return safe string representation\n return String(value);\n}\n\n/**\n * Sanitize a string value.\n */\nfunction sanitizeString(value: string, config: OutputSanitizerConfig, warnings: string[]): string {\n let result = value;\n\n // Remove file paths if configured\n if (config.removeFilePaths) {\n const pathRegex = /(?:\\/[\\w.-]+)+|(?:[A-Za-z]:\\\\[\\w\\\\.-]+)+/g;\n if (pathRegex.test(result)) {\n result = result.replace(pathRegex, '[path]');\n warnings.push('File paths removed from string');\n }\n }\n\n // Truncate if too long\n if (result.length > config.maxStringLength) {\n result = result.substring(0, config.maxStringLength) + '...[truncated]';\n warnings.push(`String truncated: exceeded ${config.maxStringLength} characters`);\n }\n\n return result;\n}\n\n/**\n * Sanitize an array.\n */\nfunction sanitizeArray(\n value: unknown[],\n config: OutputSanitizerConfig,\n warnings: string[],\n seen: WeakSet<object>,\n depth: number,\n): unknown[] {\n const result: unknown[] = [];\n const limit = Math.min(value.length, config.maxArrayLength);\n\n for (let i = 0; i < limit; i++) {\n result.push(sanitizeValue(value[i], config, warnings, seen, depth + 1));\n }\n\n if (value.length > config.maxArrayLength) {\n warnings.push(`Array truncated: ${value.length} items reduced to ${config.maxArrayLength}`);\n }\n\n return result;\n}\n\n/**\n * Sanitize a plain object.\n */\nfunction sanitizeObject(\n value: Record<string, unknown>,\n config: OutputSanitizerConfig,\n warnings: string[],\n seen: WeakSet<object>,\n depth: number,\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n const keys = Object.keys(value);\n const limit = Math.min(keys.length, config.maxObjectKeys);\n\n for (let i = 0; i < limit; i++) {\n const key = keys[i];\n\n // Skip prototype pollution vectors\n if (key === '__proto__' || key === 'constructor' || key === 'prototype') {\n warnings.push(`Dangerous key \"${key}\" removed`);\n continue;\n }\n\n result[key] = sanitizeValue(value[key], config, warnings, seen, depth + 1);\n }\n\n if (keys.length > config.maxObjectKeys) {\n warnings.push(`Object truncated: ${keys.length} keys reduced to ${config.maxObjectKeys}`);\n }\n\n return result;\n}\n\n/**\n * Sanitize an Error object.\n */\nfunction sanitizeError(error: Error, config: OutputSanitizerConfig, warnings: string[]): Record<string, unknown> {\n const result: Record<string, unknown> = {\n name: error.name,\n message: sanitizeString(error.message, config, warnings),\n };\n\n // Include stack only if configured\n if (!config.removeStackTraces && error.stack) {\n result['stack'] = sanitizeString(error.stack, config, warnings);\n } else if (error.stack) {\n warnings.push('Stack trace removed');\n }\n\n // Include error code if present\n if ('code' in error) {\n result['code'] = (error as any).code;\n }\n\n return result;\n}\n\n/**\n * Quick check if a value needs sanitization.\n * Used for optimization - skip sanitization for simple values.\n */\nexport function needsSanitization(value: unknown): boolean {\n if (value === null || value === undefined) {\n return false;\n }\n\n if (typeof value === 'number' || typeof value === 'boolean') {\n return false;\n }\n\n if (typeof value === 'string') {\n // Quick heuristic: check if string might contain paths\n return value.length > 100 || value.includes('/') || value.includes('\\\\');\n }\n\n // Objects and arrays always need checking\n return true;\n}\n\n/**\n * Sanitize a log message (less aggressive than output sanitization).\n */\nexport function sanitizeLogMessage(message: string, maxLength = 500): string {\n if (!message) return '';\n\n let result = message;\n\n // Remove file paths\n result = result.replace(/(?:\\/[\\w.-]+)+|(?:[A-Za-z]:\\\\[\\w\\\\.-]+)+/g, '[path]');\n\n // Remove line numbers\n result = result.replace(/:\\d+:\\d+/g, '');\n\n // Remove stack trace lines\n result = result.replace(/\\n\\s*at .*/g, '');\n\n // Truncate\n if (result.length > maxLength) {\n result = result.substring(0, maxLength) + '...';\n }\n\n return result.trim();\n}\n"]}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Configuration for the SynonymExpansionService
3
+ */
4
+ export interface SynonymExpansionConfig {
5
+ /**
6
+ * Additional synonym groups to include beyond defaults.
7
+ * Each group is an array of related terms.
8
+ */
9
+ additionalSynonyms?: ReadonlyArray<ReadonlyArray<string>>;
10
+ /**
11
+ * If true, completely replace default synonyms with additionalSynonyms.
12
+ * @default false
13
+ */
14
+ replaceDefaults?: boolean;
15
+ /**
16
+ * Maximum number of expanded terms per input term.
17
+ * Prevents query explosion.
18
+ * @default 5
19
+ */
20
+ maxExpansionsPerTerm?: number;
21
+ }
22
+ /**
23
+ * Lightweight synonym expansion service for improving TF-IDF search relevance.
24
+ * Zero dependencies, synchronous, and easily extensible.
25
+ *
26
+ * This service provides query-time synonym expansion to help TF-IDF-based
27
+ * search understand that semantically similar terms (like "add" and "create")
28
+ * should match the same tools.
29
+ */
30
+ export declare class SynonymExpansionService {
31
+ private synonymMap;
32
+ private maxExpansions;
33
+ constructor(config?: SynonymExpansionConfig);
34
+ /**
35
+ * Build a bidirectional synonym map from groups.
36
+ * Each term maps to all other terms in its group(s).
37
+ */
38
+ private buildSynonymMap;
39
+ /**
40
+ * Get synonyms for a single term.
41
+ * Returns empty array if no synonyms found.
42
+ *
43
+ * @example
44
+ * getSynonyms('add') // ['create', 'new', 'insert', 'make']
45
+ */
46
+ getSynonyms(term: string): string[];
47
+ /**
48
+ * Expand a query string by adding synonyms for each term.
49
+ * Returns the expanded query string with original terms and their synonyms.
50
+ *
51
+ * @example
52
+ * expandQuery('add user') // 'add create new insert make user account member profile'
53
+ */
54
+ expandQuery(query: string): string;
55
+ /**
56
+ * Check if synonym expansion is available for any term in the query.
57
+ */
58
+ hasExpansions(query: string): boolean;
59
+ /**
60
+ * Get statistics about the synonym dictionary.
61
+ */
62
+ getStats(): {
63
+ termCount: number;
64
+ avgSynonymsPerTerm: number;
65
+ };
66
+ }