snow-flow 2.0.2 → 2.0.4

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 (173) hide show
  1. package/{.claude/mcp-config.json → .mcp.json} +13 -12
  2. package/.releaserc.json +47 -0
  3. package/README.md +48 -1
  4. package/package.json +1 -1
  5. package/.claude/claude-settings.json +0 -15
  6. package/.claude/commands/analysis/README.md +0 -9
  7. package/.claude/commands/automation/README.md +0 -9
  8. package/.claude/commands/github/README.md +0 -11
  9. package/.claude/commands/helpers/standard-checkpoint-hooks.sh +0 -179
  10. package/.claude/commands/hooks/README.md +0 -11
  11. package/.claude/commands/monitoring/README.md +0 -9
  12. package/.claude/commands/optimization/README.md +0 -9
  13. package/.claude/commands/training/README.md +0 -9
  14. package/.claude/commands/workflows/README.md +0 -9
  15. package/.claude/config.json +0 -36
  16. package/.claude/helpers/github-setup.sh +0 -28
  17. package/.claude/helpers/quick-start.sh +0 -19
  18. package/.claude/helpers/setup-mcp.sh +0 -18
  19. package/.claude/settings.json +0 -114
  20. package/.claude/settings.local.json +0 -33
  21. package/.claude-flow/metrics/agent-metrics.json +0 -1
  22. package/.claude-flow/metrics/performance.json +0 -9
  23. package/.claude-flow/metrics/system-metrics.json +0 -15986
  24. package/.claude-flow/metrics/task-metrics.json +0 -10
  25. package/.roo/README.md +0 -402
  26. package/.roo/mcp-list.txt +0 -257
  27. package/.roo/mcp.json +0 -32
  28. package/.roo/workflows/basic-tdd.json +0 -32
  29. package/.roomodes +0 -201
  30. package/CLAUDE.md +0 -393
  31. package/bin/snow-flow.js +0 -3
  32. package/dist/cli.js.bak +0 -2052
  33. package/dist/config/snow-flow-config.d.ts +0 -1492
  34. package/dist/config/snow-flow-config.js +0 -938
  35. package/scripts/create-env.js +0 -91
  36. package/scripts/postinstall.js +0 -30
  37. package/scripts/register-mcp-servers.js +0 -210
  38. package/scripts/reset-mcp-servers.js +0 -246
  39. package/scripts/setup-mcp.js +0 -106
  40. package/scripts/update-version.js +0 -31
  41. package/src/agents/README.md +0 -192
  42. package/src/agents/base-agent.ts +0 -251
  43. package/src/agents/coordinator.ts +0 -971
  44. package/src/agents/index.ts +0 -18
  45. package/src/agents/queen-403-handler.ts +0 -230
  46. package/src/agents/queen-agent.ts +0 -1399
  47. package/src/agents/script-writer-agent.ts +0 -769
  48. package/src/agents/security-agent.ts +0 -726
  49. package/src/agents/widget-creator-agent.ts +0 -568
  50. package/src/api/error-handling.ts +0 -1758
  51. package/src/api/natural-language-mapper.ts +0 -630
  52. package/src/api/performance-optimizer.ts +0 -891
  53. package/src/api/transaction-manager.ts +0 -754
  54. package/src/cli/deploy-artifact.ts +0 -304
  55. package/src/cli/snow-flow-cli-integration.ts +0 -434
  56. package/src/cli.ts +0 -4455
  57. package/src/cli.ts.bak +0 -5616
  58. package/src/compliance/advanced-compliance-system.ts +0 -1268
  59. package/src/compliance/index.ts +0 -19
  60. package/src/config/snow-flow-config.ts +0 -1019
  61. package/src/documentation/index.ts +0 -16
  62. package/src/documentation/self-documenting-system.ts +0 -1421
  63. package/src/dynamic-version.ts +0 -44
  64. package/src/healing/index.ts +0 -20
  65. package/src/healing/self-healing-system.ts +0 -1435
  66. package/src/health/README.md +0 -161
  67. package/src/health/system-health.ts +0 -995
  68. package/src/index.ts +0 -60
  69. package/src/intelligence/acl-analyzer.ts +0 -377
  70. package/src/intelligence/auto-resolution-engine.ts +0 -643
  71. package/src/intelligence/gap-analysis-engine.ts +0 -488
  72. package/src/intelligence/manual-instructions-generator.ts +0 -744
  73. package/src/intelligence/mcp-coverage-analyzer.ts +0 -708
  74. package/src/intelligence/multi-pass-requirements-analyzer.ts +0 -603
  75. package/src/intelligence/performance-recommendations-engine.ts +0 -1223
  76. package/src/intelligence/requirements-analyzer.ts +0 -1148
  77. package/src/intelligence/task-analyzer.ts +0 -628
  78. package/src/managers/scope-manager.ts +0 -555
  79. package/src/mcp/advanced/servicenow-advanced-features-mcp.ts +0 -16110
  80. package/src/mcp/base-mcp-server.ts +0 -660
  81. package/src/mcp/http-transport-wrapper.ts +0 -426
  82. package/src/mcp/service-discovery-client.ts +0 -312
  83. package/src/mcp/servicenow-automation-mcp-refactored.ts +0 -678
  84. package/src/mcp/servicenow-automation-mcp.ts +0 -838
  85. package/src/mcp/servicenow-deployment-mcp-refactored.ts +0 -1292
  86. package/src/mcp/servicenow-deployment-mcp.ts +0 -7244
  87. package/src/mcp/servicenow-graph-memory-mcp-refactored.ts +0 -721
  88. package/src/mcp/servicenow-graph-memory-mcp.ts +0 -832
  89. package/src/mcp/servicenow-integration-mcp-refactored.ts +0 -655
  90. package/src/mcp/servicenow-integration-mcp.ts +0 -819
  91. package/src/mcp/servicenow-intelligent-mcp-refactored.ts +0 -977
  92. package/src/mcp/servicenow-intelligent-mcp.ts +0 -4638
  93. package/src/mcp/servicenow-mcp-server.ts +0 -728
  94. package/src/mcp/servicenow-memory-mcp.ts +0 -474
  95. package/src/mcp/servicenow-operations-mcp-refactored.ts +0 -1995
  96. package/src/mcp/servicenow-operations-mcp.ts +0 -3384
  97. package/src/mcp/servicenow-platform-development-mcp-refactored.ts +0 -611
  98. package/src/mcp/servicenow-platform-development-mcp.ts +0 -970
  99. package/src/mcp/servicenow-progressive-indexer.ts +0 -370
  100. package/src/mcp/servicenow-reporting-analytics-mcp-refactored.ts +0 -695
  101. package/src/mcp/servicenow-reporting-analytics-mcp.ts +0 -1123
  102. package/src/mcp/servicenow-security-compliance-mcp-refactored.ts +0 -642
  103. package/src/mcp/servicenow-security-compliance-mcp.ts +0 -1157
  104. package/src/mcp/servicenow-update-set-mcp-refactored.ts +0 -751
  105. package/src/mcp/servicenow-update-set-mcp.ts +0 -811
  106. package/src/mcp/shared/agent-context-provider.ts +0 -365
  107. package/src/mcp/shared/base-mcp-server.ts +0 -2463
  108. package/src/mcp/shared/mcp-memory-manager.ts +0 -540
  109. package/src/mcp/shared/mcp-resource-manager.ts +0 -367
  110. package/src/mcp/snow-flow-mcp.ts +0 -911
  111. package/src/mcp/start-all-mcp-servers.ts +0 -102
  112. package/src/mcp/start-servicenow-mcp.ts +0 -67
  113. package/src/monitoring/enhanced-monitoring-system.ts +0 -1345
  114. package/src/monitoring/performance-tracker.ts +0 -777
  115. package/src/optimization/cost-optimization-engine.ts +0 -1125
  116. package/src/optimization/index.ts +0 -10
  117. package/src/queen/README.md +0 -403
  118. package/src/queen/agent-factory.ts +0 -574
  119. package/src/queen/index.ts +0 -94
  120. package/src/queen/mcp-execution-bridge.ts +0 -681
  121. package/src/queen/neural-learning.ts +0 -319
  122. package/src/queen/parallel-agent-engine.ts +0 -848
  123. package/src/queen/queen-memory-system.ts +0 -490
  124. package/src/queen/queen-memory.ts +0 -456
  125. package/src/queen/servicenow-queen.ts +0 -1029
  126. package/src/queen/types.ts +0 -87
  127. package/src/rollback/smart-rollback-system.ts +0 -866
  128. package/src/schemas/deployment.schema.json +0 -58
  129. package/src/schemas/flow.schema.json +0 -79
  130. package/src/schemas/widget.schema.json +0 -72
  131. package/src/snow-flow-system.ts +0 -541
  132. package/src/sparc/sparc-help.ts +0 -49
  133. package/src/sparc/team-sparc.ts +0 -88
  134. package/src/strategies/global-scope-strategy.ts +0 -736
  135. package/src/templates/base/application.template.json +0 -45
  136. package/src/templates/base/business_rule.template.json +0 -33
  137. package/src/templates/base/script_include.template.json +0 -18
  138. package/src/templates/base/table.template.json +0 -64
  139. package/src/templates/base/widget.template.json +0 -25
  140. package/src/templates/patterns/composite.incident-management.template.json +0 -140
  141. package/src/templates/patterns/widget.dashboard.template.json +0 -238
  142. package/src/templates/patterns/widget.datatable.template.json +0 -292
  143. package/src/testing/integration-test-suite.ts +0 -1276
  144. package/src/types/index.ts +0 -183
  145. package/src/types/neo4j-driver.d.ts +0 -23
  146. package/src/types/servicenow.types.ts +0 -307
  147. package/src/types/snow-flow.types.ts +0 -186
  148. package/src/types/todo.types.ts +0 -70
  149. package/src/utils/action-type-cache.ts +0 -286
  150. package/src/utils/agent-detector.ts +0 -573
  151. package/src/utils/artifact-tracker.ts +0 -379
  152. package/src/utils/dependency-detector.ts +0 -233
  153. package/src/utils/deployment-metadata-handler.ts +0 -518
  154. package/src/utils/error-recovery.ts +0 -680
  155. package/src/utils/logger.ts +0 -60
  156. package/src/utils/mcp-auth-middleware.ts +0 -262
  157. package/src/utils/mcp-config-manager.ts +0 -270
  158. package/src/utils/mcp-server-manager.ts +0 -446
  159. package/src/utils/mcp-tool-registry.ts +0 -298
  160. package/src/utils/migrate-snow-flow.ts +0 -98
  161. package/src/utils/oauth-html-templates.ts +0 -188
  162. package/src/utils/scope-utils.ts +0 -443
  163. package/src/utils/servicenow-client.ts +0 -3321
  164. package/src/utils/servicenow-id-generator.ts +0 -181
  165. package/src/utils/snow-memory-manager.ts +0 -605
  166. package/src/utils/snow-oauth.ts +0 -797
  167. package/src/utils/template-engine.ts +0 -463
  168. package/src/utils/theme-manager.ts +0 -295
  169. package/src/utils/unified-auth-store.ts +0 -222
  170. package/src/utils/update-set-importer.ts +0 -422
  171. package/src/utils/update-set-xml-packager.ts +0 -371
  172. package/src/utils/widget-template-generator.ts +0 -1744
  173. package/src/version.ts +0 -1950
