@houtini/lm 1.0.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 (260) hide show
  1. package/CHANGELOG.md +273 -0
  2. package/LICENSE +21 -0
  3. package/README.md +203 -0
  4. package/dist/cache/analysis-cache.d.ts +33 -0
  5. package/dist/cache/analysis-cache.d.ts.map +1 -0
  6. package/dist/cache/analysis-cache.js +56 -0
  7. package/dist/cache/analysis-cache.js.map +1 -0
  8. package/dist/cache/cache-manager.d.ts +29 -0
  9. package/dist/cache/cache-manager.d.ts.map +1 -0
  10. package/dist/cache/cache-manager.js +85 -0
  11. package/dist/cache/cache-manager.js.map +1 -0
  12. package/dist/cache/index.d.ts +16 -0
  13. package/dist/cache/index.d.ts.map +1 -0
  14. package/dist/cache/index.js +17 -0
  15. package/dist/cache/index.js.map +1 -0
  16. package/dist/cache/prompt-cache.d.ts +33 -0
  17. package/dist/cache/prompt-cache.d.ts.map +1 -0
  18. package/dist/cache/prompt-cache.js +61 -0
  19. package/dist/cache/prompt-cache.js.map +1 -0
  20. package/dist/config.d.ts +43 -0
  21. package/dist/config.d.ts.map +1 -0
  22. package/dist/config.js +70 -0
  23. package/dist/config.js.map +1 -0
  24. package/dist/core/ThreeStagePromptManager.d.ts +39 -0
  25. package/dist/core/ThreeStagePromptManager.d.ts.map +1 -0
  26. package/dist/core/ThreeStagePromptManager.js +176 -0
  27. package/dist/core/ThreeStagePromptManager.js.map +1 -0
  28. package/dist/index.d.ts +6 -0
  29. package/dist/index.d.ts.map +1 -0
  30. package/dist/index.js +230 -0
  31. package/dist/index.js.map +1 -0
  32. package/dist/plugins/base-plugin.d.ts +47 -0
  33. package/dist/plugins/base-plugin.d.ts.map +1 -0
  34. package/dist/plugins/base-plugin.js +90 -0
  35. package/dist/plugins/base-plugin.js.map +1 -0
  36. package/dist/plugins/index.d.ts +58 -0
  37. package/dist/plugins/index.d.ts.map +1 -0
  38. package/dist/plugins/index.js +161 -0
  39. package/dist/plugins/index.js.map +1 -0
  40. package/dist/plugins/types.d.ts +5 -0
  41. package/dist/plugins/types.d.ts.map +1 -0
  42. package/dist/plugins/types.js +5 -0
  43. package/dist/plugins/types.js.map +1 -0
  44. package/dist/prompts/analyze/code-quality.d.ts +116 -0
  45. package/dist/prompts/analyze/code-quality.d.ts.map +1 -0
  46. package/dist/prompts/analyze/code-quality.js +433 -0
  47. package/dist/prompts/analyze/code-quality.js.map +1 -0
  48. package/dist/prompts/analyze/compare-integration.d.ts +130 -0
  49. package/dist/prompts/analyze/compare-integration.d.ts.map +1 -0
  50. package/dist/prompts/analyze/compare-integration.js +543 -0
  51. package/dist/prompts/analyze/compare-integration.js.map +1 -0
  52. package/dist/prompts/analyze/count-files.d.ts +109 -0
  53. package/dist/prompts/analyze/count-files.d.ts.map +1 -0
  54. package/dist/prompts/analyze/count-files.js +399 -0
  55. package/dist/prompts/analyze/count-files.js.map +1 -0
  56. package/dist/prompts/analyze/database-queries.d.ts +156 -0
  57. package/dist/prompts/analyze/database-queries.d.ts.map +1 -0
  58. package/dist/prompts/analyze/database-queries.js +759 -0
  59. package/dist/prompts/analyze/database-queries.js.map +1 -0
  60. package/dist/prompts/analyze/dependencies.d.ts +97 -0
  61. package/dist/prompts/analyze/dependencies.d.ts.map +1 -0
  62. package/dist/prompts/analyze/dependencies.js +333 -0
  63. package/dist/prompts/analyze/dependencies.js.map +1 -0
  64. package/dist/prompts/analyze/diff-signatures.d.ts +139 -0
  65. package/dist/prompts/analyze/diff-signatures.d.ts.map +1 -0
  66. package/dist/prompts/analyze/diff-signatures.js +702 -0
  67. package/dist/prompts/analyze/diff-signatures.js.map +1 -0
  68. package/dist/prompts/analyze/find-patterns.d.ts +128 -0
  69. package/dist/prompts/analyze/find-patterns.d.ts.map +1 -0
  70. package/dist/prompts/analyze/find-patterns.js +520 -0
  71. package/dist/prompts/analyze/find-patterns.js.map +1 -0
  72. package/dist/prompts/analyze/find-unused-css.d.ts +151 -0
  73. package/dist/prompts/analyze/find-unused-css.d.ts.map +1 -0
  74. package/dist/prompts/analyze/find-unused-css.js +754 -0
  75. package/dist/prompts/analyze/find-unused-css.js.map +1 -0
  76. package/dist/prompts/analyze/n8n-workflow.d.ts +137 -0
  77. package/dist/prompts/analyze/n8n-workflow.d.ts.map +1 -0
  78. package/dist/prompts/analyze/n8n-workflow.js +529 -0
  79. package/dist/prompts/analyze/n8n-workflow.js.map +1 -0
  80. package/dist/prompts/analyze/project-structure.d.ts +126 -0
  81. package/dist/prompts/analyze/project-structure.d.ts.map +1 -0
  82. package/dist/prompts/analyze/project-structure.js +569 -0
  83. package/dist/prompts/analyze/project-structure.js.map +1 -0
  84. package/dist/prompts/analyze/security-audit.d.ts +142 -0
  85. package/dist/prompts/analyze/security-audit.d.ts.map +1 -0
  86. package/dist/prompts/analyze/security-audit.js +637 -0
  87. package/dist/prompts/analyze/security-audit.js.map +1 -0
  88. package/dist/prompts/analyze/single-file.d.ts +162 -0
  89. package/dist/prompts/analyze/single-file.d.ts.map +1 -0
  90. package/dist/prompts/analyze/single-file.js +665 -0
  91. package/dist/prompts/analyze/single-file.js.map +1 -0
  92. package/dist/prompts/analyze/trace-execution.d.ts +126 -0
  93. package/dist/prompts/analyze/trace-execution.d.ts.map +1 -0
  94. package/dist/prompts/analyze/trace-execution.js +609 -0
  95. package/dist/prompts/analyze/trace-execution.js.map +1 -0
  96. package/dist/prompts/analyze/wordpress-plugin-audit.d.ts +116 -0
  97. package/dist/prompts/analyze/wordpress-plugin-audit.d.ts.map +1 -0
  98. package/dist/prompts/analyze/wordpress-plugin-audit.js +454 -0
  99. package/dist/prompts/analyze/wordpress-plugin-audit.js.map +1 -0
  100. package/dist/prompts/analyze/wordpress-security.d.ts +146 -0
  101. package/dist/prompts/analyze/wordpress-security.d.ts.map +1 -0
  102. package/dist/prompts/analyze/wordpress-security.js +698 -0
  103. package/dist/prompts/analyze/wordpress-security.js.map +1 -0
  104. package/dist/prompts/analyze/wordpress-theme-audit.d.ts +114 -0
  105. package/dist/prompts/analyze/wordpress-theme-audit.d.ts.map +1 -0
  106. package/dist/prompts/analyze/wordpress-theme-audit.js +538 -0
  107. package/dist/prompts/analyze/wordpress-theme-audit.js.map +1 -0
  108. package/dist/prompts/custom/custom-prompt.d.ts +135 -0
  109. package/dist/prompts/custom/custom-prompt.d.ts.map +1 -0
  110. package/dist/prompts/custom/custom-prompt.js +419 -0
  111. package/dist/prompts/custom/custom-prompt.js.map +1 -0
  112. package/dist/prompts/fun/arcade-game.d.ts +152 -0
  113. package/dist/prompts/fun/arcade-game.d.ts.map +1 -0
  114. package/dist/prompts/fun/arcade-game.js +653 -0
  115. package/dist/prompts/fun/arcade-game.js.map +1 -0
  116. package/dist/prompts/fun/create_text_adventure.d.ts +100 -0
  117. package/dist/prompts/fun/create_text_adventure.d.ts.map +1 -0
  118. package/dist/prompts/fun/create_text_adventure.js +397 -0
  119. package/dist/prompts/fun/create_text_adventure.js.map +1 -0
  120. package/dist/prompts/fun/css-art-generator.d.ts +168 -0
  121. package/dist/prompts/fun/css-art-generator.d.ts.map +1 -0
  122. package/dist/prompts/fun/css-art-generator.js +827 -0
  123. package/dist/prompts/fun/css-art-generator.js.map +1 -0
  124. package/dist/prompts/generate/project-documentation.d.ts +137 -0
  125. package/dist/prompts/generate/project-documentation.d.ts.map +1 -0
  126. package/dist/prompts/generate/project-documentation.js +666 -0
  127. package/dist/prompts/generate/project-documentation.js.map +1 -0
  128. package/dist/prompts/generate/refactoring.d.ts +164 -0
  129. package/dist/prompts/generate/refactoring.d.ts.map +1 -0
  130. package/dist/prompts/generate/refactoring.js +621 -0
  131. package/dist/prompts/generate/refactoring.js.map +1 -0
  132. package/dist/prompts/generate/responsive-component.d.ts +147 -0
  133. package/dist/prompts/generate/responsive-component.d.ts.map +1 -0
  134. package/dist/prompts/generate/responsive-component.js +955 -0
  135. package/dist/prompts/generate/responsive-component.js.map +1 -0
  136. package/dist/prompts/generate/typescript-conversion.d.ts +144 -0
  137. package/dist/prompts/generate/typescript-conversion.d.ts.map +1 -0
  138. package/dist/prompts/generate/typescript-conversion.js +527 -0
  139. package/dist/prompts/generate/typescript-conversion.js.map +1 -0
  140. package/dist/prompts/generate/unit-tests.d.ts +139 -0
  141. package/dist/prompts/generate/unit-tests.d.ts.map +1 -0
  142. package/dist/prompts/generate/unit-tests.js +578 -0
  143. package/dist/prompts/generate/unit-tests.js.map +1 -0
  144. package/dist/prompts/generate/wordpress-plugin.d.ts +179 -0
  145. package/dist/prompts/generate/wordpress-plugin.d.ts.map +1 -0
  146. package/dist/prompts/generate/wordpress-plugin.js +763 -0
  147. package/dist/prompts/generate/wordpress-plugin.js.map +1 -0
  148. package/dist/prompts/generate/wordpress-theme-from-static.d.ts +177 -0
  149. package/dist/prompts/generate/wordpress-theme-from-static.d.ts.map +1 -0
  150. package/dist/prompts/generate/wordpress-theme-from-static.js +695 -0
  151. package/dist/prompts/generate/wordpress-theme-from-static.js.map +1 -0
  152. package/dist/prompts/shared/cache-manager.d.ts +45 -0
  153. package/dist/prompts/shared/cache-manager.d.ts.map +1 -0
  154. package/dist/prompts/shared/cache-manager.js +129 -0
  155. package/dist/prompts/shared/cache-manager.js.map +1 -0
  156. package/dist/prompts/shared/helpers.d.ts +39 -0
  157. package/dist/prompts/shared/helpers.d.ts.map +1 -0
  158. package/dist/prompts/shared/helpers.js +151 -0
  159. package/dist/prompts/shared/helpers.js.map +1 -0
  160. package/dist/prompts/shared/templates.d.ts +35 -0
  161. package/dist/prompts/shared/templates.d.ts.map +1 -0
  162. package/dist/prompts/shared/templates.js +77 -0
  163. package/dist/prompts/shared/templates.js.map +1 -0
  164. package/dist/prompts/shared/types.d.ts +112 -0
  165. package/dist/prompts/shared/types.d.ts.map +1 -0
  166. package/dist/prompts/shared/types.js +5 -0
  167. package/dist/prompts/shared/types.js.map +1 -0
  168. package/dist/prompts/system/find-unused-files.d.ts +106 -0
  169. package/dist/prompts/system/find-unused-files.d.ts.map +1 -0
  170. package/dist/prompts/system/find-unused-files.js +353 -0
  171. package/dist/prompts/system/find-unused-files.js.map +1 -0
  172. package/dist/security/index.d.ts +39 -0
  173. package/dist/security/index.d.ts.map +1 -0
  174. package/dist/security/index.js +46 -0
  175. package/dist/security/index.js.map +1 -0
  176. package/dist/security/integration-helpers.d.ts +121 -0
  177. package/dist/security/integration-helpers.d.ts.map +1 -0
  178. package/dist/security/integration-helpers.js +190 -0
  179. package/dist/security/integration-helpers.js.map +1 -0
  180. package/dist/security/output-encoder.d.ts +94 -0
  181. package/dist/security/output-encoder.d.ts.map +1 -0
  182. package/dist/security/output-encoder.js +295 -0
  183. package/dist/security/output-encoder.js.map +1 -0
  184. package/dist/security/prompt-injection-guard.d.ts +59 -0
  185. package/dist/security/prompt-injection-guard.d.ts.map +1 -0
  186. package/dist/security/prompt-injection-guard.js +249 -0
  187. package/dist/security/prompt-injection-guard.js.map +1 -0
  188. package/dist/security/sanitisation.d.ts +67 -0
  189. package/dist/security/sanitisation.d.ts.map +1 -0
  190. package/dist/security/sanitisation.js +398 -0
  191. package/dist/security/sanitisation.js.map +1 -0
  192. package/dist/security/security-service.d.ts +103 -0
  193. package/dist/security/security-service.d.ts.map +1 -0
  194. package/dist/security/security-service.js +303 -0
  195. package/dist/security/security-service.js.map +1 -0
  196. package/dist/security-config.d.ts +45 -0
  197. package/dist/security-config.d.ts.map +1 -0
  198. package/dist/security-config.js +63 -0
  199. package/dist/security-config.js.map +1 -0
  200. package/dist/system/function-list.d.ts +61 -0
  201. package/dist/system/function-list.d.ts.map +1 -0
  202. package/dist/system/function-list.js +111 -0
  203. package/dist/system/function-list.js.map +1 -0
  204. package/dist/system/function-registry.d.ts +23 -0
  205. package/dist/system/function-registry.d.ts.map +1 -0
  206. package/dist/system/function-registry.js +136 -0
  207. package/dist/system/function-registry.js.map +1 -0
  208. package/dist/system/health-check.d.ts +33 -0
  209. package/dist/system/health-check.d.ts.map +1 -0
  210. package/dist/system/health-check.js +98 -0
  211. package/dist/system/health-check.js.map +1 -0
  212. package/dist/system/path-resolver.d.ts +55 -0
  213. package/dist/system/path-resolver.d.ts.map +1 -0
  214. package/dist/system/path-resolver.js +90 -0
  215. package/dist/system/path-resolver.js.map +1 -0
  216. package/dist/templates/plugin-template.d.ts +121 -0
  217. package/dist/templates/plugin-template.d.ts.map +1 -0
  218. package/dist/templates/plugin-template.js +450 -0
  219. package/dist/templates/plugin-template.js.map +1 -0
  220. package/dist/types/chunking-types.d.ts +88 -0
  221. package/dist/types/chunking-types.d.ts.map +1 -0
  222. package/dist/types/chunking-types.js +18 -0
  223. package/dist/types/chunking-types.js.map +1 -0
  224. package/dist/types/prompt-stages.d.ts +42 -0
  225. package/dist/types/prompt-stages.d.ts.map +1 -0
  226. package/dist/types/prompt-stages.js +6 -0
  227. package/dist/types/prompt-stages.js.map +1 -0
  228. package/dist/types.d.ts +46 -0
  229. package/dist/types.d.ts.map +1 -0
  230. package/dist/types.js +6 -0
  231. package/dist/types.js.map +1 -0
  232. package/dist/utils/css-parser.d.ts +26 -0
  233. package/dist/utils/css-parser.d.ts.map +1 -0
  234. package/dist/utils/css-parser.js +117 -0
  235. package/dist/utils/css-parser.js.map +1 -0
  236. package/dist/utils/path-resolver.d.ts +13 -0
  237. package/dist/utils/path-resolver.d.ts.map +1 -0
  238. package/dist/utils/path-resolver.js +78 -0
  239. package/dist/utils/path-resolver.js.map +1 -0
  240. package/dist/utils/plugin-utilities.d.ts +171 -0
  241. package/dist/utils/plugin-utilities.d.ts.map +1 -0
  242. package/dist/utils/plugin-utilities.js +221 -0
  243. package/dist/utils/plugin-utilities.js.map +1 -0
  244. package/dist/utils/streamHandler.d.ts +3 -0
  245. package/dist/utils/streamHandler.d.ts.map +1 -0
  246. package/dist/utils/streamHandler.js +137 -0
  247. package/dist/utils/streamHandler.js.map +1 -0
  248. package/dist/validation/output-validator.d.ts +136 -0
  249. package/dist/validation/output-validator.d.ts.map +1 -0
  250. package/dist/validation/output-validator.js +262 -0
  251. package/dist/validation/output-validator.js.map +1 -0
  252. package/dist/validation/response-factory.d.ts +44 -0
  253. package/dist/validation/response-factory.d.ts.map +1 -0
  254. package/dist/validation/response-factory.js +202 -0
  255. package/dist/validation/response-factory.js.map +1 -0
  256. package/dist/validation/schemas.d.ts +519 -0
  257. package/dist/validation/schemas.d.ts.map +1 -0
  258. package/dist/validation/schemas.js +6 -0
  259. package/dist/validation/schemas.js.map +1 -0
  260. package/package.json +72 -0
