@dotsetlabs/tollgate 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (215) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +885 -0
  3. package/dist/analyzers/filesystem.d.ts +26 -0
  4. package/dist/analyzers/filesystem.d.ts.map +1 -0
  5. package/dist/analyzers/filesystem.js +284 -0
  6. package/dist/analyzers/filesystem.js.map +1 -0
  7. package/dist/analyzers/http.d.ts +90 -0
  8. package/dist/analyzers/http.d.ts.map +1 -0
  9. package/dist/analyzers/http.js +433 -0
  10. package/dist/analyzers/http.js.map +1 -0
  11. package/dist/analyzers/index.d.ts +101 -0
  12. package/dist/analyzers/index.d.ts.map +1 -0
  13. package/dist/analyzers/index.js +342 -0
  14. package/dist/analyzers/index.js.map +1 -0
  15. package/dist/analyzers/loader.d.ts +114 -0
  16. package/dist/analyzers/loader.d.ts.map +1 -0
  17. package/dist/analyzers/loader.js +184 -0
  18. package/dist/analyzers/loader.js.map +1 -0
  19. package/dist/analyzers/prompt-injection.d.ts +95 -0
  20. package/dist/analyzers/prompt-injection.d.ts.map +1 -0
  21. package/dist/analyzers/prompt-injection.js +725 -0
  22. package/dist/analyzers/prompt-injection.js.map +1 -0
  23. package/dist/analyzers/sdk.d.ts +230 -0
  24. package/dist/analyzers/sdk.d.ts.map +1 -0
  25. package/dist/analyzers/sdk.js +283 -0
  26. package/dist/analyzers/sdk.js.map +1 -0
  27. package/dist/analyzers/shell.d.ts +20 -0
  28. package/dist/analyzers/shell.d.ts.map +1 -0
  29. package/dist/analyzers/shell.js +297 -0
  30. package/dist/analyzers/shell.js.map +1 -0
  31. package/dist/analyzers/sql.d.ts +37 -0
  32. package/dist/analyzers/sql.d.ts.map +1 -0
  33. package/dist/analyzers/sql.js +455 -0
  34. package/dist/analyzers/sql.js.map +1 -0
  35. package/dist/analyzers/types.d.ts +117 -0
  36. package/dist/analyzers/types.d.ts.map +1 -0
  37. package/dist/analyzers/types.js +46 -0
  38. package/dist/analyzers/types.js.map +1 -0
  39. package/dist/approval/interactive.d.ts +72 -0
  40. package/dist/approval/interactive.d.ts.map +1 -0
  41. package/dist/approval/interactive.js +550 -0
  42. package/dist/approval/interactive.js.map +1 -0
  43. package/dist/approval/terminal.d.ts +59 -0
  44. package/dist/approval/terminal.d.ts.map +1 -0
  45. package/dist/approval/terminal.js +238 -0
  46. package/dist/approval/terminal.js.map +1 -0
  47. package/dist/approval/types.d.ts +66 -0
  48. package/dist/approval/types.d.ts.map +1 -0
  49. package/dist/approval/types.js +2 -0
  50. package/dist/approval/types.js.map +1 -0
  51. package/dist/audit/exporter.d.ts +138 -0
  52. package/dist/audit/exporter.d.ts.map +1 -0
  53. package/dist/audit/exporter.js +366 -0
  54. package/dist/audit/exporter.js.map +1 -0
  55. package/dist/audit/logger.d.ts +156 -0
  56. package/dist/audit/logger.d.ts.map +1 -0
  57. package/dist/audit/logger.js +406 -0
  58. package/dist/audit/logger.js.map +1 -0
  59. package/dist/audit/redaction.d.ts +110 -0
  60. package/dist/audit/redaction.d.ts.map +1 -0
  61. package/dist/audit/redaction.js +307 -0
  62. package/dist/audit/redaction.js.map +1 -0
  63. package/dist/audit/schema.d.ts +76 -0
  64. package/dist/audit/schema.d.ts.map +1 -0
  65. package/dist/audit/schema.js +122 -0
  66. package/dist/audit/schema.js.map +1 -0
  67. package/dist/cli/commands/doctor.d.ts +34 -0
  68. package/dist/cli/commands/doctor.d.ts.map +1 -0
  69. package/dist/cli/commands/doctor.js +431 -0
  70. package/dist/cli/commands/doctor.js.map +1 -0
  71. package/dist/cli/commands/export.d.ts +18 -0
  72. package/dist/cli/commands/export.d.ts.map +1 -0
  73. package/dist/cli/commands/export.js +63 -0
  74. package/dist/cli/commands/export.js.map +1 -0
  75. package/dist/cli/commands/init.d.ts +12 -0
  76. package/dist/cli/commands/init.d.ts.map +1 -0
  77. package/dist/cli/commands/init.js +102 -0
  78. package/dist/cli/commands/init.js.map +1 -0
  79. package/dist/cli/commands/logs.d.ts +11 -0
  80. package/dist/cli/commands/logs.d.ts.map +1 -0
  81. package/dist/cli/commands/logs.js +60 -0
  82. package/dist/cli/commands/logs.js.map +1 -0
  83. package/dist/cli/commands/scan.d.ts +29 -0
  84. package/dist/cli/commands/scan.d.ts.map +1 -0
  85. package/dist/cli/commands/scan.js +251 -0
  86. package/dist/cli/commands/scan.js.map +1 -0
  87. package/dist/cli/commands/serve.d.ts +26 -0
  88. package/dist/cli/commands/serve.d.ts.map +1 -0
  89. package/dist/cli/commands/serve.js +424 -0
  90. package/dist/cli/commands/serve.js.map +1 -0
  91. package/dist/cli/commands/start.d.ts +20 -0
  92. package/dist/cli/commands/start.d.ts.map +1 -0
  93. package/dist/cli/commands/start.js +82 -0
  94. package/dist/cli/commands/start.js.map +1 -0
  95. package/dist/cli/commands/stats.d.ts +10 -0
  96. package/dist/cli/commands/stats.d.ts.map +1 -0
  97. package/dist/cli/commands/stats.js +42 -0
  98. package/dist/cli/commands/stats.js.map +1 -0
  99. package/dist/cli/commands/templates.d.ts +26 -0
  100. package/dist/cli/commands/templates.d.ts.map +1 -0
  101. package/dist/cli/commands/templates.js +221 -0
  102. package/dist/cli/commands/templates.js.map +1 -0
  103. package/dist/cli/commands/validate.d.ts +12 -0
  104. package/dist/cli/commands/validate.d.ts.map +1 -0
  105. package/dist/cli/commands/validate.js +107 -0
  106. package/dist/cli/commands/validate.js.map +1 -0
  107. package/dist/cli/commands/wrap.d.ts +19 -0
  108. package/dist/cli/commands/wrap.d.ts.map +1 -0
  109. package/dist/cli/commands/wrap.js +59 -0
  110. package/dist/cli/commands/wrap.js.map +1 -0
  111. package/dist/cli/index.d.ts +17 -0
  112. package/dist/cli/index.d.ts.map +1 -0
  113. package/dist/cli/index.js +202 -0
  114. package/dist/cli/index.js.map +1 -0
  115. package/dist/cli/ui.d.ts +139 -0
  116. package/dist/cli/ui.d.ts.map +1 -0
  117. package/dist/cli/ui.js +271 -0
  118. package/dist/cli/ui.js.map +1 -0
  119. package/dist/constants.d.ts +33 -0
  120. package/dist/constants.d.ts.map +1 -0
  121. package/dist/constants.js +54 -0
  122. package/dist/constants.js.map +1 -0
  123. package/dist/errors.d.ts +28 -0
  124. package/dist/errors.d.ts.map +1 -0
  125. package/dist/errors.js +37 -0
  126. package/dist/errors.js.map +1 -0
  127. package/dist/index.d.ts +49 -0
  128. package/dist/index.d.ts.map +1 -0
  129. package/dist/index.js +82 -0
  130. package/dist/index.js.map +1 -0
  131. package/dist/orchestrator/index.d.ts +11 -0
  132. package/dist/orchestrator/index.d.ts.map +1 -0
  133. package/dist/orchestrator/index.js +10 -0
  134. package/dist/orchestrator/index.js.map +1 -0
  135. package/dist/orchestrator/manager.d.ts +127 -0
  136. package/dist/orchestrator/manager.d.ts.map +1 -0
  137. package/dist/orchestrator/manager.js +498 -0
  138. package/dist/orchestrator/manager.js.map +1 -0
  139. package/dist/orchestrator/types.d.ts +141 -0
  140. package/dist/orchestrator/types.d.ts.map +1 -0
  141. package/dist/orchestrator/types.js +9 -0
  142. package/dist/orchestrator/types.js.map +1 -0
  143. package/dist/policy/engine.d.ts +55 -0
  144. package/dist/policy/engine.d.ts.map +1 -0
  145. package/dist/policy/engine.js +288 -0
  146. package/dist/policy/engine.js.map +1 -0
  147. package/dist/policy/natural-language.d.ts +141 -0
  148. package/dist/policy/natural-language.d.ts.map +1 -0
  149. package/dist/policy/natural-language.js +552 -0
  150. package/dist/policy/natural-language.js.map +1 -0
  151. package/dist/policy/parser.d.ts +141 -0
  152. package/dist/policy/parser.d.ts.map +1 -0
  153. package/dist/policy/parser.js +314 -0
  154. package/dist/policy/parser.js.map +1 -0
  155. package/dist/policy/types.d.ts +428 -0
  156. package/dist/policy/types.d.ts.map +1 -0
  157. package/dist/policy/types.js +32 -0
  158. package/dist/policy/types.js.map +1 -0
  159. package/dist/policy/validator.d.ts +72 -0
  160. package/dist/policy/validator.d.ts.map +1 -0
  161. package/dist/policy/validator.js +453 -0
  162. package/dist/policy/validator.js.map +1 -0
  163. package/dist/proxy/bridge.d.ts +84 -0
  164. package/dist/proxy/bridge.d.ts.map +1 -0
  165. package/dist/proxy/bridge.js +217 -0
  166. package/dist/proxy/bridge.js.map +1 -0
  167. package/dist/proxy/client.d.ts +130 -0
  168. package/dist/proxy/client.d.ts.map +1 -0
  169. package/dist/proxy/client.js +290 -0
  170. package/dist/proxy/client.js.map +1 -0
  171. package/dist/proxy/server.d.ts +111 -0
  172. package/dist/proxy/server.d.ts.map +1 -0
  173. package/dist/proxy/server.js +444 -0
  174. package/dist/proxy/server.js.map +1 -0
  175. package/dist/scanner.d.ts +91 -0
  176. package/dist/scanner.d.ts.map +1 -0
  177. package/dist/scanner.js +373 -0
  178. package/dist/scanner.js.map +1 -0
  179. package/dist/session/index.d.ts +32 -0
  180. package/dist/session/index.d.ts.map +1 -0
  181. package/dist/session/index.js +31 -0
  182. package/dist/session/index.js.map +1 -0
  183. package/dist/session/manager.d.ts +166 -0
  184. package/dist/session/manager.d.ts.map +1 -0
  185. package/dist/session/manager.js +454 -0
  186. package/dist/session/manager.js.map +1 -0
  187. package/dist/session/sqlite-store.d.ts +54 -0
  188. package/dist/session/sqlite-store.d.ts.map +1 -0
  189. package/dist/session/sqlite-store.js +209 -0
  190. package/dist/session/sqlite-store.js.map +1 -0
  191. package/dist/session/types.d.ts +179 -0
  192. package/dist/session/types.d.ts.map +1 -0
  193. package/dist/session/types.js +38 -0
  194. package/dist/session/types.js.map +1 -0
  195. package/dist/templates.d.ts +64 -0
  196. package/dist/templates.d.ts.map +1 -0
  197. package/dist/templates.js +451 -0
  198. package/dist/templates.js.map +1 -0
  199. package/dist/utils/config.d.ts +57 -0
  200. package/dist/utils/config.d.ts.map +1 -0
  201. package/dist/utils/config.js +104 -0
  202. package/dist/utils/config.js.map +1 -0
  203. package/dist/utils/errors.d.ts +18 -0
  204. package/dist/utils/errors.d.ts.map +1 -0
  205. package/dist/utils/errors.js +35 -0
  206. package/dist/utils/errors.js.map +1 -0
  207. package/dist/utils/logger.d.ts +144 -0
  208. package/dist/utils/logger.d.ts.map +1 -0
  209. package/dist/utils/logger.js +300 -0
  210. package/dist/utils/logger.js.map +1 -0
  211. package/dist/wizard.d.ts +68 -0
  212. package/dist/wizard.d.ts.map +1 -0
  213. package/dist/wizard.js +395 -0
  214. package/dist/wizard.js.map +1 -0
  215. package/package.json +99 -0