@@ -1,891 +0,0 @@
1
- /**
2
- * Performance Optimization and Caching Strategy
3
- * Advanced caching and performance optimization for ServiceNow API calls
4
- */
5
-
6
- import { ServiceNowClient } from '../utils/servicenow-client.js';
7
- import { Logger } from '../utils/logger.js';
8
- import fs from 'fs';
9
- import path from 'path';
10
- import os from 'os';
11
-
12
- export interface CacheEntry<T> {
13
- key: string;
14
- value: T;
15
- timestamp: Date;
16
- ttl: number;
17
- access_count: number;
18
- last_accessed: Date;
19
- tags: string[];
20
- size: number;
21
- }
22
-
23
- export interface CacheConfig {
24
- max_size: number;
25
- default_ttl: number;
26
- cleanup_interval: number;
27
- persistence_enabled: boolean;
28
- compression_enabled: boolean;
29
- }
30
-
31
- export interface PerformanceMetrics {
32
- cache_hit_rate: number;
33
- cache_miss_rate: number;
34
- average_response_time: number;
35
- api_call_count: number;
36
- cache_size: number;
37
- memory_usage: number;
38
- bandwidth_saved: number;
39
- }
40
-
41
- export interface OptimizationHint {
42
- type: 'batch' | 'cache' | 'compress' | 'parallel' | 'lazy';
43
- description: string;
44
- estimated_improvement: number;
45
- implementation_complexity: 'low' | 'medium' | 'high';
46
- }
47
-
48
- export interface BatchRequest {
49
- id: string;
50
- requests: APIRequest[];
51
- priority: 'high' | 'medium' | 'low';
52
- timeout: number;
53
- retry_count: number;
54
- }
55
-
56
- export interface APIRequest {
57
- id: string;
58
- method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
59
- url: string;
60
- data?: any;
61
- headers?: Record<string, string>;
62
- cache_key?: string;
63
- cacheable: boolean;
64
- priority: number;
65
- }
66
-
67
- export interface APIResponse<T> {
68
- success: boolean;
69
- data?: T;
70
- error?: string;
71
- cached: boolean;
72
- response_time: number;
73
- cache_hit: boolean;
74
- }
75
-
76
- export class PerformanceOptimizer {
77
- private client: ServiceNowClient;
78
- private logger: Logger;
79
- private cache: Map<string, CacheEntry<any>> = new Map();
80
- private config: CacheConfig;
81
- private metrics: PerformanceMetrics;
82
- private cleanupTimer?: NodeJS.Timeout;
83
- private batchQueue: Map<string, BatchRequest> = new Map();
84
- private rateLimiter: Map<string, number> = new Map();
85
- private connectionPool: Map<string, any> = new Map();
86
-
87
- constructor(client: ServiceNowClient, config?: Partial<CacheConfig>) {
88
- this.client = client;
89
- this.logger = new Logger('PerformanceOptimizer');
90
-
91
- this.config = {
92
- max_size: 1000,
93
- default_ttl: 300000, // 5 minutes
94
- cleanup_interval: 60000, // 1 minute
95
- persistence_enabled: true,
96
- compression_enabled: true,
97
- ...config
98
- };
99
-
100
- this.metrics = {
101
- cache_hit_rate: 0,
102
- cache_miss_rate: 0,
103
- average_response_time: 0,
104
- api_call_count: 0,
105
- cache_size: 0,
106
- memory_usage: 0,
107
- bandwidth_saved: 0
108
- };
109
-
110
- this.startCleanupTimer();
111
- this.loadPersistedCache();
112
- }
113
-
114
- /**
115
- * Optimized API call with caching and performance monitoring
116
- */
117
- async optimizedAPICall<T>(request: APIRequest): Promise<APIResponse<T>> {
118
- const startTime = Date.now();
119
- const cacheKey = request.cache_key || this.generateCacheKey(request);
120
-
121
- // Check cache first
122
- if (request.cacheable) {
123
- const cached = this.getFromCache<T>(cacheKey);
124
- if (cached) {
125
- const responseTime = Date.now() - startTime;
126
- this.updateMetrics(true, responseTime);
127
-
128
- return {
129
- success: true,
130
- data: cached,
131
- cached: true,
132
- response_time: responseTime,
133
- cache_hit: true
134
- };
135
- }
136
- }
137
-
138
- // Apply rate limiting
139
- if (this.isRateLimited(request.url)) {
140
- await this.waitForRateLimit(request.url);
141
- }
142
-
143
- try {
144
- // Execute API call
145
- const response = await this.executeAPICall<T>(request);
146
- const responseTime = Date.now() - startTime;
147
-
148
- // Cache successful responses
149
- if (request.cacheable && response.success && response.data) {
150
- this.setInCache(cacheKey, response.data, {
151
- ttl: this.getTTLForRequest(request),
152
- tags: this.getTagsForRequest(request)
153
- });
154
- }
155
-
156
- this.updateMetrics(false, responseTime);
157
-
158
- return {
159
- ...response,
160
- cached: false,
161
- response_time: responseTime,
162
- cache_hit: false
163
- };
164
-
165
- } catch (error) {
166
- const responseTime = Date.now() - startTime;
167
- this.updateMetrics(false, responseTime);
168
-
169
- return {
170
- success: false,
171
- error: error instanceof Error ? error.message : String(error),
172
- cached: false,
173
- response_time: responseTime,
174
- cache_hit: false
175
- };
176
- }
177
- }
178
-
179
- /**
180
- * Batch multiple API requests for better performance
181
- */
182
- async batchAPIRequests<T>(requests: APIRequest[]): Promise<APIResponse<T>[]> {
183
- const batchId = `batch_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
184
- const batchRequest: BatchRequest = {
185
- id: batchId,
186
- requests: requests.sort((a, b) => b.priority - a.priority),
187
- priority: 'medium',
188
- timeout: 30000,
189
- retry_count: 0
190
- };
191
-
192
- this.batchQueue.set(batchId, batchRequest);
193
-
194
- try {
195
- // Group requests by type for optimization
196
- const groupedRequests = this.groupRequestsByType(requests);
197
- const results: APIResponse<T>[] = [];
198
-
199
- // Execute groups in parallel
200
- const groupPromises = Object.entries(groupedRequests).map(async ([type, groupRequests]) => {
201
- return await this.executeBatchGroup<T>(groupRequests, type);
202
- });
203
-
204
- const groupResults = await Promise.all(groupPromises);
205
-
206
- // Flatten results
207
- for (const groupResult of groupResults) {
208
- results.push(...groupResult);
209
- }
210
-
211
- return results;
212
-
213
- } finally {
214
- this.batchQueue.delete(batchId);
215
- }
216
- }
217
-
218
- /**
219
- * Preload commonly accessed data
220
- */
221
- async preloadData(preloadConfig: {
222
- action_types: boolean;
223
- trigger_types: boolean;
224
- flow_templates: boolean;
225
- user_preferences: boolean;
226
- }): Promise<void> {
227
- const preloadTasks: Promise<void>[] = [];
228
-
229
- if (preloadConfig.action_types) {
230
- preloadTasks.push(this.preloadActionTypes());
231
- }
232
-
233
- if (preloadConfig.trigger_types) {
234
- preloadTasks.push(this.preloadTriggerTypes());
235
- }
236
-
237
- if (preloadConfig.flow_templates) {
238
- preloadTasks.push(this.preloadFlowTemplates());
239
- }
240
-
241
- if (preloadConfig.user_preferences) {
242
- preloadTasks.push(this.preloadUserPreferences());
243
- }
244
-
245
- await Promise.all(preloadTasks);
246
- this.logger.info('Data preloading completed');
247
- }
248
-
249
- /**
250
- * Analyze performance and provide optimization suggestions
251
- */
252
- analyzePerformance(): {
253
- metrics: PerformanceMetrics;
254
- bottlenecks: string[];
255
- optimization_hints: OptimizationHint[];
256
- } {
257
- const bottlenecks: string[] = [];
258
- const optimizationHints: OptimizationHint[] = [];
259
-
260
- // Analyze cache hit rate
261
- if (this.metrics.cache_hit_rate < 0.5) {
262
- bottlenecks.push('Low cache hit rate');
263
- optimizationHints.push({
264
- type: 'cache',
265
- description: 'Increase cache TTL for frequently accessed data',
266
- estimated_improvement: 0.3,
267
- implementation_complexity: 'low'
268
- });
269
- }
270
-
271
- // Analyze response times
272
- if (this.metrics.average_response_time > 2000) {
273
- bottlenecks.push('High response times');
274
- optimizationHints.push({
275
- type: 'parallel',
276
- description: 'Implement parallel processing for independent requests',
277
- estimated_improvement: 0.5,
278
- implementation_complexity: 'medium'
279
- });
280
- }
281
-
282
- // Analyze cache size
283
- if (this.cache.size > this.config.max_size * 0.8) {
284
- bottlenecks.push('Cache nearing capacity');
285
- optimizationHints.push({
286
- type: 'compress',
287
- description: 'Enable compression for cached data',
288
- estimated_improvement: 0.4,
289
- implementation_complexity: 'medium'
290
- });
291
- }
292
-
293
- // Analyze API call patterns
294
- const batchableRequests = this.identifyBatchableRequests();
295
- if (batchableRequests.length > 0) {
296
- optimizationHints.push({
297
- type: 'batch',
298
- description: `Batch ${batchableRequests.length} similar requests`,
299
- estimated_improvement: 0.6,
300
- implementation_complexity: 'high'
301
- });
302
- }
303
-
304
- return {
305
- metrics: this.metrics,
306
- bottlenecks,
307
- optimization_hints: optimizationHints
308
- };
309
- }
310
-
311
- /**
312
- * Implement adaptive caching based on usage patterns
313
- */
314
- optimizeCaching(): void {
315
- const cacheAnalysis = this.analyzeCacheUsage();
316
-
317
- // Adjust TTL based on access patterns
318
- for (const [key, entry] of this.cache) {
319
- const accessFrequency = entry.access_count / (Date.now() - entry.timestamp.getTime());
320
-
321
- if (accessFrequency > 0.01) { // Frequently accessed
322
- entry.ttl = this.config.default_ttl * 2;
323
- } else if (accessFrequency < 0.001) { // Rarely accessed
324
- entry.ttl = this.config.default_ttl * 0.5;
325
- }
326
- }
327
-
328
- // Implement cache warming for predicted requests
329
- this.warmCache(cacheAnalysis.predicted_requests);
330
- }
331
-
332
- /**
333
- * Get from cache with LRU eviction
334
- */
335
- private getFromCache<T>(key: string): T | null {
336
- const entry = this.cache.get(key);
337
- if (!entry) {
338
- return null;
339
- }
340
-
341
- // Check if expired
342
- if (Date.now() - entry.timestamp.getTime() > entry.ttl) {
343
- this.cache.delete(key);
344
- return null;
345
- }
346
-
347
- // Update access statistics
348
- entry.access_count++;
349
- entry.last_accessed = new Date();
350
-
351
- return entry.value;
352
- }
353
-
354
- /**
355
- * Set in cache with size management
356
- */
357
- private setInCache<T>(key: string, value: T, options: {
358
- ttl?: number;
359
- tags?: string[];
360
- } = {}): void {
361
- // Check if cache is full
362
- if (this.cache.size >= this.config.max_size) {
363
- this.evictLeastRecent();
364
- }
365
-
366
- const entry: CacheEntry<T> = {
367
- key,
368
- value,
369
- timestamp: new Date(),
370
- ttl: options.ttl || this.config.default_ttl,
371
- access_count: 1,
372
- last_accessed: new Date(),
373
- tags: options.tags || [],
374
- size: this.estimateSize(value)
375
- };
376
-
377
- this.cache.set(key, entry);
378
- this.updateCacheMetrics();
379
- }
380
-
381
- /**
382
- * Execute API call with connection pooling
383
- */
384
- private async executeAPICall<T>(request: APIRequest): Promise<APIResponse<T>> {
385
- const connection = this.getPooledConnection(request.url);
386
- const startTime = Date.now();
387
-
388
- try {
389
- let response;
390
-
391
- switch (request.method) {
392
- case 'GET':
393
- response = await this.client.getRecords(this.extractTable(request.url), request.data);
394
- break;
395
- case 'POST':
396
- response = await this.client.createRecord(this.extractTable(request.url), request.data);
397
- break;
398
- case 'PUT':
399
- case 'PATCH':
400
- response = await this.client.updateRecord(this.extractTable(request.url), request.data.sys_id, request.data);
401
- break;
402
- case 'DELETE':
403
- response = await this.client.deleteRecord(this.extractTable(request.url), request.data.sys_id);
404
- break;
405
- default:
406
- throw new Error(`Unsupported method: ${request.method}`);
407
- }
408
-
409
- return {
410
- success: response.success,
411
- data: response.data,
412
- error: response.error,
413
- cached: false,
414
- response_time: Date.now() - startTime,
415
- cache_hit: false
416
- };
417
-
418
- } finally {
419
- this.returnPooledConnection(request.url, connection);
420
- }
421
- }
422
-
423
- /**
424
- * Group requests by type for batch processing
425
- */
426
- private groupRequestsByType(requests: APIRequest[]): Record<string, APIRequest[]> {
427
- const groups: Record<string, APIRequest[]> = {};
428
-
429
- for (const request of requests) {
430
- const type = `${request.method}_${this.extractTable(request.url)}`;
431
- if (!groups[type]) {
432
- groups[type] = [];
433
- }
434
- groups[type].push(request);
435
- }
436
-
437
- return groups;
438
- }
439
-
440
- /**
441
- * Execute batch group with parallel processing
442
- */
443
- private async executeBatchGroup<T>(requests: APIRequest[], type: string): Promise<APIResponse<T>[]> {
444
- const batchSize = this.getBatchSizeForType(type);
445
- const results: APIResponse<T>[] = [];
446
-
447
- // Process requests in batches
448
- for (let i = 0; i < requests.length; i += batchSize) {
449
- const batch = requests.slice(i, i + batchSize);
450
- const batchPromises = batch.map(request => this.optimizedAPICall<T>(request));
451
-
452
- const batchResults = await Promise.all(batchPromises);
453
- results.push(...batchResults);
454
- }
455
-
456
- return results;
457
- }
458
-
459
- /**
460
- * Preload action types
461
- */
462
- private async preloadActionTypes(): Promise<void> {
463
- const request: APIRequest = {
464
- id: 'preload_action_types',
465
- method: 'GET',
466
- url: '/api/now/table/sys_hub_action_type_base',
467
- cacheable: true,
468
- priority: 1
469
- };
470
-
471
- await this.optimizedAPICall(request);
472
- }
473
-
474
- /**
475
- * Preload trigger types
476
- */
477
- private async preloadTriggerTypes(): Promise<void> {
478
- const request: APIRequest = {
479
- id: 'preload_trigger_types',
480
- method: 'GET',
481
- url: '/api/now/table/sys_hub_trigger_type',
482
- cacheable: true,
483
- priority: 1
484
- };
485
-
486
- await this.optimizedAPICall(request);
487
- }
488
-
489
- /**
490
- * Preload flow templates
491
- */
492
- private async preloadFlowTemplates(): Promise<void> {
493
- const request: APIRequest = {
494
- id: 'preload_flow_templates',
495
- method: 'GET',
496
- url: '/api/now/table/sys_hub_flow_template',
497
- cacheable: true,
498
- priority: 1
499
- };
500
-
501
- await this.optimizedAPICall(request);
502
- }
503
-
504
- /**
505
- * Preload user preferences
506
- */
507
- private async preloadUserPreferences(): Promise<void> {
508
- const request: APIRequest = {
509
- id: 'preload_user_preferences',
510
- method: 'GET',
511
- url: '/api/now/table/sys_user_preference',
512
- cacheable: true,
513
- priority: 1
514
- };
515
-
516
- await this.optimizedAPICall(request);
517
- }
518
-
519
- /**
520
- * Analyze cache usage patterns
521
- */
522
- private analyzeCacheUsage(): {
523
- most_accessed: string[];
524
- least_accessed: string[];
525
- predicted_requests: string[];
526
- } {
527
- const sortedEntries = Array.from(this.cache.entries())
528
- .sort((a, b) => b[1].access_count - a[1].access_count);
529
-
530
- const mostAccessed = sortedEntries.slice(0, 10).map(([key]) => key);
531
- const leastAccessed = sortedEntries.slice(-10).map(([key]) => key);
532
-
533
- // Predict likely requests based on patterns
534
- const predictedRequests = this.predictLikelyRequests(mostAccessed);
535
-
536
- return {
537
- most_accessed: mostAccessed,
538
- least_accessed: leastAccessed,
539
- predicted_requests: predictedRequests
540
- };
541
- }
542
-
543
- /**
544
- * Warm cache with predicted requests
545
- */
546
- private async warmCache(predictedRequests: string[]): Promise<void> {
547
- const warmingTasks = predictedRequests.map(async (cacheKey) => {
548
- if (!this.cache.has(cacheKey)) {
549
- const request = this.reconstructRequestFromCacheKey(cacheKey);
550
- if (request) {
551
- await this.optimizedAPICall(request);
552
- }
553
- }
554
- });
555
-
556
- await Promise.all(warmingTasks);
557
- }
558
-
559
- /**
560
- * Evict least recently used entries
561
- */
562
- private evictLeastRecent(): void {
563
- const entries = Array.from(this.cache.entries())
564
- .sort((a, b) => a[1].last_accessed.getTime() - b[1].last_accessed.getTime());
565
-
566
- const entriesToEvict = entries.slice(0, Math.ceil(this.config.max_size * 0.1));
567
-
568
- for (const [key] of entriesToEvict) {
569
- this.cache.delete(key);
570
- }
571
- }
572
-
573
- /**
574
- * Update performance metrics
575
- */
576
- private updateMetrics(cacheHit: boolean, responseTime: number): void {
577
- this.metrics.api_call_count++;
578
-
579
- if (cacheHit) {
580
- this.metrics.cache_hit_rate = (this.metrics.cache_hit_rate * (this.metrics.api_call_count - 1) + 1) / this.metrics.api_call_count;
581
- } else {
582
- this.metrics.cache_miss_rate = (this.metrics.cache_miss_rate * (this.metrics.api_call_count - 1) + 1) / this.metrics.api_call_count;
583
- }
584
-
585
- this.metrics.average_response_time = (this.metrics.average_response_time * (this.metrics.api_call_count - 1) + responseTime) / this.metrics.api_call_count;
586
- }
587
-
588
- /**
589
- * Update cache metrics
590
- */
591
- private updateCacheMetrics(): void {
592
- this.metrics.cache_size = this.cache.size;
593
- this.metrics.memory_usage = Array.from(this.cache.values())
594
- .reduce((total, entry) => total + entry.size, 0);
595
- }
596
-
597
- /**
598
- * Generate cache key for request
599
- */
600
- private generateCacheKey(request: APIRequest): string {
601
- const keyParts = [
602
- request.method,
603
- request.url,
604
- JSON.stringify(request.data),
605
- JSON.stringify(request.headers)
606
- ];
607
-
608
- return Buffer.from(keyParts.join('|')).toString('base64');
609
- }
610
-
611
- /**
612
- * Get TTL for specific request type
613
- */
614
- private getTTLForRequest(request: APIRequest): number {
615
- const url = request.url.toLowerCase();
616
-
617
- if (url.includes('action_type') || url.includes('trigger_type')) {
618
- return 3600000; // 1 hour for metadata
619
- }
620
-
621
- if (url.includes('flow_template')) {
622
- return 1800000; // 30 minutes for templates
623
- }
624
-
625
- if (url.includes('user_preference')) {
626
- return 600000; // 10 minutes for preferences
627
- }
628
-
629
- return this.config.default_ttl;
630
- }
631
-
632
- /**
633
- * Get tags for request
634
- */
635
- private getTagsForRequest(request: APIRequest): string[] {
636
- const tags: string[] = [];
637
- const url = request.url.toLowerCase();
638
-
639
- if (url.includes('action_type')) tags.push('action_type');
640
- if (url.includes('trigger_type')) tags.push('trigger_type');
641
- if (url.includes('flow')) tags.push('flow');
642
- if (url.includes('user')) tags.push('user');
643
-
644
- return tags;
645
- }
646
-
647
- /**
648
- * Estimate size of cached value
649
- */
650
- private estimateSize(value: any): number {
651
- return JSON.stringify(value).length * 2; // Rough estimate
652
- }
653
-
654
- /**
655
- * Extract table name from URL
656
- */
657
- private extractTable(url: string): string {
658
- const match = url.match(/\/table\/([^\/\?]+)/);
659
- return match ? match[1] : 'unknown';
660
- }
661
-
662
- /**
663
- * Get batch size for request type
664
- */
665
- private getBatchSizeForType(type: string): number {
666
- if (type.includes('GET')) return 10;
667
- if (type.includes('POST')) return 5;
668
- if (type.includes('PUT') || type.includes('PATCH')) return 3;
669
- if (type.includes('DELETE')) return 3;
670
- return 5;
671
- }
672
-
673
- /**
674
- * Check if request is rate limited
675
- */
676
- private isRateLimited(url: string): boolean {
677
- const domain = this.extractDomain(url);
678
- const lastRequest = this.rateLimiter.get(domain);
679
-
680
- if (!lastRequest) return false;
681
-
682
- const timeSinceLastRequest = Date.now() - lastRequest;
683
- return timeSinceLastRequest < 100; // 100ms rate limit
684
- }
685
-
686
- /**
687
- * Wait for rate limit to clear
688
- */
689
- private async waitForRateLimit(url: string): Promise<void> {
690
- const domain = this.extractDomain(url);
691
- const lastRequest = this.rateLimiter.get(domain);
692
-
693
- if (lastRequest) {
694
- const waitTime = 100 - (Date.now() - lastRequest);
695
- if (waitTime > 0) {
696
- await new Promise(resolve => setTimeout(resolve, waitTime));
697
- }
698
- }
699
-
700
- this.rateLimiter.set(domain, Date.now());
701
- }
702
-
703
- /**
704
- * Extract domain from URL
705
- */
706
- private extractDomain(url: string): string {
707
- try {
708
- return new URL(url).hostname;
709
- } catch {
710
- return 'default';
711
- }
712
- }
713
-
714
- /**
715
- * Get pooled connection
716
- */
717
- private getPooledConnection(url: string): any {
718
- const domain = this.extractDomain(url);
719
- return this.connectionPool.get(domain) || {};
720
- }
721
-
722
- /**
723
- * Return pooled connection
724
- */
725
- private returnPooledConnection(url: string, connection: any): void {
726
- const domain = this.extractDomain(url);
727
- this.connectionPool.set(domain, connection);
728
- }
729
-
730
- /**
731
- * Identify batchable requests
732
- */
733
- private identifyBatchableRequests(): string[] {
734
- // Implementation would analyze request patterns
735
- return [];
736
- }
737
-
738
- /**
739
- * Predict likely requests based on patterns
740
- */
741
- private predictLikelyRequests(mostAccessed: string[]): string[] {
742
- // Implementation would use ML or pattern analysis
743
- return mostAccessed.slice(0, 5);
744
- }
745
-
746
- /**
747
- * Reconstruct request from cache key
748
- */
749
- private reconstructRequestFromCacheKey(cacheKey: string): APIRequest | null {
750
- try {
751
- const decoded = Buffer.from(cacheKey, 'base64').toString();
752
- const [method, url, data, headers] = decoded.split('|');
753
-
754
- return {
755
- id: 'reconstructed',
756
- method: method as any,
757
- url,
758
- data: JSON.parse(data),
759
- headers: JSON.parse(headers),
760
- cacheable: true,
761
- priority: 1
762
- };
763
- } catch {
764
- return null;
765
- }
766
- }
767
-
768
- /**
769
- * Start cleanup timer
770
- */
771
- private startCleanupTimer(): void {
772
- this.cleanupTimer = setInterval(() => {
773
- this.cleanupExpiredEntries();
774
- }, this.config.cleanup_interval);
775
- }
776
-
777
- /**
778
- * Cleanup expired entries
779
- */
780
- private cleanupExpiredEntries(): void {
781
- const now = Date.now();
782
- const expiredKeys: string[] = [];
783
-
784
- for (const [key, entry] of this.cache) {
785
- if (now - entry.timestamp.getTime() > entry.ttl) {
786
- expiredKeys.push(key);
787
- }
788
- }
789
-
790
- for (const key of expiredKeys) {
791
- this.cache.delete(key);
792
- }
793
-
794
- if (expiredKeys.length > 0) {
795
- this.logger.debug(`Cleaned up ${expiredKeys.length} expired cache entries`);
796
- this.updateCacheMetrics();
797
- }
798
- }
799
-
800
- /**
801
- * Load persisted cache
802
- */
803
- private loadPersistedCache(): void {
804
- if (!this.config.persistence_enabled) return;
805
-
806
- try {
807
- const cacheFile = path.join(process.env.SNOW_FLOW_HOME || path.join(os.homedir(), '.snow-flow'), 'cache', 'performance_cache.json');
808
-
809
- if (fs.existsSync(cacheFile)) {
810
- const cacheData = JSON.parse(fs.readFileSync(cacheFile, 'utf-8'));
811
-
812
- for (const [key, entry] of Object.entries(cacheData)) {
813
- this.cache.set(key, {
814
- ...entry as CacheEntry<any>,
815
- timestamp: new Date((entry as any).timestamp),
816
- last_accessed: new Date((entry as any).last_accessed)
817
- });
818
- }
819
-
820
- this.logger.info(`Loaded ${this.cache.size} entries from persisted cache`);
821
- }
822
- } catch (error) {
823
- this.logger.warn('Failed to load persisted cache:', error);
824
- }
825
- }
826
-
827
- /**
828
- * Save cache to disk
829
- */
830
- saveCacheToDisk(): void {
831
- if (!this.config.persistence_enabled) return;
832
-
833
- try {
834
- const cacheDir = path.join(process.env.SNOW_FLOW_HOME || path.join(os.homedir(), '.snow-flow'), 'cache');
835
- if (!fs.existsSync(cacheDir)) {
836
- fs.mkdirSync(cacheDir, { recursive: true });
837
- }
838
-
839
- const cacheFile = path.join(cacheDir, 'performance_cache.json');
840
- const cacheData = Object.fromEntries(this.cache.entries());
841
-
842
- fs.writeFileSync(cacheFile, JSON.stringify(cacheData, null, 2));
843
- this.logger.info(`Saved ${this.cache.size} entries to persisted cache`);
844
- } catch (error) {
845
- this.logger.warn('Failed to save cache to disk:', error);
846
- }
847
- }
848
-
849
- /**
850
- * Clear cache
851
- */
852
- clearCache(tags?: string[]): void {
853
- if (!tags || tags.length === 0) {
854
- this.cache.clear();
855
- this.logger.info('Cleared all cache entries');
856
- } else {
857
- const keysToDelete: string[] = [];
858
-
859
- for (const [key, entry] of this.cache) {
860
- if (entry.tags.some(tag => tags.includes(tag))) {
861
- keysToDelete.push(key);
862
- }
863
- }
864
-
865
- for (const key of keysToDelete) {
866
- this.cache.delete(key);
867
- }
868
-
869
- this.logger.info(`Cleared ${keysToDelete.length} cache entries with tags: ${tags.join(', ')}`);
870
- }
871
-
872
- this.updateCacheMetrics();
873
- }
874
-
875
- /**
876
- * Destroy optimizer and cleanup
877
- */
878
- destroy(): void {
879
- if (this.cleanupTimer) {
880
- clearInterval(this.cleanupTimer);
881
- }
882
-
883
- this.saveCacheToDisk();
884
- this.cache.clear();
885
- this.batchQueue.clear();
886
- this.rateLimiter.clear();
887
- this.connectionPool.clear();
888
-
889
- this.logger.info('Performance optimizer destroyed');
890
- }
891
- }