@defai.digital/ax-cli 3.5.4 → 3.6.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 (162) hide show
  1. package/.ax-cli/checkpoints/2025-11-20/checkpoint-11e9e0ba-c39d-4fd2-aa77-bc818811c921.json +69 -0
  2. package/.ax-cli/checkpoints/2025-11-20/checkpoint-2b260b98-b418-4c7c-9694-e2b94967e662.json +24 -0
  3. package/.ax-cli/checkpoints/2025-11-20/checkpoint-7e03601e-e8ab-4cd7-9841-a74b66adf78f.json +69 -0
  4. package/.ax-cli/checkpoints/2025-11-20/checkpoint-7f9c6562-771f-4fd0-adcf-9e7e9ac34ae8.json +44 -0
  5. package/.ax-cli/checkpoints/2025-11-20/checkpoint-e1ebe666-4c3a-4367-ba5c-27fe512a9c70.json +24 -0
  6. package/.ax-cli/checkpoints/2025-11-21/checkpoint-15743e7d-430c-4d76-b6fc-955d7a5c250c.json +44 -0
  7. package/.ax-cli/checkpoints/2025-11-21/checkpoint-25cf7679-0b3f-4988-83d7-704548fbba91.json +69 -0
  8. package/.ax-cli/checkpoints/2025-11-21/checkpoint-54aedbac-6db0-464e-8ebb-dbb3979e6dca.json +24 -0
  9. package/.ax-cli/checkpoints/2025-11-21/checkpoint-7658aed8-fe5d-4222-903f-1a7c63717ea7.json +24 -0
  10. package/.ax-cli/checkpoints/2025-11-21/checkpoint-c9c13497-40dc-4294-a327-6a5fc854eaa1.json +69 -0
  11. package/.ax-cli/memory.json +15 -8
  12. package/README.md +423 -82
  13. package/ax.config.json +333 -0
  14. package/config-defaults/messages.yaml +75 -0
  15. package/config-defaults/models.yaml +66 -0
  16. package/config-defaults/prompts.yaml +156 -0
  17. package/config-defaults/settings.yaml +86 -0
  18. package/dist/agent/chat-history-manager.d.ts +56 -0
  19. package/dist/agent/chat-history-manager.js +150 -0
  20. package/dist/agent/chat-history-manager.js.map +1 -0
  21. package/dist/agent/llm-agent.js +1 -1
  22. package/dist/agent/llm-agent.js.map +1 -1
  23. package/dist/agent/tool-manager.d.ts +39 -0
  24. package/dist/agent/tool-manager.js +76 -0
  25. package/dist/agent/tool-manager.js.map +1 -0
  26. package/dist/analyzers/code-smells/detectors/data-clumps-detector.js +7 -9
  27. package/dist/analyzers/code-smells/detectors/data-clumps-detector.js.map +1 -1
  28. package/dist/analyzers/code-smells/detectors/dead-code-detector.js +1 -1
  29. package/dist/analyzers/code-smells/detectors/dead-code-detector.js.map +1 -1
  30. package/dist/analyzers/code-smells/detectors/duplicate-code-detector.js +22 -10
  31. package/dist/analyzers/code-smells/detectors/duplicate-code-detector.js.map +1 -1
  32. package/dist/analyzers/code-smells/detectors/feature-envy-detector.js +1 -1
  33. package/dist/analyzers/code-smells/detectors/feature-envy-detector.js.map +1 -1
  34. package/dist/analyzers/code-smells/detectors/inappropriate-intimacy-detector.js +1 -1
  35. package/dist/analyzers/code-smells/detectors/inappropriate-intimacy-detector.js.map +1 -1
  36. package/dist/analyzers/code-smells/detectors/large-class-detector.js +4 -1
  37. package/dist/analyzers/code-smells/detectors/large-class-detector.js.map +1 -1
  38. package/dist/analyzers/code-smells/detectors/long-method-detector.js +4 -1
  39. package/dist/analyzers/code-smells/detectors/long-method-detector.js.map +1 -1
  40. package/dist/analyzers/code-smells/detectors/long-parameter-list-detector.js +4 -1
  41. package/dist/analyzers/code-smells/detectors/long-parameter-list-detector.js.map +1 -1
  42. package/dist/analyzers/code-smells/detectors/magic-numbers-detector.js +4 -5
  43. package/dist/analyzers/code-smells/detectors/magic-numbers-detector.js.map +1 -1
  44. package/dist/analyzers/code-smells/detectors/nested-conditionals-detector.js +4 -1
  45. package/dist/analyzers/code-smells/detectors/nested-conditionals-detector.js.map +1 -1
  46. package/dist/commands/memory.js +1 -1
  47. package/dist/commands/memory.js.map +1 -1
  48. package/dist/commands/setup.js +19 -6
  49. package/dist/commands/setup.js.map +1 -1
  50. package/dist/index.js +7 -0
  51. package/dist/index.js.bak +664 -0
  52. package/dist/index.js.map +1 -1
  53. package/dist/llm/client.d.ts +1 -0
  54. package/dist/llm/client.js +44 -0
  55. package/dist/llm/client.js.map +1 -1
  56. package/dist/mcp/health.js +4 -2
  57. package/dist/mcp/health.js.map +1 -1
  58. package/dist/mcp/ssrf-protection.d.ts +86 -0
  59. package/dist/mcp/ssrf-protection.js +313 -0
  60. package/dist/mcp/ssrf-protection.js.map +1 -0
  61. package/dist/mcp/validation.d.ts +4 -0
  62. package/dist/mcp/validation.js +122 -11
  63. package/dist/mcp/validation.js.map +1 -1
  64. package/dist/schemas/settings-schemas.d.ts +53 -0
  65. package/dist/schemas/settings-schemas.js +47 -0
  66. package/dist/schemas/settings-schemas.js.map +1 -1
  67. package/dist/tools/bash.d.ts +3 -2
  68. package/dist/tools/bash.js +31 -2
  69. package/dist/tools/bash.js.map +1 -1
  70. package/dist/tools/search.d.ts +1 -1
  71. package/dist/tools/search.js +121 -128
  72. package/dist/tools/search.js.map +1 -1
  73. package/dist/tools/text-editor.js +52 -15
  74. package/dist/tools/text-editor.js.map +1 -1
  75. package/dist/tools/web-search/index.d.ts +0 -2
  76. package/dist/tools/web-search/index.js +0 -2
  77. package/dist/tools/web-search/index.js.map +1 -1
  78. package/dist/tools/web-search/router.d.ts +0 -2
  79. package/dist/tools/web-search/router.js +2 -37
  80. package/dist/tools/web-search/router.js.map +1 -1
  81. package/dist/tools/web-search/web-search-tool.js +2 -12
  82. package/dist/tools/web-search/web-search-tool.js.map +1 -1
  83. package/dist/ui/components/chat-history.js +1 -1
  84. package/dist/ui/components/chat-history.js.map +1 -1
  85. package/dist/ui/components/chat-input.d.ts +4 -1
  86. package/dist/ui/components/chat-input.js +133 -52
  87. package/dist/ui/components/chat-input.js.map +1 -1
  88. package/dist/ui/components/chat-interface.js +5 -4
  89. package/dist/ui/components/chat-interface.js.map +1 -1
  90. package/dist/ui/components/confirmation-dialog.js +1 -1
  91. package/dist/ui/components/confirmation-dialog.js.map +1 -1
  92. package/dist/ui/components/keyboard-hints.js +2 -0
  93. package/dist/ui/components/keyboard-hints.js.map +1 -1
  94. package/dist/ui/components/status-bar.js +3 -13
  95. package/dist/ui/components/status-bar.js.map +1 -1
  96. package/dist/ui/components/welcome-panel.js +4 -0
  97. package/dist/ui/components/welcome-panel.js.map +1 -1
  98. package/dist/ui/hooks/use-chat-reducer.d.ts +61 -0
  99. package/dist/ui/hooks/use-chat-reducer.js +118 -0
  100. package/dist/ui/hooks/use-chat-reducer.js.map +1 -0
  101. package/dist/ui/hooks/use-enhanced-input.d.ts +44 -0
  102. package/dist/ui/hooks/use-enhanced-input.js +364 -0
  103. package/dist/ui/hooks/use-enhanced-input.js.map +1 -0
  104. package/dist/ui/hooks/use-input-handler.d.ts +48 -0
  105. package/dist/ui/hooks/use-input-handler.js +1446 -0
  106. package/dist/ui/hooks/use-input-handler.js.map +1 -0
  107. package/dist/utils/audit-logger.d.ts +205 -0
  108. package/dist/utils/audit-logger.js +269 -0
  109. package/dist/utils/audit-logger.js.map +1 -0
  110. package/dist/utils/command-security.d.ts +85 -0
  111. package/dist/utils/command-security.js +200 -0
  112. package/dist/utils/command-security.js.map +1 -0
  113. package/dist/utils/config-loader.js +3 -3
  114. package/dist/utils/config-loader.js.map +1 -1
  115. package/dist/utils/encryption.d.ts +78 -0
  116. package/dist/utils/encryption.js +216 -0
  117. package/dist/utils/encryption.js.map +1 -0
  118. package/dist/utils/error-sanitizer.d.ts +119 -0
  119. package/dist/utils/error-sanitizer.js +253 -0
  120. package/dist/utils/error-sanitizer.js.map +1 -0
  121. package/dist/utils/input-sanitizer.d.ts +210 -0
  122. package/dist/utils/input-sanitizer.js +362 -0
  123. package/dist/utils/input-sanitizer.js.map +1 -0
  124. package/dist/utils/json-utils.d.ts +13 -0
  125. package/dist/utils/json-utils.js +55 -1
  126. package/dist/utils/json-utils.js.map +1 -1
  127. package/dist/utils/paste-collapse.d.ts +46 -0
  128. package/dist/utils/paste-collapse.js +77 -0
  129. package/dist/utils/paste-collapse.js.map +1 -0
  130. package/dist/utils/paste-utils.d.ts +99 -0
  131. package/dist/utils/paste-utils.js +239 -0
  132. package/dist/utils/paste-utils.js.map +1 -0
  133. package/dist/utils/path-security.d.ts +90 -0
  134. package/dist/utils/path-security.js +328 -0
  135. package/dist/utils/path-security.js.map +1 -0
  136. package/dist/utils/process-pool.d.ts +105 -0
  137. package/dist/utils/process-pool.js +326 -0
  138. package/dist/utils/process-pool.js.map +1 -0
  139. package/dist/utils/rate-limiter.d.ts +221 -0
  140. package/dist/utils/rate-limiter.js +317 -0
  141. package/dist/utils/rate-limiter.js.map +1 -0
  142. package/dist/utils/settings-manager.js +99 -6
  143. package/dist/utils/settings-manager.js.map +1 -1
  144. package/dist/utils/streaming-analyzer.js +9 -21
  145. package/dist/utils/streaming-analyzer.js.map +1 -1
  146. package/package.json +3 -7
  147. package/packages/schemas/dist/index.d.ts +14 -0
  148. package/packages/schemas/dist/index.d.ts.map +1 -0
  149. package/packages/schemas/dist/index.js +19 -0
  150. package/packages/schemas/dist/index.js.map +1 -0
  151. package/packages/schemas/dist/public/core/brand-types.d.ts +308 -0
  152. package/packages/schemas/dist/public/core/brand-types.d.ts.map +1 -0
  153. package/packages/schemas/dist/public/core/brand-types.js +243 -0
  154. package/packages/schemas/dist/public/core/brand-types.js.map +1 -0
  155. package/packages/schemas/dist/public/core/enums.d.ts +227 -0
  156. package/packages/schemas/dist/public/core/enums.d.ts.map +1 -0
  157. package/packages/schemas/dist/public/core/enums.js +222 -0
  158. package/packages/schemas/dist/public/core/enums.js.map +1 -0
  159. package/packages/schemas/dist/public/core/id-types.d.ts +286 -0
  160. package/packages/schemas/dist/public/core/id-types.d.ts.map +1 -0
  161. package/packages/schemas/dist/public/core/id-types.js +136 -0
  162. package/packages/schemas/dist/public/core/id-types.js.map +1 -0