@@ -0,0 +1,431 @@
1
+ /**
2
+ * Tollgate Doctor Command
3
+ *
4
+ * Diagnostic command to verify configuration and environment before running.
5
+ * Checks configuration validity, environment variables, and system resources.
6
+ *
7
+ * Usage:
8
+ * tollgate doctor - Run all diagnostics
9
+ * tollgate doctor --config path - Check specific config file
10
+ * tollgate doctor --server name - Check specific server only
11
+ */
12
+ import chalk from 'chalk';
13
+ import { existsSync, accessSync, constants, mkdirSync, unlinkSync, writeFileSync } from 'node:fs';
14
+ import { join, dirname } from 'node:path';
15
+ import { loadConfig, validateConfigWithDetails, getDataDir, } from '../../index.js';
16
+ // ============================================================================
17
+ // Diagnostic Checks
18
+ // ============================================================================
19
+ /**
20
+ * Check 1: Configuration file exists and is readable
21
+ */
22
+ function checkConfigExists(configPath) {
23
+ const name = 'Configuration file';
24
+ if (!existsSync(configPath)) {
25
+ return {
26
+ name,
27
+ status: 'fail',
28
+ message: `Not found: ${configPath}`,
29
+ details: 'Run `tollgate init` to create a configuration file.',
30
+ fixable: true,
31
+ };
32
+ }
33
+ try {
34
+ accessSync(configPath, constants.R_OK);
35
+ return {
36
+ name,
37
+ status: 'pass',
38
+ message: `Found: ${configPath}`,
39
+ };
40
+ }
41
+ catch {
42
+ return {
43
+ name,
44
+ status: 'fail',
45
+ message: `Not readable: ${configPath}`,
46
+ details: 'Check file permissions.',
47
+ };
48
+ }
49
+ }
50
+ /**
51
+ * Check 2: Configuration is valid
52
+ */
53
+ async function checkConfigValid(configPath) {
54
+ const name = 'Configuration valid';
55
+ try {
56
+ const config = await loadConfig(configPath);
57
+ const validation = validateConfigWithDetails(config);
58
+ if (!validation.valid) {
59
+ const errors = validation.issues.filter((i) => i.level === 'error');
60
+ return {
61
+ name,
62
+ status: 'fail',
63
+ message: `${errors.length} error(s) found`,
64
+ details: errors.map((e) => ` - ${e.message}`).join('\n'),
65
+ };
66
+ }
67
+ const warnings = validation.issues.filter((i) => i.level === 'warning');
68
+ if (warnings.length > 0) {
69
+ return {
70
+ name,
71
+ status: 'warn',
72
+ message: `Valid with ${warnings.length} warning(s)`,
73
+ details: warnings.map((w) => ` - ${w.message}`).join('\n'),
74
+ };
75
+ }
76
+ return {
77
+ name,
78
+ status: 'pass',
79
+ message: 'Valid',
80
+ };
81
+ }
82
+ catch (error) {
83
+ return {
84
+ name,
85
+ status: 'fail',
86
+ message: 'Failed to parse configuration',
87
+ details: error instanceof Error ? error.message : String(error),
88
+ };
89
+ }
90
+ }
91
+ /**
92
+ * Check 3: Servers configured
93
+ */
94
+ function checkServersConfigured(config, serverFilter) {
95
+ const name = 'Servers configured';
96
+ if (!config.servers || Object.keys(config.servers).length === 0) {
97
+ return {
98
+ name,
99
+ status: 'fail',
100
+ message: 'No servers configured',
101
+ details: 'Add at least one server to your configuration.',
102
+ };
103
+ }
104
+ const serverNames = Object.keys(config.servers);
105
+ if (serverFilter) {
106
+ if (!config.servers[serverFilter]) {
107
+ return {
108
+ name,
109
+ status: 'fail',
110
+ message: `Server "${serverFilter}" not found`,
111
+ details: `Available servers: ${serverNames.join(', ')}`,
112
+ };
113
+ }
114
+ return {
115
+ name,
116
+ status: 'pass',
117
+ message: `Server "${serverFilter}" configured`,
118
+ };
119
+ }
120
+ return {
121
+ name,
122
+ status: 'pass',
123
+ message: `${serverNames.length} server(s): ${serverNames.join(', ')}`,
124
+ };
125
+ }
126
+ /**
127
+ * Check 4: Environment variables for each server
128
+ */
129
+ function checkServerEnvVars(serverName, serverConfig) {
130
+ const results = [];
131
+ // Check if server has env config
132
+ if (!serverConfig.env) {
133
+ return results;
134
+ }
135
+ for (const [key, value] of Object.entries(serverConfig.env)) {
136
+ const name = `Env: ${key} (${serverName})`;
137
+ // Check if it references an environment variable
138
+ const envVarMatch = String(value).match(/\$\{?([A-Z_][A-Z0-9_]*)\}?/);
139
+ if (envVarMatch) {
140
+ const envVarName = envVarMatch[1];
141
+ const envValue = process.env[envVarName];
142
+ if (!envValue) {
143
+ results.push({
144
+ name,
145
+ status: 'warn',
146
+ message: `Not set: ${envVarName}`,
147
+ details: `Set this environment variable before running the ${serverName} server.`,
148
+ });
149
+ }
150
+ else {
151
+ // Mask the value for display
152
+ const maskedValue = envValue.length > 8
153
+ ? `${envValue.slice(0, 4)}...${envValue.slice(-4)}`
154
+ : '****';
155
+ results.push({
156
+ name,
157
+ status: 'pass',
158
+ message: `Set (${maskedValue})`,
159
+ });
160
+ }
161
+ }
162
+ }
163
+ return results;
164
+ }
165
+ /**
166
+ * Check 5: Server command exists
167
+ */
168
+ function checkServerCommand(serverName, serverConfig) {
169
+ const name = `Command: ${serverName}`;
170
+ if (!serverConfig.command) {
171
+ return {
172
+ name,
173
+ status: 'fail',
174
+ message: 'No command specified',
175
+ };
176
+ }
177
+ // For npx commands, we just verify the format
178
+ if (serverConfig.command === 'npx') {
179
+ return {
180
+ name,
181
+ status: 'pass',
182
+ message: `npx ${serverConfig.args?.join(' ') ?? ''}`,
183
+ };
184
+ }
185
+ // For other commands, we could check if they exist in PATH
186
+ // but that's complex and may have false negatives
187
+ return {
188
+ name,
189
+ status: 'pass',
190
+ message: serverConfig.command,
191
+ };
192
+ }
193
+ /**
194
+ * Check 6: Data directory writable
195
+ */
196
+ function checkDataDirectory() {
197
+ const name = 'Data directory';
198
+ const dataDir = getDataDir();
199
+ try {
200
+ // Create directory if it doesn't exist
201
+ if (!existsSync(dataDir)) {
202
+ mkdirSync(dataDir, { recursive: true });
203
+ }
204
+ // Test write access
205
+ const testFile = join(dataDir, '.doctor-test');
206
+ writeFileSync(testFile, 'test');
207
+ unlinkSync(testFile);
208
+ return {
209
+ name,
210
+ status: 'pass',
211
+ message: `Writable: ${dataDir}`,
212
+ };
213
+ }
214
+ catch (error) {
215
+ return {
216
+ name,
217
+ status: 'fail',
218
+ message: `Not writable: ${dataDir}`,
219
+ details: error instanceof Error ? error.message : String(error),
220
+ };
221
+ }
222
+ }
223
+ /**
224
+ * Check 7: Audit database
225
+ */
226
+ function checkAuditDatabase(auditPath) {
227
+ const name = 'Audit database';
228
+ const dataDir = getDataDir();
229
+ const dbPath = auditPath ?? join(dataDir, 'audit.db');
230
+ if (existsSync(dbPath)) {
231
+ try {
232
+ accessSync(dbPath, constants.R_OK | constants.W_OK);
233
+ return {
234
+ name,
235
+ status: 'pass',
236
+ message: `Exists and writable: ${dbPath}`,
237
+ };
238
+ }
239
+ catch {
240
+ return {
241
+ name,
242
+ status: 'fail',
243
+ message: `Not writable: ${dbPath}`,
244
+ details: 'Check file permissions on the audit database.',
245
+ };
246
+ }
247
+ }
248
+ // Database doesn't exist yet - check if we can create it
249
+ const dbDir = dirname(dbPath);
250
+ if (!existsSync(dbDir)) {
251
+ try {
252
+ mkdirSync(dbDir, { recursive: true });
253
+ }
254
+ catch {
255
+ return {
256
+ name,
257
+ status: 'warn',
258
+ message: `Directory not writable: ${dbDir}`,
259
+ details: 'Audit database will be created on first use.',
260
+ };
261
+ }
262
+ }
263
+ return {
264
+ name,
265
+ status: 'pass',
266
+ message: `Will be created: ${dbPath}`,
267
+ };
268
+ }
269
+ /**
270
+ * Check 8: Analyzer availability
271
+ */
272
+ function checkAnalyzers(config, serverFilter) {
273
+ const name = 'Smart analyzers';
274
+ const analyzersUsed = new Set();
275
+ const servers = serverFilter
276
+ ? { [serverFilter]: config.servers?.[serverFilter] }
277
+ : config.servers ?? {};
278
+ for (const serverConfig of Object.values(servers)) {
279
+ if (!serverConfig)
280
+ continue;
281
+ // Check default analyzer
282
+ if (serverConfig.defaults?.analyzer) {
283
+ analyzersUsed.add(serverConfig.defaults.analyzer);
284
+ }
285
+ // Check tool-specific analyzers
286
+ if (serverConfig.tools) {
287
+ for (const toolPolicy of Object.values(serverConfig.tools)) {
288
+ if (typeof toolPolicy === 'object' && toolPolicy !== null && 'analyzer' in toolPolicy) {
289
+ analyzersUsed.add(String(toolPolicy.analyzer));
290
+ }
291
+ }
292
+ }
293
+ }
294
+ if (analyzersUsed.size === 0) {
295
+ return {
296
+ name,
297
+ status: 'pass',
298
+ message: 'None configured (using static policies)',
299
+ };
300
+ }
301
+ const validAnalyzers = ['sql', 'filesystem', 'shell', 'http'];
302
+ const invalid = [...analyzersUsed].filter((a) => !validAnalyzers.includes(a));
303
+ if (invalid.length > 0) {
304
+ return {
305
+ name,
306
+ status: 'fail',
307
+ message: `Invalid analyzer(s): ${invalid.join(', ')}`,
308
+ details: `Valid analyzers: ${validAnalyzers.join(', ')}`,
309
+ };
310
+ }
311
+ return {
312
+ name,
313
+ status: 'pass',
314
+ message: `Configured: ${[...analyzersUsed].join(', ')}`,
315
+ };
316
+ }
317
+ // ============================================================================
318
+ // Main Doctor Command
319
+ // ============================================================================
320
+ export async function runDoctor(options) {
321
+ const configPath = options.config ?? './tollgate.yaml';
322
+ const results = [];
323
+ console.log(chalk.bold('\n🩺 Tollgate Doctor\n'));
324
+ // Check 1: Config file exists
325
+ results.push(checkConfigExists(configPath));
326
+ // If config doesn't exist, we can't continue with most checks
327
+ if (results[0].status === 'fail') {
328
+ printResults(results, options);
329
+ return;
330
+ }
331
+ // Check 2: Config is valid
332
+ results.push(await checkConfigValid(configPath));
333
+ // Try to load config for further checks
334
+ let config;
335
+ try {
336
+ config = await loadConfig(configPath);
337
+ }
338
+ catch {
339
+ printResults(results, options);
340
+ return;
341
+ }
342
+ // Check 3: Servers configured
343
+ results.push(checkServersConfigured(config, options.server));
344
+ // Check 4 & 5: Per-server checks
345
+ const servers = options.server
346
+ ? { [options.server]: config.servers?.[options.server] }
347
+ : config.servers ?? {};
348
+ for (const [serverName, serverConfig] of Object.entries(servers)) {
349
+ if (!serverConfig)
350
+ continue;
351
+ // Command check
352
+ results.push(checkServerCommand(serverName, serverConfig));
353
+ // Environment variable checks
354
+ results.push(...checkServerEnvVars(serverName, serverConfig));
355
+ }
356
+ // Check 6: Data directory
357
+ results.push(checkDataDirectory());
358
+ // Check 7: Audit database
359
+ results.push(checkAuditDatabase());
360
+ // Check 8: Analyzers
361
+ results.push(checkAnalyzers(config, options.server));
362
+ // Print results
363
+ printResults(results, options);
364
+ }
365
+ // ============================================================================
366
+ // Output Formatting
367
+ // ============================================================================
368
+ function printResults(results, options) {
369
+ if (options.json) {
370
+ const report = {
371
+ timestamp: new Date().toISOString(),
372
+ configPath: options.config ?? './tollgate.yaml',
373
+ passed: results.filter((r) => r.status === 'pass').length,
374
+ warnings: results.filter((r) => r.status === 'warn').length,
375
+ failed: results.filter((r) => r.status === 'fail').length,
376
+ results,
377
+ };
378
+ console.log(JSON.stringify(report, null, 2));
379
+ return;
380
+ }
381
+ // Print individual results
382
+ for (const result of results) {
383
+ const icon = getStatusIcon(result.status);
384
+ const color = getStatusColor(result.status);
385
+ console.log(`${icon} ${chalk.bold(result.name)}`);
386
+ console.log(` ${color(result.message)}`);
387
+ if (result.details) {
388
+ console.log(chalk.dim(` ${result.details.replace(/\n/g, '\n ')}`));
389
+ }
390
+ }
391
+ // Summary
392
+ console.log(chalk.bold('\n📊 Summary\n'));
393
+ const passed = results.filter((r) => r.status === 'pass').length;
394
+ const warnings = results.filter((r) => r.status === 'warn').length;
395
+ const failed = results.filter((r) => r.status === 'fail').length;
396
+ console.log(` ${chalk.green('✓')} Passed: ${passed}`);
397
+ console.log(` ${chalk.yellow('⚠')} Warnings: ${warnings}`);
398
+ console.log(` ${chalk.red('✗')} Failed: ${failed}`);
399
+ console.log();
400
+ if (failed > 0) {
401
+ console.log(chalk.red('Some checks failed. Please fix the issues above.'));
402
+ process.exit(1);
403
+ }
404
+ else if (warnings > 0) {
405
+ console.log(chalk.yellow('Configuration is valid with warnings.'));
406
+ }
407
+ else {
408
+ console.log(chalk.green('All checks passed! Your configuration is ready.'));
409
+ }
410
+ }
411
+ function getStatusIcon(status) {
412
+ switch (status) {
413
+ case 'pass':
414
+ return chalk.green('✓');
415
+ case 'warn':
416
+ return chalk.yellow('⚠');
417
+ case 'fail':
418
+ return chalk.red('✗');
419
+ }
420
+ }
421
+ function getStatusColor(status) {
422
+ switch (status) {
423
+ case 'pass':
424
+ return chalk.green;
425
+ case 'warn':
426
+ return chalk.yellow;
427
+ case 'fail':
428
+ return chalk.red;
429
+ }
430
+ }
431
+ //# sourceMappingURL=doctor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../../src/cli/commands/doctor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Tollgate Export Command
3
+ *
4
+ * Exports audit logs in various formats for compliance reporting.
5
+ */
6
+ export interface ExportOptions {
7
+ format: string;
8
+ output?: string;
9
+ since?: string;
10
+ until?: string;
11
+ server?: string;
12
+ limit?: string;
13
+ risk?: string;
14
+ redact: boolean;
15
+ auditPath?: string;
16
+ }
17
+ export declare function exportLogs(options: ExportOptions): Promise<void>;
18
+ //# sourceMappingURL=export.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/export.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAYH,MAAM,WAAW,aAAa;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAsCtE"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Tollgate Export Command
3
+ *
4
+ * Exports audit logs in various formats for compliance reporting.
5
+ */
6
+ import chalk from 'chalk';
7
+ import { writeFileSync } from 'node:fs';
8
+ import { AuditLogger, exportAuditRecords, ConfigError, TollgateError, } from '../../index.js';
9
+ export async function exportLogs(options) {
10
+ try {
11
+ const logger = new AuditLogger(options.auditPath);
12
+ // Parse dates
13
+ const since = options.since ? new Date(options.since) : undefined;
14
+ const until = options.until ? new Date(options.until) : undefined;
15
+ // Validate format
16
+ const validFormats = ['json', 'jsonl', 'csv', 'cef'];
17
+ if (!validFormats.includes(options.format)) {
18
+ console.error(chalk.red(`Invalid format: ${options.format}`));
19
+ console.error(chalk.dim(`Valid formats: ${validFormats.join(', ')}`));
20
+ process.exit(1);
21
+ }
22
+ // Export records
23
+ const output = exportAuditRecords(logger, options.format, {
24
+ since,
25
+ until,
26
+ server: options.server,
27
+ limit: options.limit ? parseInt(options.limit, 10) : undefined,
28
+ riskLevel: options.risk,
29
+ useRedacted: options.redact !== false,
30
+ });
31
+ // Output to file or stdout
32
+ if (options.output) {
33
+ writeFileSync(options.output, output);
34
+ console.error(chalk.green(`Exported to ${options.output}`));
35
+ }
36
+ else {
37
+ console.log(output);
38
+ }
39
+ logger.close();
40
+ }
41
+ catch (error) {
42
+ handleError(error);
43
+ }
44
+ }
45
+ function handleError(error) {
46
+ if (error instanceof ConfigError) {
47
+ console.error(chalk.red(`Configuration Error: ${error.message}`));
48
+ if (error.details) {
49
+ console.error(chalk.dim(JSON.stringify(error.details, null, 2)));
50
+ }
51
+ }
52
+ else if (error instanceof TollgateError) {
53
+ console.error(chalk.red(`Error [${error.code}]: ${error.message}`));
54
+ }
55
+ else if (error instanceof Error) {
56
+ console.error(chalk.red(`Error: ${error.message}`));
57
+ }
58
+ else {
59
+ console.error(chalk.red('An unknown error occurred'));
60
+ }
61
+ process.exit(1);
62
+ }
63
+ //# sourceMappingURL=export.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export.js","sourceRoot":"","sources":["../../../src/cli/commands/export.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Tollgate Init Command
3
+ *
4
+ * Creates a tollgate.yaml configuration file.
5
+ */
6
+ export interface InitOptions {
7
+ output: string;
8
+ interactive?: boolean;
9
+ force?: boolean;
10
+ }
11
+ export declare function initConfig(options: InitOptions): Promise<void>;
12
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAWH,MAAM,WAAW,WAAW;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,KAAK,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CA2EpE"}
@@ -0,0 +1,102 @@
1
+ /**
2
+ * Tollgate Init Command
3
+ *
4
+ * Creates a tollgate.yaml configuration file.
5
+ */
6
+ import chalk from 'chalk';
7
+ import { writeFileSync, existsSync } from 'node:fs';
8
+ import { runWizard, generateConfig, ConfigError, TollgateError, } from '../../index.js';
9
+ export async function initConfig(options) {
10
+ try {
11
+ if (existsSync(options.output) && !options.force) {
12
+ console.error(chalk.red(`Error: ${options.output} already exists`));
13
+ console.error(chalk.dim('Use --force to overwrite.'));
14
+ process.exit(1);
15
+ }
16
+ let configContent;
17
+ if (options.interactive) {
18
+ // Run interactive wizard
19
+ const wizardResult = await runWizard();
20
+ configContent = generateConfig(wizardResult);
21
+ }
22
+ else {
23
+ // Use default example config
24
+ configContent = `# Tollgate Configuration
25
+ # https://github.com/dotsetlabs/tollgate
26
+
27
+ version: "1"
28
+
29
+ # Default action when no policy matches
30
+ defaults:
31
+ action: prompt # allow | deny | prompt
32
+ timeout: 60000 # Approval timeout in ms
33
+
34
+ # MCP Server configurations
35
+ servers:
36
+ # PostgreSQL database server
37
+ postgres:
38
+ command: "npx"
39
+ args: ["-y", "@modelcontextprotocol/server-postgres"]
40
+ env:
41
+ DATABASE_URL: "\${DATABASE_URL}"
42
+ tools:
43
+ # Allow read-only queries
44
+ "query":
45
+ action: allow
46
+ # Prompt for write operations
47
+ "execute":
48
+ action: prompt
49
+ message: "Agent wants to execute SQL"
50
+ # Block everything else
51
+ "*":
52
+ action: deny
53
+
54
+ # Filesystem server
55
+ filesystem:
56
+ command: "npx"
57
+ args: ["-y", "@anthropic/mcp-server-filesystem", "./"]
58
+ tools:
59
+ # Allow all read operations
60
+ "read_*":
61
+ action: allow
62
+ "list_*":
63
+ action: allow
64
+ # Prompt for writes
65
+ "write_*":
66
+ action: prompt
67
+ "create_*":
68
+ action: prompt
69
+ # Block deletes
70
+ "delete_*":
71
+ action: deny
72
+ reason: "File deletion is disabled for safety"
73
+ `;
74
+ }
75
+ writeFileSync(options.output, configContent);
76
+ console.log(chalk.green(`Created ${options.output}`));
77
+ console.log(chalk.dim('\nEdit this file to configure your MCP servers and policies.'));
78
+ console.log(chalk.dim('Run `tollgate validate` to check your configuration.'));
79
+ }
80
+ catch (error) {
81
+ handleError(error);
82
+ }
83
+ }
84
+ function handleError(error) {
85
+ if (error instanceof ConfigError) {
86
+ console.error(chalk.red(`Configuration Error: ${error.message}`));
87
+ if (error.details) {
88
+ console.error(chalk.dim(JSON.stringify(error.details, null, 2)));
89
+ }
90
+ }
91
+ else if (error instanceof TollgateError) {
92
+ console.error(chalk.red(`Error [${error.code}]: ${error.message}`));
93
+ }
94
+ else if (error instanceof Error) {
95
+ console.error(chalk.red(`Error: ${error.message}`));
96
+ }
97
+ else {
98
+ console.error(chalk.red('An unknown error occurred'));
99
+ }
100
+ process.exit(1);
101
+ }
102
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EACH,SAAS,EACT,cAAc,EACd,WAAW,EACX,aAAa,GAChB,MAAM,gBAAgB,CAAC;AAQxB,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,OAAoB;IACjD,IAAI,CAAC;QACD,IAAI,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YAC/C,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,OAAO,CAAC,MAAM,iBAAiB,CAAC,CAAC,CAAC;YACpE,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC,CAAC;YACtD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,CAAC;QAED,IAAI,aAAqB,CAAC;QAE1B,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;YACtB,yBAAyB;YACzB,MAAM,YAAY,GAAG,MAAM,SAAS,EAAE,CAAC;YACvC,aAAa,GAAG,cAAc,CAAC,YAAY,CAAC,CAAC;QACjD,CAAC;aAAM,CAAC;YACJ,6BAA6B;YAC7B,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiD3B,CAAC;QACM,CAAC;QAED,aAAa,CAAC,OAAO,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;QAC7C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,WAAW,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QACtD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,8DAA8D,CAAC,CAAC,CAAC;QACvF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,sDAAsD,CAAC,CAAC,CAAC;IACnF,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,WAAW,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;AACL,CAAC;AAED,SAAS,WAAW,CAAC,KAAc;IAC/B,IAAI,KAAK,YAAY,WAAW,EAAE,CAAC;QAC/B,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,wBAAwB,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAClE,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;YAChB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACrE,CAAC;IACL,CAAC;SAAM,IAAI,KAAK,YAAY,aAAa,EAAE,CAAC;QACxC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,KAAK,CAAC,IAAI,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IACxE,CAAC;SAAM,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;QAChC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IACxD,CAAC;SAAM,CAAC;QACJ,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC,CAAC;IAC1D,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACpB,CAAC"}