@@ -0,0 +1,303 @@
1
+ /**
2
+ * Security Service Wrapper
3
+ *
4
+ * Provides a unified interface for all security operations.
5
+ * Acts as a facade over individual security modules.
6
+ *
7
+ * Usage:
8
+ * const security = new SecurityService();
9
+ * const result = await security.executeSecurely(plugin, params, llmClient);
10
+ */
11
+ import { SanitisationHelper } from './sanitisation.js';
12
+ import { PromptInjectionGuard } from './prompt-injection-guard.js';
13
+ import { OutputEncoder } from './output-encoder.js';
14
+ export class SecurityService {
15
+ constructor(config) {
16
+ this.config = {
17
+ enableSanitisation: true,
18
+ enableInjectionDetection: true,
19
+ enableOutputEncoding: true,
20
+ injectionThreshold: 0.5,
21
+ logSecurityEvents: true,
22
+ ...config
23
+ };
24
+ this.startTime = Date.now();
25
+ }
26
+ /**
27
+ * Main wrapper method - executes a plugin with full security protection
28
+ */
29
+ async executeSecurely(plugin, params, llmClient) {
30
+ const startTime = Date.now();
31
+ const warnings = [];
32
+ try {
33
+ // Step 1: Sanitise and validate input parameters
34
+ const secureParams = await this.secureParameters(params, plugin.name);
35
+ // Check if any parameters were blocked
36
+ if (secureParams.blocked) {
37
+ throw new Error(`Security violation: ${secureParams.warnings.join(', ')}`);
38
+ }
39
+ warnings.push(...secureParams.warnings);
40
+ // Step 2: Execute the plugin with secured parameters
41
+ const result = await plugin.execute(secureParams.sanitised, llmClient);
42
+ // Step 3: Secure the output
43
+ const secureResult = await this.secureOutput(result, plugin.category);
44
+ // Step 4: Add security metadata
45
+ const processingTime = Date.now() - startTime;
46
+ if (warnings.length > 0 && this.config.logSecurityEvents) {
47
+ console.warn(`Security warnings for ${plugin.name}:`, warnings);
48
+ }
49
+ return {
50
+ ...secureResult,
51
+ __security: {
52
+ safe: true,
53
+ warnings,
54
+ processingTime,
55
+ timestamp: new Date().toISOString()
56
+ }
57
+ };
58
+ }
59
+ catch (error) {
60
+ // Sanitise error messages
61
+ const sanitisedError = this.sanitiseError(error, plugin.name);
62
+ throw sanitisedError;
63
+ }
64
+ }
65
+ /**
66
+ * Secure input parameters
67
+ */
68
+ async secureParameters(params, pluginName) {
69
+ const startTime = Date.now();
70
+ const warnings = [];
71
+ let blocked = false;
72
+ let riskLevel = 'low';
73
+ if (!this.config.enableSanitisation && !this.config.enableInjectionDetection) {
74
+ return {
75
+ safe: true,
76
+ blocked: false,
77
+ sanitised: params,
78
+ warnings: [],
79
+ riskLevel: 'low',
80
+ processingTime: Date.now() - startTime
81
+ };
82
+ }
83
+ const sanitised = {};
84
+ for (const [key, value] of Object.entries(params)) {
85
+ if (typeof value === 'string') {
86
+ // Determine context for this parameter
87
+ const context = this.getParameterContext(key);
88
+ // Step 1: Check for injection if enabled
89
+ if (this.config.enableInjectionDetection) {
90
+ const injectionResult = PromptInjectionGuard.analyseInjection(value, { source: 'parameter', pluginName });
91
+ if (injectionResult.detected) {
92
+ if (injectionResult.confidence >= (this.config.injectionThreshold || 0.5)) {
93
+ if (injectionResult.riskLevel === 'critical') {
94
+ blocked = true;
95
+ warnings.push(`Critical injection attempt in parameter '${key}': ${injectionResult.mitigation}`);
96
+ riskLevel = 'critical';
97
+ continue;
98
+ }
99
+ else {
100
+ warnings.push(`Injection detected in parameter '${key}': ${injectionResult.mitigation}`);
101
+ riskLevel = this.getHigherRiskLevel(riskLevel, injectionResult.riskLevel);
102
+ }
103
+ }
104
+ }
105
+ }
106
+ // Step 2: Sanitise the parameter if enabled
107
+ if (this.config.enableSanitisation) {
108
+ const sanitisationResult = SanitisationHelper.sanitiseInput(value, context);
109
+ if (sanitisationResult.blocked) {
110
+ blocked = true;
111
+ warnings.push(`Parameter '${key}' blocked: ${sanitisationResult.reason}`);
112
+ continue;
113
+ }
114
+ sanitised[key] = sanitisationResult.cleaned;
115
+ warnings.push(...sanitisationResult.warnings.map(w => `${key}: ${w}`));
116
+ }
117
+ else {
118
+ sanitised[key] = value;
119
+ }
120
+ }
121
+ else {
122
+ // Non-string values pass through (could add object sanitisation here)
123
+ sanitised[key] = value;
124
+ }
125
+ }
126
+ const processingTime = Date.now() - startTime;
127
+ return {
128
+ safe: !blocked && riskLevel !== 'critical',
129
+ blocked,
130
+ sanitised,
131
+ warnings,
132
+ riskLevel,
133
+ processingTime
134
+ };
135
+ }
136
+ /**
137
+ * Secure output data
138
+ */
139
+ async secureOutput(output, pluginCategory) {
140
+ if (!this.config.enableOutputEncoding) {
141
+ return output;
142
+ }
143
+ const outputContext = this.getOutputContext(pluginCategory);
144
+ try {
145
+ const safeResponse = OutputEncoder.createSafeResponse(output, outputContext);
146
+ if (safeResponse.metadata.warnings.length > 0 && this.config.logSecurityEvents) {
147
+ console.warn('Output encoding warnings:', safeResponse.metadata.warnings);
148
+ }
149
+ return safeResponse.data;
150
+ }
151
+ catch (error) {
152
+ console.error('Error securing output:', error);
153
+ return output; // Fallback to original output if encoding fails
154
+ }
155
+ }
156
+ /**
157
+ * Sanitise error messages to prevent information disclosure
158
+ */
159
+ sanitiseError(error, pluginName) {
160
+ if (!this.config.enableSanitisation) {
161
+ return error;
162
+ }
163
+ let message = error.message || 'An error occurred';
164
+ // Remove sensitive information from error messages
165
+ message = message
166
+ .replace(/\/[a-zA-Z]:[\\\/][^\\\/\s]*[\\\/][^\\\/\s]*/g, '[PATH_REMOVED]') // Windows/Unix paths
167
+ .replace(/Error: ENOENT: no such file or directory, open '([^']*)'/, 'Error: File not found')
168
+ .replace(/at Object\.readFileSync[^)]*\)/g, 'at file read operation')
169
+ .replace(/\b(?:\d{1,3}\.){3}\d{1,3}\b/g, '[IP_REMOVED]') // IP addresses
170
+ .replace(/\bfile:\/\/[^\s]*/g, '[FILE_URL_REMOVED]') // File URLs
171
+ .replace(/API[_\s]?KEY[_\s]?[=:]\s*[^\s]+/gi, 'API_KEY=[REDACTED]'); // API keys
172
+ const sanitisedError = new Error(message);
173
+ sanitisedError.name = error.name || 'SecurityError';
174
+ if (this.config.logSecurityEvents) {
175
+ console.warn(`Sanitised error for ${pluginName}: ${error.message} → ${message}`);
176
+ }
177
+ return sanitisedError;
178
+ }
179
+ /**
180
+ * Quick security check for individual values
181
+ */
182
+ async quickCheck(value, context = 'parameter') {
183
+ const startTime = Date.now();
184
+ // Injection detection
185
+ const injectionResult = PromptInjectionGuard.analyseInjection(value, { source: context });
186
+ // Input sanitisation
187
+ const sanitisationResult = SanitisationHelper.sanitiseInput(value, 'general');
188
+ const blocked = sanitisationResult.blocked ||
189
+ (injectionResult.detected && injectionResult.riskLevel === 'critical');
190
+ return {
191
+ safe: !injectionResult.detected && !sanitisationResult.blocked,
192
+ blocked,
193
+ sanitised: sanitisationResult.cleaned,
194
+ warnings: [
195
+ ...sanitisationResult.warnings,
196
+ ...(injectionResult.detected ? [injectionResult.mitigation] : [])
197
+ ],
198
+ riskLevel: injectionResult.detected ? injectionResult.riskLevel : 'low',
199
+ processingTime: Date.now() - startTime
200
+ };
201
+ }
202
+ /**
203
+ * Validate and sanitise file paths
204
+ */
205
+ async validateFilePath(filePath) {
206
+ const startTime = Date.now();
207
+ const result = SanitisationHelper.sanitiseFilePath(filePath);
208
+ return {
209
+ safe: !result.blocked,
210
+ blocked: result.blocked,
211
+ sanitised: result.cleaned,
212
+ warnings: result.warnings,
213
+ riskLevel: result.blocked ? 'high' : 'low',
214
+ processingTime: Date.now() - startTime
215
+ };
216
+ }
217
+ /**
218
+ * Encode output for specific contexts
219
+ */
220
+ encodeOutput(content, context) {
221
+ return OutputEncoder.encode(content, { context });
222
+ }
223
+ /**
224
+ * Run comprehensive security tests
225
+ */
226
+ runDiagnostics() {
227
+ try {
228
+ const sanitisation = SanitisationHelper.validateSanitisation();
229
+ const injection = PromptInjectionGuard.runSecurityTests();
230
+ const encoding = OutputEncoder.validateEncoding();
231
+ return {
232
+ sanitisation,
233
+ injection,
234
+ encoding,
235
+ serviceHealth: true
236
+ };
237
+ }
238
+ catch (error) {
239
+ console.error('Security diagnostics failed:', error);
240
+ return {
241
+ sanitisation: false,
242
+ injection: { passed: 0, failed: 1 },
243
+ encoding: { passed: false, errors: ['Diagnostics failed'] },
244
+ serviceHealth: false
245
+ };
246
+ }
247
+ }
248
+ /**
249
+ * Get parameter context for security checks
250
+ */
251
+ getParameterContext(paramKey) {
252
+ const key = paramKey.toLowerCase();
253
+ if (key.includes('path') || key.includes('file') || key.includes('dir')) {
254
+ return 'file-path';
255
+ }
256
+ if (key === 'code' || key === 'content' || key.includes('source')) {
257
+ return 'code';
258
+ }
259
+ if (key === 'prompt' || key === 'instructions' || key.includes('instruction')) {
260
+ return 'prompt';
261
+ }
262
+ return 'general';
263
+ }
264
+ /**
265
+ * Get output context based on plugin category
266
+ */
267
+ getOutputContext(pluginCategory) {
268
+ switch (pluginCategory) {
269
+ case 'generate':
270
+ return 'code';
271
+ case 'custom':
272
+ return 'code'; // Custom prompts often generate code/HTML/CSS
273
+ case 'analyze':
274
+ case 'multifile':
275
+ case 'system':
276
+ return 'json';
277
+ default:
278
+ return 'json';
279
+ }
280
+ }
281
+ /**
282
+ * Compare risk levels and return the higher one
283
+ */
284
+ getHigherRiskLevel(current, new_) {
285
+ const levels = { low: 0, medium: 1, high: 2, critical: 3 };
286
+ return levels[new_] > levels[current] ? new_ : current;
287
+ }
288
+ /**
289
+ * Update security configuration
290
+ */
291
+ updateConfig(newConfig) {
292
+ this.config = { ...this.config, ...newConfig };
293
+ }
294
+ /**
295
+ * Get current security configuration
296
+ */
297
+ getConfig() {
298
+ return { ...this.config };
299
+ }
300
+ }
301
+ // Singleton instance for global use
302
+ export const securityService = new SecurityService();
303
+ //# sourceMappingURL=security-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security-service.js","sourceRoot":"","sources":["../../src/security/security-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Security configuration for Houtini LM MCP
3
+ *
4
+ * These settings control file access permissions and security policies.
5
+ * Can be overridden via environment variables.
6
+ */
7
+ export declare const securityConfig: {
8
+ /**
9
+ * Get the list of allowed directories from environment variable
10
+ * NO DEFAULTS - Must be explicitly configured for security
11
+ *
12
+ * @returns {string[]} Array of normalized, absolute paths
13
+ * @throws {Error} If LLM_MCP_ALLOWED_DIRS is not set
14
+ */
15
+ getAllowedDirectories(): string[];
16
+ /**
17
+ * Additional security settings
18
+ */
19
+ security: {
20
+ /** Maximum file size in bytes (200MB default) */
21
+ maxFileSize: number;
22
+ /** Enforce absolute paths */
23
+ requireAbsolutePaths: boolean;
24
+ /** Log security violations */
25
+ logSecurityViolations: boolean;
26
+ /** Allowed file extensions */
27
+ allowedExtensions: string[];
28
+ };
29
+ /**
30
+ * Authentication settings (for future implementation)
31
+ */
32
+ auth: {
33
+ /** Enable API key authentication */
34
+ enableApiKey: boolean;
35
+ /** API key header name */
36
+ apiKeyHeader: string;
37
+ /** Enable rate limiting */
38
+ enableRateLimit: boolean;
39
+ /** Rate limit window in milliseconds */
40
+ rateLimitWindow: number;
41
+ /** Maximum requests per window */
42
+ rateLimitMax: number;
43
+ };
44
+ };
45
+ //# sourceMappingURL=security-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security-config.d.ts","sourceRoot":"","sources":["../src/security-config.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,eAAO,MAAM,cAAc;IACzB;;;;;;OAMG;6BACsB,MAAM,EAAE;IAajC;;OAEG;;QAED,iDAAiD;;QAGjD,6BAA6B;;QAG7B,8BAA8B;;QAG9B,8BAA8B;;;IAUhC;;OAEG;;QAED,oCAAoC;;QAGpC,0BAA0B;;QAG1B,2BAA2B;;QAG3B,wCAAwC;;QAGxC,kCAAkC;;;CAGrC,CAAC"}
@@ -0,0 +1,63 @@
1
+ import { resolve, normalize } from 'path';
2
+ /**
3
+ * Security configuration for Houtini LM MCP
4
+ *
5
+ * These settings control file access permissions and security policies.
6
+ * Can be overridden via environment variables.
7
+ */
8
+ export const securityConfig = {
9
+ /**
10
+ * Get the list of allowed directories from environment variable
11
+ * NO DEFAULTS - Must be explicitly configured for security
12
+ *
13
+ * @returns {string[]} Array of normalized, absolute paths
14
+ * @throws {Error} If LLM_MCP_ALLOWED_DIRS is not set
15
+ */
16
+ getAllowedDirectories() {
17
+ if (!process.env.LLM_MCP_ALLOWED_DIRS) {
18
+ // TEMPORARY FIX: Use fallback directories for development
19
+ console.error('WARNING: LLM_MCP_ALLOWED_DIRS not set, using fallback directories');
20
+ const fallbackDirs = ['C:\\MCP', 'C:\\DEV'];
21
+ return fallbackDirs.map(dir => resolve(normalize(dir.trim())).toLowerCase());
22
+ }
23
+ return process.env.LLM_MCP_ALLOWED_DIRS
24
+ .split(',')
25
+ .map(dir => resolve(normalize(dir.trim())).toLowerCase());
26
+ },
27
+ /**
28
+ * Additional security settings
29
+ */
30
+ security: {
31
+ /** Maximum file size in bytes (200MB default) */
32
+ maxFileSize: 200 * 1024 * 1024,
33
+ /** Enforce absolute paths */
34
+ requireAbsolutePaths: true,
35
+ /** Log security violations */
36
+ logSecurityViolations: true,
37
+ /** Allowed file extensions */
38
+ allowedExtensions: [
39
+ '.csv', '.json', '.txt', '.js', '.ts', '.py',
40
+ '.md', '.log', '.jsx', '.tsx', '.java', '.c',
41
+ '.cpp', '.rs', '.go', '.php', '.rb', '.swift',
42
+ '.html', '.css', '.scss', '.sass', '.less',
43
+ '.xml', '.yml', '.yaml', '.toml', '.ini'
44
+ ]
45
+ },
46
+ /**
47
+ * Authentication settings (for future implementation)
48
+ */
49
+ auth: {
50
+ /** Enable API key authentication */
51
+ enableApiKey: false,
52
+ /** API key header name */
53
+ apiKeyHeader: 'X-API-Key',
54
+ /** Enable rate limiting */
55
+ enableRateLimit: false,
56
+ /** Rate limit window in milliseconds */
57
+ rateLimitWindow: 15 * 60 * 1000, // 15 minutes
58
+ /** Maximum requests per window */
59
+ rateLimitMax: 100
60
+ }
61
+ };
62
+ // No backwards compatibility exports - security must be explicitly configured
63
+ //# sourceMappingURL=security-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security-config.js","sourceRoot":"","sources":["../src/security-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AAE1C;;;;;GAKG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B;;;;;;OAMG;IACH,qBAAqB;QACnB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,EAAE,CAAC;YACtC,0DAA0D;YAC1D,OAAO,CAAC,KAAK,CAAC,mEAAmE,CAAC,CAAC;YACnF,MAAM,YAAY,GAAG,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;YAC5C,OAAO,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;QAC/E,CAAC;QAED,OAAO,OAAO,CAAC,GAAG,CAAC,oBAAoB;aACpC,KAAK,CAAC,GAAG,CAAC;aACV,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;IAC9D,CAAC;IAED;;OAEG;IACH,QAAQ,EAAE;QACR,iDAAiD;QACjD,WAAW,EAAE,GAAG,GAAG,IAAI,GAAG,IAAI;QAE9B,6BAA6B;QAC7B,oBAAoB,EAAE,IAAI;QAE1B,8BAA8B;QAC9B,qBAAqB,EAAE,IAAI;QAE3B,8BAA8B;QAC9B,iBAAiB,EAAE;YACjB,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK;YAC5C,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI;YAC5C,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ;YAC7C,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO;YAC1C,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM;SACzC;KACF;IAED;;OAEG;IACH,IAAI,EAAE;QACJ,oCAAoC;QACpC,YAAY,EAAE,KAAK;QAEnB,0BAA0B;QAC1B,YAAY,EAAE,WAAW;QAEzB,2BAA2B;QAC3B,eAAe,EAAE,KAAK;QAEtB,wCAAwC;QACxC,eAAe,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,aAAa;QAE9C,kCAAkC;QAClC,YAAY,EAAE,GAAG;KAClB;CACF,CAAC;AAEF,8EAA8E"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Function Registry Plugin - Discover and list all available Houtini LM functions
3
+ * Helps users explore capabilities and understand function usage patterns
4
+ */
5
+ import { BasePlugin } from '../plugins/base-plugin.js';
6
+ import { IPromptPlugin } from '../prompts/shared/types.js';
7
+ export declare class FunctionRegistryPlugin extends BasePlugin implements IPromptPlugin {
8
+ name: string;
9
+ category: "system";
10
+ description: string;
11
+ parameters: {
12
+ category: {
13
+ type: "string";
14
+ description: string;
15
+ required: boolean;
16
+ };
17
+ detailed: {
18
+ type: "boolean";
19
+ description: string;
20
+ default: boolean;
21
+ required: boolean;
22
+ };
23
+ includeExamples: {
24
+ type: "boolean";
25
+ description: string;
26
+ default: boolean;
27
+ required: boolean;
28
+ };
29
+ };
30
+ execute(params: any, llmClient: any): Promise<{
31
+ success: boolean;
32
+ timestamp: string;
33
+ modelUsed: string;
34
+ executionTimeMs: number;
35
+ data: {
36
+ content: any;
37
+ metadata: {
38
+ functionName: string;
39
+ parsedAt: string;
40
+ responseLength: number;
41
+ };
42
+ };
43
+ error?: undefined;
44
+ } | {
45
+ success: boolean;
46
+ timestamp: string;
47
+ modelUsed: string;
48
+ executionTimeMs: number;
49
+ error: {
50
+ code: string;
51
+ message: any;
52
+ details: {
53
+ originalError: any;
54
+ };
55
+ };
56
+ data?: undefined;
57
+ }>;
58
+ getPromptStages(params: any): any;
59
+ }
60
+ export default FunctionRegistryPlugin;
61
+ //# sourceMappingURL=function-list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"function-list.d.ts","sourceRoot":"","sources":["../../src/system/function-list.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAI3D,qBAAa,sBAAuB,SAAQ,UAAW,YAAW,aAAa;IAC7E,IAAI,SAAoB;IACxB,QAAQ,EAAG,QAAQ,CAAU;IAC7B,WAAW,SAAoE;IAE/E,UAAU;;;;;;;;;;;;;;;;;;MAkBR;IAEI,OAAO,CAAC,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAwEzC,eAAe,CAAC,MAAM,EAAE,GAAG,GAAG,GAAG;CAOlC;AAGD,eAAe,sBAAsB,CAAC"}
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Function Registry Plugin - Discover and list all available Houtini LM functions
3
+ * Helps users explore capabilities and understand function usage patterns
4
+ */
5
+ import { BasePlugin } from '../plugins/base-plugin.js';
6
+ import { withSecurity } from '../security/integration-helpers.js';
7
+ import { discoverAvailableFunctions, getFunctionCategories } from './function-registry.js';
8
+ export class FunctionRegistryPlugin extends BasePlugin {
9
+ constructor() {
10
+ super(...arguments);
11
+ this.name = 'list_functions';
12
+ this.category = 'system';
13
+ this.description = 'List all available Houtini LM functions with usage information';
14
+ this.parameters = {
15
+ category: {
16
+ type: 'string',
17
+ description: 'Filter by category (analyze, generate, system, custom, fun)',
18
+ required: false
19
+ },
20
+ detailed: {
21
+ type: 'boolean',
22
+ description: 'Include detailed information about each function',
23
+ default: true,
24
+ required: false
25
+ },
26
+ includeExamples: {
27
+ type: 'boolean',
28
+ description: 'Include usage examples for each function',
29
+ default: true,
30
+ required: false
31
+ }
32
+ };
33
+ }
34
+ async execute(params, llmClient) {
35
+ return await withSecurity(this, params, llmClient, async (secureParams) => {
36
+ try {
37
+ const allFunctions = await discoverAvailableFunctions();
38
+ const categories = await getFunctionCategories();
39
+ // Filter by category if specified
40
+ const filteredFunctions = secureParams.category
41
+ ? allFunctions.filter(func => func.category === secureParams.category)
42
+ : allFunctions;
43
+ const result = {
44
+ summary: {
45
+ totalFunctions: allFunctions.length,
46
+ filteredCount: filteredFunctions.length,
47
+ categories: categories,
48
+ timestamp: new Date().toISOString()
49
+ },
50
+ functions: secureParams.detailed === false
51
+ ? filteredFunctions.map(func => ({ name: func.name, category: func.category }))
52
+ : filteredFunctions.map(func => ({
53
+ name: func.name,
54
+ category: func.category,
55
+ description: func.description,
56
+ supportedModes: func.supportedModes,
57
+ primaryMode: func.primaryMode,
58
+ examples: secureParams.includeExamples !== false ? func.exampleUsage : undefined
59
+ }))
60
+ };
61
+ // Add helpful tips for users
62
+ if (secureParams.detailed !== false) {
63
+ result.tips = {
64
+ singleFile: "Use 'filePath' parameter for individual file analysis",
65
+ multiFile: "Use 'projectPath' parameter for directory/project analysis",
66
+ pathResolution: "Use 'houtini-lm:resolve_path' to check if a path is file or directory",
67
+ modeInfo: "Functions support 'single-file', 'multi-file', or both modes"
68
+ };
69
+ }
70
+ return {
71
+ success: true,
72
+ timestamp: new Date().toISOString(),
73
+ modelUsed: 'system-utility',
74
+ executionTimeMs: 0,
75
+ data: {
76
+ content: result,
77
+ metadata: {
78
+ functionName: 'list_functions',
79
+ parsedAt: new Date().toISOString(),
80
+ responseLength: JSON.stringify(result).length
81
+ }
82
+ }
83
+ };
84
+ }
85
+ catch (error) {
86
+ return {
87
+ success: false,
88
+ timestamp: new Date().toISOString(),
89
+ modelUsed: 'system-utility',
90
+ executionTimeMs: 0,
91
+ error: {
92
+ code: 'FUNCTION_DISCOVERY_ERROR',
93
+ message: error.message || 'Failed to discover functions',
94
+ details: { originalError: error.message }
95
+ }
96
+ };
97
+ }
98
+ });
99
+ }
100
+ // Not used for system functions, but required by interface
101
+ getPromptStages(params) {
102
+ return {
103
+ systemAndContext: 'Function discovery system function',
104
+ dataPayload: `Category filter: ${params.category || 'all'}`,
105
+ outputInstructions: 'Return function registry information'
106
+ };
107
+ }
108
+ }
109
+ // Export as default for plugin loader
110
+ export default FunctionRegistryPlugin;
111
+ //# sourceMappingURL=function-list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"function-list.js","sourceRoot":"","sources":["../../src/system/function-list.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ export interface FunctionInfo {
2
+ name: string;
3
+ category: string;
4
+ file: string;
5
+ description?: string;
6
+ supportedModes: string[];
7
+ primaryMode: string;
8
+ exampleUsage?: {
9
+ singleFile?: string;
10
+ multiFile?: string;
11
+ };
12
+ }
13
+ /**
14
+ * Discover all available Houtini LM functions by scanning prompt directories
15
+ */
16
+ export declare function discoverAvailableFunctions(): Promise<FunctionInfo[]>;
17
+ /**
18
+ * Get function categories with counts
19
+ */
20
+ export declare function getFunctionCategories(): Promise<{
21
+ [category: string]: number;
22
+ }>;
23
+ //# sourceMappingURL=function-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"function-registry.d.ts","sourceRoot":"","sources":["../../src/system/function-registry.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE;QACb,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;CACH;AAED;;GAEG;AACH,wBAAsB,0BAA0B,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC,CAiC1E;AA0GD;;GAEG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC;IAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,CAAC,CASrF"}