@@ -0,0 +1,326 @@
1
+ /**
2
+ * Process Pool Manager
3
+ *
4
+ * Manages a pool of reusable child processes to prevent memory leaks
5
+ * and resource exhaustion (REQ-ARCH-002).
6
+ *
7
+ * Key features:
8
+ * - Limits concurrent processes to prevent resource exhaustion
9
+ * - Queues requests when pool is full
10
+ * - Automatic cleanup of idle processes
11
+ * - Graceful shutdown with proper cleanup
12
+ * - Memory leak prevention through proper event listener management
13
+ *
14
+ * @module process-pool
15
+ */
16
+ import { spawn } from 'child_process';
17
+ import { EventEmitter } from 'events';
18
+ /**
19
+ * Process pool manager for efficient process reuse
20
+ */
21
+ export class ProcessPool extends EventEmitter {
22
+ maxProcesses;
23
+ processTimeout;
24
+ maxQueueSize;
25
+ activeProcesses = new Set();
26
+ taskQueue = [];
27
+ shuttingDown = false;
28
+ idleTimers = new Map();
29
+ constructor(config = {}) {
30
+ super();
31
+ this.maxProcesses = config.maxProcesses ?? 5;
32
+ this.processTimeout = config.processTimeout ?? 30000;
33
+ this.maxQueueSize = config.maxQueueSize ?? 100;
34
+ }
35
+ /**
36
+ * Execute a command using the process pool
37
+ */
38
+ async execute(options) {
39
+ if (this.shuttingDown) {
40
+ throw new Error('Process pool is shutting down');
41
+ }
42
+ // Check queue size limit
43
+ if (this.taskQueue.length >= this.maxQueueSize) {
44
+ throw new Error(`Process pool queue is full (max: ${this.maxQueueSize})`);
45
+ }
46
+ return new Promise((resolve, reject) => {
47
+ const task = {
48
+ options,
49
+ resolve,
50
+ reject,
51
+ timestamp: Date.now(),
52
+ };
53
+ this.taskQueue.push(task);
54
+ this.processQueue();
55
+ });
56
+ }
57
+ /**
58
+ * Process the task queue
59
+ */
60
+ processQueue() {
61
+ // Don't process if shutting down
62
+ if (this.shuttingDown) {
63
+ return;
64
+ }
65
+ // Process tasks while we have capacity
66
+ while (this.taskQueue.length > 0 &&
67
+ this.activeProcesses.size < this.maxProcesses) {
68
+ const task = this.taskQueue.shift();
69
+ if (!task)
70
+ break;
71
+ this.executeTask(task);
72
+ }
73
+ }
74
+ /**
75
+ * Execute a single task
76
+ */
77
+ async executeTask(task) {
78
+ const { options, resolve, reject } = task;
79
+ try {
80
+ const result = await this.spawnProcess(options);
81
+ resolve(result);
82
+ }
83
+ catch (error) {
84
+ reject(error instanceof Error ? error : new Error(String(error)));
85
+ }
86
+ finally {
87
+ // Process next task in queue
88
+ this.processQueue();
89
+ }
90
+ }
91
+ /**
92
+ * Spawn a process and manage its lifecycle
93
+ */
94
+ async spawnProcess(options) {
95
+ return new Promise((resolve, reject) => {
96
+ const proc = spawn(options.command, options.args, {
97
+ cwd: options.cwd,
98
+ });
99
+ this.activeProcesses.add(proc);
100
+ let stdout = '';
101
+ let stderr = '';
102
+ let isResolved = false;
103
+ let timeoutHandle = null;
104
+ // Set timeout
105
+ const timeout = options.timeout ?? this.processTimeout;
106
+ if (timeout > 0) {
107
+ timeoutHandle = setTimeout(() => {
108
+ if (!isResolved) {
109
+ isResolved = true;
110
+ this.cleanupProcess(proc, timeoutHandle);
111
+ reject(new Error(`Process timeout after ${timeout}ms`));
112
+ }
113
+ }, timeout);
114
+ }
115
+ // Collect stdout
116
+ if (proc.stdout) {
117
+ proc.stdout.on('data', (data) => {
118
+ stdout += data.toString();
119
+ });
120
+ }
121
+ // Collect stderr
122
+ if (proc.stderr) {
123
+ proc.stderr.on('data', (data) => {
124
+ stderr += data.toString();
125
+ });
126
+ }
127
+ // Handle process exit
128
+ proc.on('close', (code, signal) => {
129
+ if (isResolved) {
130
+ return;
131
+ }
132
+ isResolved = true;
133
+ this.cleanupProcess(proc, timeoutHandle);
134
+ resolve({
135
+ stdout,
136
+ stderr,
137
+ exitCode: code,
138
+ signal: signal,
139
+ });
140
+ });
141
+ // Handle process errors
142
+ proc.on('error', (error) => {
143
+ if (isResolved) {
144
+ return;
145
+ }
146
+ isResolved = true;
147
+ this.cleanupProcess(proc, timeoutHandle);
148
+ reject(error);
149
+ });
150
+ });
151
+ }
152
+ /**
153
+ * Cleanup process and associated resources
154
+ */
155
+ cleanupProcess(proc, timeoutHandle) {
156
+ // Clear timeout
157
+ if (timeoutHandle) {
158
+ clearTimeout(timeoutHandle);
159
+ }
160
+ // Clear idle timer if exists
161
+ const idleTimer = this.idleTimers.get(proc);
162
+ if (idleTimer) {
163
+ clearTimeout(idleTimer);
164
+ this.idleTimers.delete(proc);
165
+ }
166
+ // Remove all event listeners to prevent memory leaks
167
+ if (proc.stdout) {
168
+ proc.stdout.removeAllListeners();
169
+ }
170
+ if (proc.stderr) {
171
+ proc.stderr.removeAllListeners();
172
+ }
173
+ proc.removeAllListeners();
174
+ // Kill process if still running
175
+ if (proc.exitCode === null && proc.signalCode === null) {
176
+ try {
177
+ proc.kill('SIGTERM');
178
+ // Force kill after 3 seconds if SIGTERM doesn't work
179
+ const forceKillTimeout = setTimeout(() => {
180
+ try {
181
+ if (proc.exitCode === null && !proc.killed) {
182
+ proc.kill('SIGKILL');
183
+ }
184
+ }
185
+ catch {
186
+ // Process already terminated
187
+ }
188
+ // Always clear timeout to prevent leak
189
+ clearTimeout(forceKillTimeout);
190
+ }, 3000);
191
+ // Clear force kill timeout when process exits
192
+ // NOTE: Use setImmediate to ensure listener fires even if already exited
193
+ setImmediate(() => {
194
+ if (proc.exitCode !== null || proc.signalCode !== null) {
195
+ clearTimeout(forceKillTimeout);
196
+ }
197
+ else {
198
+ proc.once('exit', () => clearTimeout(forceKillTimeout));
199
+ }
200
+ });
201
+ }
202
+ catch {
203
+ // Process already terminated or can't be killed
204
+ }
205
+ }
206
+ // Remove from active set
207
+ this.activeProcesses.delete(proc);
208
+ // Emit metrics event
209
+ this.emit('processCompleted', {
210
+ activeProcesses: this.activeProcesses.size,
211
+ queuedTasks: this.taskQueue.length,
212
+ });
213
+ }
214
+ /**
215
+ * Get pool statistics
216
+ */
217
+ getStats() {
218
+ return {
219
+ activeProcesses: this.activeProcesses.size,
220
+ queuedTasks: this.taskQueue.length,
221
+ maxProcesses: this.maxProcesses,
222
+ maxQueueSize: this.maxQueueSize,
223
+ };
224
+ }
225
+ /**
226
+ * Shutdown the pool gracefully
227
+ */
228
+ async shutdown(force = false) {
229
+ this.shuttingDown = true;
230
+ // Reject all queued tasks
231
+ while (this.taskQueue.length > 0) {
232
+ const task = this.taskQueue.shift();
233
+ if (task) {
234
+ task.reject(new Error('Process pool shutting down'));
235
+ }
236
+ }
237
+ // Wait for active processes to complete or force kill
238
+ if (force) {
239
+ // Force kill all active processes
240
+ for (const proc of this.activeProcesses) {
241
+ try {
242
+ proc.kill('SIGKILL');
243
+ }
244
+ catch {
245
+ // Ignore errors
246
+ }
247
+ }
248
+ this.activeProcesses.clear();
249
+ }
250
+ else {
251
+ // Wait for active processes to complete (with timeout)
252
+ const shutdownTimeout = 10000; // 10 seconds
253
+ const startTime = Date.now();
254
+ while (this.activeProcesses.size > 0) {
255
+ if (Date.now() - startTime > shutdownTimeout) {
256
+ // Force kill remaining processes
257
+ for (const proc of this.activeProcesses) {
258
+ try {
259
+ proc.kill('SIGKILL');
260
+ }
261
+ catch {
262
+ // Ignore errors
263
+ }
264
+ }
265
+ this.activeProcesses.clear();
266
+ break;
267
+ }
268
+ // Wait 100ms before checking again
269
+ await new Promise((resolve) => setTimeout(resolve, 100));
270
+ }
271
+ }
272
+ // Clear all idle timers
273
+ for (const timer of this.idleTimers.values()) {
274
+ clearTimeout(timer);
275
+ }
276
+ this.idleTimers.clear();
277
+ this.emit('shutdown');
278
+ }
279
+ /**
280
+ * Check if pool is idle (no active processes or queued tasks)
281
+ */
282
+ isIdle() {
283
+ return this.activeProcesses.size === 0 && this.taskQueue.length === 0;
284
+ }
285
+ /**
286
+ * Check if pool is at capacity
287
+ */
288
+ isAtCapacity() {
289
+ return this.activeProcesses.size >= this.maxProcesses;
290
+ }
291
+ }
292
+ /**
293
+ * Singleton process pool instance for ripgrep
294
+ */
295
+ let ripgrepPool = null;
296
+ /**
297
+ * Get or create the ripgrep process pool
298
+ */
299
+ export function getRipgrepPool() {
300
+ if (!ripgrepPool) {
301
+ ripgrepPool = new ProcessPool({
302
+ maxProcesses: 5,
303
+ processTimeout: 30000,
304
+ maxQueueSize: 100,
305
+ });
306
+ // Cleanup on process exit
307
+ process.on('beforeExit', () => {
308
+ if (ripgrepPool) {
309
+ ripgrepPool.shutdown(true).catch(() => {
310
+ // Ignore errors during shutdown
311
+ });
312
+ }
313
+ });
314
+ }
315
+ return ripgrepPool;
316
+ }
317
+ /**
318
+ * Shutdown the ripgrep pool (for testing)
319
+ */
320
+ export async function shutdownRipgrepPool() {
321
+ if (ripgrepPool) {
322
+ await ripgrepPool.shutdown();
323
+ ripgrepPool = null;
324
+ }
325
+ }
326
+ //# sourceMappingURL=process-pool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process-pool.js","sourceRoot":"","sources":["../../src/utils/process-pool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,KAAK,EAAgB,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AA0CtC;;GAEG;AACH,MAAM,OAAO,WAAY,SAAQ,YAAY;IAC1B,YAAY,CAAS;IACrB,cAAc,CAAS;IACvB,YAAY,CAAS;IAE9B,eAAe,GAAsB,IAAI,GAAG,EAAE,CAAC;IAC/C,SAAS,GAAiB,EAAE,CAAC;IAC7B,YAAY,GAAY,KAAK,CAAC;IAC9B,UAAU,GAAsC,IAAI,GAAG,EAAE,CAAC;IAElE,YAAY,SAA4B,EAAE;QACxC,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,YAAY,IAAI,CAAC,CAAC;QAC7C,IAAI,CAAC,cAAc,GAAG,MAAM,CAAC,cAAc,IAAI,KAAK,CAAC;QACrD,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,YAAY,IAAI,GAAG,CAAC;IACjD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAO,CAAC,OAAgC;QAC5C,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;QACnD,CAAC;QAED,yBAAyB;QACzB,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YAC/C,MAAM,IAAI,KAAK,CAAC,oCAAoC,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC;QAC5E,CAAC;QAED,OAAO,IAAI,OAAO,CAAyB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC7D,MAAM,IAAI,GAAe;gBACvB,OAAO;gBACP,OAAO;gBACP,MAAM;gBACN,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;aACtB,CAAC;YAEF,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC1B,IAAI,CAAC,YAAY,EAAE,CAAC;QACtB,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACK,YAAY;QAClB,iCAAiC;QACjC,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,OAAO;QACT,CAAC;QAED,uCAAuC;QACvC,OACE,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC;YACzB,IAAI,CAAC,eAAe,CAAC,IAAI,GAAG,IAAI,CAAC,YAAY,EAC7C,CAAC;YACD,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;YACpC,IAAI,CAAC,IAAI;gBAAE,MAAM;YAEjB,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,WAAW,CAAC,IAAgB;QACxC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;QAE1C,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;YAChD,OAAO,CAAC,MAAM,CAAC,CAAC;QAClB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACpE,CAAC;gBAAS,CAAC;YACT,6BAA6B;YAC7B,IAAI,CAAC,YAAY,EAAE,CAAC;QACtB,CAAC;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,YAAY,CACxB,OAAgC;QAEhC,OAAO,IAAI,OAAO,CAAyB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC7D,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,EAAE;gBAChD,GAAG,EAAE,OAAO,CAAC,GAAG;aACjB,CAAC,CAAC;YAEH,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAE/B,IAAI,MAAM,GAAG,EAAE,CAAC;YAChB,IAAI,MAAM,GAAG,EAAE,CAAC;YAChB,IAAI,UAAU,GAAG,KAAK,CAAC;YACvB,IAAI,aAAa,GAA0B,IAAI,CAAC;YAEhD,cAAc;YACd,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,IAAI,CAAC,cAAc,CAAC;YACvD,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;gBAChB,aAAa,GAAG,UAAU,CAAC,GAAG,EAAE;oBAC9B,IAAI,CAAC,UAAU,EAAE,CAAC;wBAChB,UAAU,GAAG,IAAI,CAAC;wBAClB,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;wBACzC,MAAM,CAAC,IAAI,KAAK,CAAC,yBAAyB,OAAO,IAAI,CAAC,CAAC,CAAC;oBAC1D,CAAC;gBACH,CAAC,EAAE,OAAO,CAAC,CAAC;YACd,CAAC;YAED,iBAAiB;YACjB,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBAChB,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;oBAC9B,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAC5B,CAAC,CAAC,CAAC;YACL,CAAC;YAED,iBAAiB;YACjB,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBAChB,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;oBAC9B,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAC5B,CAAC,CAAC,CAAC;YACL,CAAC;YAED,sBAAsB;YACtB,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE;gBAChC,IAAI,UAAU,EAAE,CAAC;oBACf,OAAO;gBACT,CAAC;gBACD,UAAU,GAAG,IAAI,CAAC;gBAElB,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;gBAEzC,OAAO,CAAC;oBACN,MAAM;oBACN,MAAM;oBACN,QAAQ,EAAE,IAAI;oBACd,MAAM,EAAE,MAAM;iBACf,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;YAEH,wBAAwB;YACxB,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;gBACzB,IAAI,UAAU,EAAE,CAAC;oBACf,OAAO;gBACT,CAAC;gBACD,UAAU,GAAG,IAAI,CAAC;gBAElB,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;gBACzC,MAAM,CAAC,KAAK,CAAC,CAAC;YAChB,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACK,cAAc,CACpB,IAAkB,EAClB,aAAoC;QAEpC,gBAAgB;QAChB,IAAI,aAAa,EAAE,CAAC;YAClB,YAAY,CAAC,aAAa,CAAC,CAAC;QAC9B,CAAC;QAED,6BAA6B;QAC7B,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC5C,IAAI,SAAS,EAAE,CAAC;YACd,YAAY,CAAC,SAAS,CAAC,CAAC;YACxB,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC/B,CAAC;QAED,qDAAqD;QACrD,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,IAAI,CAAC,MAAM,CAAC,kBAAkB,EAAE,CAAC;QACnC,CAAC;QACD,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,IAAI,CAAC,MAAM,CAAC,kBAAkB,EAAE,CAAC;QACnC,CAAC;QACD,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAE1B,gCAAgC;QAChC,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;YACvD,IAAI,CAAC;gBACH,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBAErB,qDAAqD;gBACrD,MAAM,gBAAgB,GAAG,UAAU,CAAC,GAAG,EAAE;oBACvC,IAAI,CAAC;wBACH,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;4BAC3C,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;wBACvB,CAAC;oBACH,CAAC;oBAAC,MAAM,CAAC;wBACP,6BAA6B;oBAC/B,CAAC;oBACD,uCAAuC;oBACvC,YAAY,CAAC,gBAAgB,CAAC,CAAC;gBACjC,CAAC,EAAE,IAAI,CAAC,CAAC;gBAET,8CAA8C;gBAC9C,yEAAyE;gBACzE,YAAY,CAAC,GAAG,EAAE;oBAChB,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;wBACvD,YAAY,CAAC,gBAAgB,CAAC,CAAC;oBACjC,CAAC;yBAAM,CAAC;wBACN,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,gBAAgB,CAAC,CAAC,CAAC;oBAC1D,CAAC;gBACH,CAAC,CAAC,CAAC;YACL,CAAC;YAAC,MAAM,CAAC;gBACP,gDAAgD;YAClD,CAAC;QACH,CAAC;QAED,yBAAyB;QACzB,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAElC,qBAAqB;QACrB,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE;YAC5B,eAAe,EAAE,IAAI,CAAC,eAAe,CAAC,IAAI;YAC1C,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM;SACnC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,QAAQ;QAMN,OAAO;YACL,eAAe,EAAE,IAAI,CAAC,eAAe,CAAC,IAAI;YAC1C,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM;YAClC,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,YAAY,EAAE,IAAI,CAAC,YAAY;SAChC,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,QAAQ,CAAC,QAAiB,KAAK;QACnC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QAEzB,0BAA0B;QAC1B,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACjC,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;YACpC,IAAI,IAAI,EAAE,CAAC;gBACT,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC,CAAC;YACvD,CAAC;QACH,CAAC;QAED,sDAAsD;QACtD,IAAI,KAAK,EAAE,CAAC;YACV,kCAAkC;YAClC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;gBACxC,IAAI,CAAC;oBACH,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBACvB,CAAC;gBAAC,MAAM,CAAC;oBACP,gBAAgB;gBAClB,CAAC;YACH,CAAC;YACD,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;QAC/B,CAAC;aAAM,CAAC;YACN,uDAAuD;YACvD,MAAM,eAAe,GAAG,KAAK,CAAC,CAAC,aAAa;YAC5C,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAE7B,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;gBACrC,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,GAAG,eAAe,EAAE,CAAC;oBAC7C,iCAAiC;oBACjC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;wBACxC,IAAI,CAAC;4BACH,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;wBACvB,CAAC;wBAAC,MAAM,CAAC;4BACP,gBAAgB;wBAClB,CAAC;oBACH,CAAC;oBACD,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;oBAC7B,MAAM;gBACR,CAAC;gBAED,mCAAmC;gBACnC,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;YAC3D,CAAC;QACH,CAAC;QAED,wBAAwB;QACxB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC;YAC7C,YAAY,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC;QACD,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;QAExB,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACxB,CAAC;IAED;;OAEG;IACH,MAAM;QACJ,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,KAAK,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,CAAC;IACxE,CAAC;IAED;;OAEG;IACH,YAAY;QACV,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,IAAI,IAAI,CAAC,YAAY,CAAC;IACxD,CAAC;CACF;AAED;;GAEG;AACH,IAAI,WAAW,GAAuB,IAAI,CAAC;AAE3C;;GAEG;AACH,MAAM,UAAU,cAAc;IAC5B,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,WAAW,GAAG,IAAI,WAAW,CAAC;YAC5B,YAAY,EAAE,CAAC;YACf,cAAc,EAAE,KAAK;YACrB,YAAY,EAAE,GAAG;SAClB,CAAC,CAAC;QAEH,0BAA0B;QAC1B,OAAO,CAAC,EAAE,CAAC,YAAY,EAAE,GAAG,EAAE;YAC5B,IAAI,WAAW,EAAE,CAAC;gBAChB,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;oBACpC,gCAAgC;gBAClC,CAAC,CAAC,CAAC;YACL,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB;IACvC,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,WAAW,CAAC,QAAQ,EAAE,CAAC;QAC7B,WAAW,GAAG,IAAI,CAAC;IACrB,CAAC;AACH,CAAC"}
@@ -0,0 +1,221 @@
1
+ /**
2
+ * Basic Rate Limiting Utilities (Free Tier) - REQ-SEC-006
3
+ *
4
+ * Implements token bucket algorithm for rate limiting API calls and user actions
5
+ * Prevents API abuse and ensures fair resource usage
6
+ *
7
+ * Free Tier Features:
8
+ * ✅ Token bucket rate limiting
9
+ * ✅ Multi-tier limits (per-second, per-minute)
10
+ * ✅ Per-key limits (per-user, per-IP)
11
+ * ✅ In-memory state (lightweight)
12
+ *
13
+ * Enterprise features (requires @ax-cli/enterprise):
14
+ * - Custom quotas per user/team/project
15
+ * - Cost analytics & forecasting
16
+ * - Budget alerts ($X/day threshold)
17
+ * - Persistent state (survives restarts)
18
+ * - Multi-tenant quota management
19
+ * - Usage optimization tips
20
+ *
21
+ * Security: Protects against:
22
+ * - API abuse (excessive requests)
23
+ * - Resource exhaustion
24
+ * - Denial of service (unintentional)
25
+ */
26
+ export interface RateLimitConfig {
27
+ /**
28
+ * Maximum number of requests allowed in the window
29
+ */
30
+ maxRequests: number;
31
+ /**
32
+ * Time window in milliseconds
33
+ */
34
+ windowMs: number;
35
+ /**
36
+ * Optional: burst allowance (can exceed limit briefly)
37
+ */
38
+ burstAllowance?: number;
39
+ }
40
+ export interface RateLimitResult {
41
+ /**
42
+ * Whether the request is allowed
43
+ */
44
+ allowed: boolean;
45
+ /**
46
+ * Tokens remaining in the current window
47
+ */
48
+ remaining: number;
49
+ /**
50
+ * Time until the rate limit resets (in milliseconds)
51
+ */
52
+ resetIn: number;
53
+ /**
54
+ * Total limit for this rate limiter
55
+ */
56
+ limit: number;
57
+ }
58
+ /**
59
+ * Token Bucket Rate Limiter
60
+ *
61
+ * Uses the token bucket algorithm which allows bursts while maintaining
62
+ * a steady average rate. Tokens are added at a constant rate, and requests
63
+ * consume tokens.
64
+ *
65
+ * @example
66
+ * ```typescript
67
+ * const limiter = new RateLimiter({
68
+ * maxRequests: 60,
69
+ * windowMs: 60000, // 60 requests per minute
70
+ * });
71
+ *
72
+ * const result = limiter.tryAcquire();
73
+ * if (result.allowed) {
74
+ * // Make API call
75
+ * } else {
76
+ * console.log(`Rate limit exceeded. Try again in ${result.resetIn}ms`);
77
+ * }
78
+ * ```
79
+ */
80
+ export declare class RateLimiter {
81
+ private tokens;
82
+ private readonly maxTokens;
83
+ private readonly refillRate;
84
+ private lastRefill;
85
+ private readonly config;
86
+ constructor(config: RateLimitConfig);
87
+ /**
88
+ * Refill tokens based on elapsed time
89
+ */
90
+ private refill;
91
+ /**
92
+ * Try to acquire a token (allow a request)
93
+ *
94
+ * @param cost - Number of tokens to consume (default: 1)
95
+ * @returns Rate limit result indicating if request is allowed
96
+ */
97
+ tryAcquire(cost?: number): RateLimitResult;
98
+ /**
99
+ * Get current state without consuming a token
100
+ */
101
+ getState(): RateLimitResult;
102
+ /**
103
+ * Reset the rate limiter (clear all tokens)
104
+ */
105
+ reset(): void;
106
+ }
107
+ /**
108
+ * Multi-tier Rate Limiter
109
+ *
110
+ * Enforces multiple rate limits simultaneously (e.g., per-second, per-minute, per-hour)
111
+ * Request is only allowed if ALL tiers allow it
112
+ *
113
+ * @example
114
+ * ```typescript
115
+ * const limiter = new MultiTierRateLimiter([
116
+ * { maxRequests: 10, windowMs: 1000 }, // 10/second
117
+ * { maxRequests: 100, windowMs: 60000 }, // 100/minute
118
+ * ]);
119
+ * ```
120
+ */
121
+ export declare class MultiTierRateLimiter {
122
+ private limiters;
123
+ constructor(configs: RateLimitConfig[]);
124
+ /**
125
+ * Try to acquire across all tiers
126
+ * Request is only allowed if ALL tiers allow it
127
+ */
128
+ tryAcquire(cost?: number): RateLimitResult;
129
+ /**
130
+ * Get current state (most restrictive tier)
131
+ */
132
+ getState(): RateLimitResult;
133
+ /**
134
+ * Reset all tiers
135
+ */
136
+ reset(): void;
137
+ }
138
+ /**
139
+ * Keyed Rate Limiter
140
+ *
141
+ * Maintains separate rate limits for different keys (e.g., per-user, per-IP)
142
+ * Automatically cleans up old entries to prevent memory leaks
143
+ *
144
+ * @example
145
+ * ```typescript
146
+ * const limiter = new KeyedRateLimiter({
147
+ * maxRequests: 100,
148
+ * windowMs: 60000,
149
+ * });
150
+ *
151
+ * // Different limits for different users
152
+ * const result = limiter.tryAcquire('user-123');
153
+ * ```
154
+ */
155
+ export declare class KeyedRateLimiter {
156
+ private limiters;
157
+ private readonly config;
158
+ private cleanupTimer;
159
+ private readonly maxKeys;
160
+ constructor(config: RateLimitConfig, maxKeys?: number);
161
+ /**
162
+ * Get or create a rate limiter for the given key
163
+ */
164
+ private getLimiter;
165
+ /**
166
+ * Try to acquire for a specific key
167
+ */
168
+ tryAcquire(key: string, cost?: number): RateLimitResult;
169
+ /**
170
+ * Get state for a specific key
171
+ */
172
+ getState(key: string): RateLimitResult;
173
+ /**
174
+ * Reset a specific key
175
+ */
176
+ reset(key: string): void;
177
+ /**
178
+ * Clean up inactive limiters
179
+ */
180
+ private cleanup;
181
+ /**
182
+ * Dispose of resources
183
+ */
184
+ dispose(): void;
185
+ }
186
+ /**
187
+ * Default rate limit configurations for common use cases
188
+ */
189
+ export declare const DEFAULT_RATE_LIMITS: {
190
+ /**
191
+ * API calls - 60 requests per minute
192
+ */
193
+ readonly API: {
194
+ readonly maxRequests: 60;
195
+ readonly windowMs: number;
196
+ readonly burstAllowance: 10;
197
+ };
198
+ /**
199
+ * LLM API calls - 20 requests per minute (more expensive)
200
+ */
201
+ readonly LLM_API: {
202
+ readonly maxRequests: 20;
203
+ readonly windowMs: number;
204
+ readonly burstAllowance: 5;
205
+ };
206
+ /**
207
+ * User actions - 100 requests per minute
208
+ */
209
+ readonly USER_ACTIONS: {
210
+ readonly maxRequests: 100;
211
+ readonly windowMs: number;
212
+ readonly burstAllowance: 20;
213
+ };
214
+ /**
215
+ * File operations - 50 per minute
216
+ */
217
+ readonly FILE_OPS: {
218
+ readonly maxRequests: 50;
219
+ readonly windowMs: number;
220
+ };
221
+ };