claude-flow 2.5.0-alpha.139 → 2.7.0-alpha

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 (171) hide show
  1. package/.claude/agents/reasoning/README.md +171 -0
  2. package/.claude/agents/reasoning/agent.md +816 -0
  3. package/.claude/agents/reasoning/example-reasoning-agent-template.md +362 -0
  4. package/.claude/agents/reasoning/goal-planner.md +73 -0
  5. package/.claude/settings.json +2 -1
  6. package/.claude/sparc-modes.json +108 -0
  7. package/README.md +45 -55
  8. package/bin/claude-flow +1 -1
  9. package/dist/src/cli/command-registry.js +70 -6
  10. package/dist/src/cli/command-registry.js.map +1 -1
  11. package/dist/src/cli/commands/hive-mind/pause.js +2 -9
  12. package/dist/src/cli/commands/hive-mind/pause.js.map +1 -1
  13. package/dist/src/cli/commands/index.js +1 -114
  14. package/dist/src/cli/commands/index.js.map +1 -1
  15. package/dist/src/cli/commands/swarm-spawn.js +5 -33
  16. package/dist/src/cli/commands/swarm-spawn.js.map +1 -1
  17. package/dist/src/cli/help-formatter.js +0 -3
  18. package/dist/src/cli/help-formatter.js.map +1 -1
  19. package/dist/src/cli/help-text.js +69 -7
  20. package/dist/src/cli/help-text.js.map +1 -1
  21. package/dist/src/cli/simple-cli.js +182 -172
  22. package/dist/src/cli/simple-cli.js.map +1 -1
  23. package/dist/src/cli/simple-commands/agent-booster.js +415 -0
  24. package/dist/src/cli/simple-commands/agent-booster.js.map +1 -0
  25. package/dist/src/cli/simple-commands/agent.js +856 -13
  26. package/dist/src/cli/simple-commands/agent.js.map +1 -1
  27. package/dist/src/cli/simple-commands/env-template.js +180 -0
  28. package/dist/src/cli/simple-commands/env-template.js.map +1 -0
  29. package/dist/src/cli/simple-commands/hooks.js +233 -0
  30. package/dist/src/cli/simple-commands/hooks.js.map +1 -1
  31. package/dist/src/cli/simple-commands/init/help.js +23 -0
  32. package/dist/src/cli/simple-commands/init/help.js.map +1 -1
  33. package/dist/src/cli/simple-commands/init/index.js +63 -0
  34. package/dist/src/cli/simple-commands/init/index.js.map +1 -1
  35. package/dist/src/cli/simple-commands/memory.js +307 -16
  36. package/dist/src/cli/simple-commands/memory.js.map +1 -1
  37. package/dist/src/cli/simple-commands/proxy.js +304 -0
  38. package/dist/src/cli/simple-commands/proxy.js.map +1 -0
  39. package/dist/src/cli/simple-commands/sparc.js +16 -19
  40. package/dist/src/cli/simple-commands/sparc.js.map +1 -1
  41. package/dist/src/cli/validation-helper.js.map +1 -1
  42. package/dist/src/execution/agent-executor.js +181 -0
  43. package/dist/src/execution/agent-executor.js.map +1 -0
  44. package/dist/src/execution/index.js +12 -0
  45. package/dist/src/execution/index.js.map +1 -0
  46. package/dist/src/execution/provider-manager.js +110 -0
  47. package/dist/src/execution/provider-manager.js.map +1 -0
  48. package/dist/src/hooks/index.js +0 -3
  49. package/dist/src/hooks/index.js.map +1 -1
  50. package/dist/src/hooks/redaction-hook.js +89 -0
  51. package/dist/src/hooks/redaction-hook.js.map +1 -0
  52. package/dist/src/mcp/claude-flow-tools.js +205 -150
  53. package/dist/src/mcp/claude-flow-tools.js.map +1 -1
  54. package/dist/src/mcp/mcp-server.js +125 -0
  55. package/dist/src/mcp/mcp-server.js.map +1 -1
  56. package/dist/src/sdk/query-control.js +293 -139
  57. package/dist/src/sdk/query-control.js.map +1 -1
  58. package/dist/src/sdk/session-forking.js +206 -129
  59. package/dist/src/sdk/session-forking.js.map +1 -1
  60. package/dist/src/utils/key-redactor.js +108 -0
  61. package/dist/src/utils/key-redactor.js.map +1 -0
  62. package/dist/src/utils/metrics-reader.js +37 -39
  63. package/dist/src/utils/metrics-reader.js.map +1 -1
  64. package/docs/AGENT-BOOSTER-INTEGRATION.md +407 -0
  65. package/docs/AGENTIC-FLOW-INTEGRATION-GUIDE.md +753 -0
  66. package/docs/AGENTIC_FLOW_EXECUTION_FIX_REPORT.md +474 -0
  67. package/docs/AGENTIC_FLOW_INTEGRATION_STATUS.md +143 -0
  68. package/docs/AGENTIC_FLOW_MVP_COMPLETE.md +367 -0
  69. package/docs/AGENTIC_FLOW_SECURITY_TEST_REPORT.md +369 -0
  70. package/docs/COMMAND-VERIFICATION-REPORT.md +441 -0
  71. package/docs/COMMIT_SUMMARY.md +247 -0
  72. package/docs/DEEP_REVIEW_COMPREHENSIVE_REPORT.md +922 -0
  73. package/docs/DOCKER-VALIDATION-REPORT.md +281 -0
  74. package/docs/ENV-SETUP-GUIDE.md +270 -0
  75. package/docs/FINAL_PRE_PUBLISH_VALIDATION.md +823 -0
  76. package/docs/FINAL_VALIDATION_REPORT.md +165 -0
  77. package/docs/HOOKS-V2-MODIFICATION.md +146 -0
  78. package/docs/INDEX.md +568 -0
  79. package/docs/INTEGRATION_COMPLETE.md +414 -0
  80. package/docs/MEMORY_REDACTION_TEST_REPORT.md +300 -0
  81. package/docs/PERFORMANCE-SYSTEMS-STATUS.md +340 -0
  82. package/docs/PRE_RELEASE_FIXES_REPORT.md +435 -0
  83. package/docs/README.md +35 -0
  84. package/docs/REASONING-AGENTS.md +482 -0
  85. package/docs/REASONINGBANK-AGENT-CREATION-GUIDE.md +813 -0
  86. package/docs/REASONINGBANK-ANALYSIS-COMPLETE.md +479 -0
  87. package/docs/REASONINGBANK-BENCHMARK-RESULTS.md +166 -0
  88. package/docs/REASONINGBANK-BENCHMARK.md +396 -0
  89. package/docs/REASONINGBANK-CLI-INTEGRATION.md +455 -0
  90. package/docs/REASONINGBANK-CORE-INTEGRATION.md +658 -0
  91. package/docs/REASONINGBANK-COST-OPTIMIZATION.md +329 -0
  92. package/docs/REASONINGBANK-DEMO.md +419 -0
  93. package/docs/REASONINGBANK-INTEGRATION-COMPLETE.md +249 -0
  94. package/docs/REASONINGBANK-VALIDATION.md +532 -0
  95. package/docs/REASONINGBANK_ARCHITECTURE.md +475 -0
  96. package/docs/REASONINGBANK_INTEGRATION_COMPLETE.md +558 -0
  97. package/docs/REASONINGBANK_INTEGRATION_PLAN.md +1188 -0
  98. package/docs/REGRESSION-ANALYSIS-REPORT.md +500 -0
  99. package/docs/RELEASE_v2.6.0-alpha.2.md +658 -0
  100. package/docs/api/API_DOCUMENTATION.md +721 -0
  101. package/docs/architecture/ARCHITECTURE.md +1690 -0
  102. package/docs/ci-cd/README.md +368 -0
  103. package/docs/development/DEPLOYMENT.md +2348 -0
  104. package/docs/development/DEVELOPMENT_WORKFLOW.md +1333 -0
  105. package/docs/development/build-analysis-report.md +252 -0
  106. package/docs/development/pair-optimization.md +156 -0
  107. package/docs/development/token-tracking-status.md +103 -0
  108. package/docs/development/training-pipeline-demo.md +163 -0
  109. package/docs/development/training-pipeline-real-only.md +196 -0
  110. package/docs/epic-sdk-integration.md +1269 -0
  111. package/docs/experimental/RIEMANN_HYPOTHESIS_PROOF.md +124 -0
  112. package/docs/experimental/computational_verification.py +436 -0
  113. package/docs/experimental/novel_approaches.md +560 -0
  114. package/docs/experimental/riemann_hypothesis_analysis.md +263 -0
  115. package/docs/experimental/riemann_proof_attempt.md +124 -0
  116. package/docs/experimental/riemann_synthesis.md +277 -0
  117. package/docs/experimental/verification_results.json +12 -0
  118. package/docs/experimental/visualization_insights.md +720 -0
  119. package/docs/guides/USER_GUIDE.md +1138 -0
  120. package/docs/guides/token-tracking-guide.md +291 -0
  121. package/docs/reference/AGENTS.md +1011 -0
  122. package/docs/reference/MCP_TOOLS.md +2188 -0
  123. package/docs/reference/SPARC.md +717 -0
  124. package/docs/reference/SWARM.md +2000 -0
  125. package/docs/sdk/CLAUDE-CODE-SDK-DEEP-ANALYSIS.md +649 -0
  126. package/docs/sdk/CLAUDE-FLOW-SDK-INTEGRATION-ANALYSIS.md +242 -0
  127. package/docs/sdk/INTEGRATION-ROADMAP.md +420 -0
  128. package/docs/sdk/MCP-TOOLS-UPDATE.md +270 -0
  129. package/docs/sdk/SDK-ADVANCED-FEATURES-INTEGRATION.md +723 -0
  130. package/docs/sdk/SDK-ALL-FEATURES-INTEGRATION-MATRIX.md +612 -0
  131. package/docs/sdk/SDK-INTEGRATION-COMPLETE.md +358 -0
  132. package/docs/sdk/SDK-INTEGRATION-PHASES-V2.5.md +750 -0
  133. package/docs/sdk/SDK-LEVERAGE-REAL-FEATURES.md +676 -0
  134. package/docs/sdk/SDK-VALIDATION-RESULTS.md +400 -0
  135. package/docs/sdk/epic-sdk-integration.md +1269 -0
  136. package/docs/setup/remote-setup.md +93 -0
  137. package/docs/validation/final-validation-summary.md +220 -0
  138. package/docs/validation/verification-integration.md +190 -0
  139. package/docs/validation/verification-validation.md +349 -0
  140. package/docs/wiki/background-commands.md +1213 -0
  141. package/docs/wiki/session-persistence.md +342 -0
  142. package/docs/wiki/stream-chain-command.md +537 -0
  143. package/package.json +4 -2
  144. package/src/cli/command-registry.js +70 -5
  145. package/src/cli/commands/hive-mind/pause.ts +2 -15
  146. package/src/cli/commands/index.ts +1 -84
  147. package/src/cli/commands/swarm-spawn.ts +3 -47
  148. package/src/cli/help-text.js +42 -7
  149. package/src/cli/simple-cli.ts +18 -8
  150. package/src/cli/simple-commands/agent-booster.js +515 -0
  151. package/src/cli/simple-commands/agent.js +1001 -12
  152. package/src/cli/simple-commands/agent.ts +137 -0
  153. package/src/cli/simple-commands/config.ts +127 -0
  154. package/src/cli/simple-commands/env-template.js +190 -0
  155. package/src/cli/simple-commands/hooks.js +310 -0
  156. package/src/cli/simple-commands/init/help.js +23 -0
  157. package/src/cli/simple-commands/init/index.js +84 -6
  158. package/src/cli/simple-commands/memory.js +363 -16
  159. package/src/cli/simple-commands/proxy.js +384 -0
  160. package/src/cli/simple-commands/sparc.js +16 -19
  161. package/src/execution/agent-executor.ts +306 -0
  162. package/src/execution/index.ts +19 -0
  163. package/src/execution/provider-manager.ts +187 -0
  164. package/src/hooks/index.ts +0 -5
  165. package/src/hooks/redaction-hook.ts +115 -0
  166. package/src/mcp/claude-flow-tools.ts +203 -120
  167. package/src/mcp/mcp-server.js +86 -0
  168. package/src/sdk/query-control.ts +377 -223
  169. package/src/sdk/session-forking.ts +312 -207
  170. package/src/utils/key-redactor.js +178 -0
  171. package/src/utils/key-redactor.ts +184 -0
@@ -1,156 +1,233 @@
1
1
  import { query } from '@anthropic-ai/claude-code';
2
2
  import { EventEmitter } from 'events';
3
- export class RealSessionForking extends EventEmitter {
4
- sessions = new Map();
5
- async fork(baseSessionId, options = {}) {
6
- const baseSnapshot = this.sessions.get(baseSessionId);
7
- if (!baseSnapshot) {
8
- throw new Error(`Session not found: ${baseSessionId}`);
9
- }
10
- const lastMessage = baseSnapshot.messages[baseSnapshot.messages.length - 1];
11
- const forkPoint = lastMessage.uuid;
12
- const forkedQuery = query({
13
- prompt: async function*() {
14
- yield {
15
- type: 'user',
16
- message: {
17
- role: 'user',
18
- content: ''
19
- }
20
- };
21
- }(),
22
- options: {
23
- ...options,
24
- forkSession: true,
25
- resume: baseSessionId,
26
- resumeSessionAt: forkPoint
27
- }
3
+ import { Logger } from '../core/logger.js';
4
+ import { generateId } from '../utils/helpers.js';
5
+ export class ParallelSwarmExecutor extends EventEmitter {
6
+ logger;
7
+ activeSessions = new Map();
8
+ sessionHistory = new Map();
9
+ executionMetrics;
10
+ constructor(){
11
+ super();
12
+ this.logger = new Logger({
13
+ level: 'info',
14
+ format: 'text',
15
+ destination: 'console'
16
+ }, {
17
+ component: 'ParallelSwarmExecutor'
28
18
  });
29
- let newSessionId = null;
30
- const messages = [];
31
- const firstMsg = await forkedQuery.next();
32
- if (!firstMsg.done && firstMsg.value) {
33
- newSessionId = firstMsg.value.session_id;
34
- messages.push(firstMsg.value);
35
- }
36
- if (!newSessionId) {
37
- throw new Error('Failed to create forked session');
38
- }
39
- const forkedSnapshot = {
40
- sessionId: newSessionId,
41
- parentId: baseSessionId,
42
- messages,
43
- createdAt: Date.now(),
44
- forkedFrom: forkPoint
19
+ this.executionMetrics = {
20
+ totalAgentsSpawned: 0,
21
+ parallelExecutions: 0,
22
+ avgSpawnTime: 0,
23
+ performanceGain: 1.0
45
24
  };
46
- this.sessions.set(newSessionId, forkedSnapshot);
47
- this.emit('fork:created', {
48
- parentId: baseSessionId,
49
- forkId: newSessionId,
50
- forkPoint
25
+ }
26
+ async spawnParallelAgents(agentConfigs, options = {}) {
27
+ const startTime = Date.now();
28
+ const executionId = generateId('parallel-exec');
29
+ this.logger.info('Starting parallel agent spawning', {
30
+ executionId,
31
+ agentCount: agentConfigs.length,
32
+ forkingEnabled: true
51
33
  });
52
- return {
53
- sessionId: newSessionId,
54
- parentSessionId: baseSessionId,
55
- query: forkedQuery,
56
- messageHistory: messages,
57
- commit: async ()=>{
58
- await this.commitFork(newSessionId, baseSessionId);
59
- },
60
- rollback: async ()=>{
61
- await this.rollbackFork(newSessionId);
62
- },
63
- getDiff: ()=>{
64
- return this.calculateDiff(newSessionId, baseSessionId);
65
- }
34
+ const sortedConfigs = this.sortByPriority(agentConfigs);
35
+ const maxParallel = options.maxParallelAgents || 10;
36
+ const batches = this.createBatches(sortedConfigs, maxParallel);
37
+ const agentResults = new Map();
38
+ const failedAgents = [];
39
+ const successfulAgents = [];
40
+ for (const batch of batches){
41
+ const batchPromises = batch.map((config)=>this.spawnSingleAgent(config, options, executionId));
42
+ const batchResults = await Promise.allSettled(batchPromises);
43
+ batchResults.forEach((result, index)=>{
44
+ const config = batch[index];
45
+ if (result.status === 'fulfilled') {
46
+ agentResults.set(config.agentId, result.value);
47
+ successfulAgents.push(config.agentId);
48
+ } else {
49
+ failedAgents.push(config.agentId);
50
+ agentResults.set(config.agentId, {
51
+ agentId: config.agentId,
52
+ output: '',
53
+ messages: [],
54
+ duration: Date.now() - startTime,
55
+ status: 'failed',
56
+ error: result.reason
57
+ });
58
+ }
59
+ });
60
+ }
61
+ const totalDuration = Date.now() - startTime;
62
+ this.updateMetrics(agentConfigs.length, totalDuration);
63
+ const result = {
64
+ success: failedAgents.length === 0,
65
+ agentResults,
66
+ totalDuration,
67
+ failedAgents,
68
+ successfulAgents
66
69
  };
70
+ this.logger.info('Parallel agent spawning completed', {
71
+ executionId,
72
+ totalAgents: agentConfigs.length,
73
+ successful: successfulAgents.length,
74
+ failed: failedAgents.length,
75
+ duration: totalDuration,
76
+ performanceGain: this.executionMetrics.performanceGain
77
+ });
78
+ this.emit('parallel:complete', result);
79
+ return result;
67
80
  }
68
- async trackSession(sessionId, queryGenerator) {
69
- let snapshot = this.sessions.get(sessionId);
70
- if (!snapshot) {
71
- snapshot = {
81
+ async spawnSingleAgent(config, options, executionId) {
82
+ const sessionId = generateId('fork-session');
83
+ const startTime = Date.now();
84
+ this.logger.debug('Spawning forked session', {
85
+ sessionId,
86
+ agentId: config.agentId,
87
+ agentType: config.agentType
88
+ });
89
+ try {
90
+ const sdkOptions = {
91
+ forkSession: true,
92
+ resume: options.baseSessionId,
93
+ resumeSessionAt: options.resumeFromMessage,
94
+ model: options.model || 'claude-sonnet-4',
95
+ maxTurns: 50,
96
+ timeout: config.timeout || options.timeout || 60000,
97
+ mcpServers: options.mcpServers || {},
98
+ cwd: process.cwd()
99
+ };
100
+ const prompt = this.buildAgentPrompt(config);
101
+ const forkedQuery = query({
102
+ prompt,
103
+ options: sdkOptions
104
+ });
105
+ const forkedSession = {
72
106
  sessionId,
73
- parentId: null,
107
+ agentId: config.agentId,
108
+ agentType: config.agentType,
109
+ query: forkedQuery,
74
110
  messages: [],
75
- createdAt: Date.now()
111
+ status: 'spawning',
112
+ startTime
76
113
  };
77
- this.sessions.set(sessionId, snapshot);
78
- }
79
- for await (const message of queryGenerator){
80
- snapshot.messages.push(message);
81
- this.emit('message', {
114
+ this.activeSessions.set(sessionId, forkedSession);
115
+ this.emit('session:forked', {
82
116
  sessionId,
83
- message,
84
- messageCount: snapshot.messages.length
117
+ agentId: config.agentId
85
118
  });
119
+ const messages = [];
120
+ let outputText = '';
121
+ for await (const message of forkedQuery){
122
+ messages.push(message);
123
+ forkedSession.messages.push(message);
124
+ if (message.type === 'assistant') {
125
+ const textContent = message.message.content.filter((c)=>c.type === 'text').map((c)=>c.text).join('\n');
126
+ outputText += textContent;
127
+ }
128
+ forkedSession.status = 'active';
129
+ this.emit('session:message', {
130
+ sessionId,
131
+ message
132
+ });
133
+ }
134
+ forkedSession.status = 'completed';
135
+ forkedSession.endTime = Date.now();
136
+ this.sessionHistory.set(sessionId, messages);
137
+ const duration = Date.now() - startTime;
138
+ this.logger.debug('Forked session completed', {
139
+ sessionId,
140
+ agentId: config.agentId,
141
+ duration,
142
+ messageCount: messages.length
143
+ });
144
+ return {
145
+ agentId: config.agentId,
146
+ output: outputText,
147
+ messages,
148
+ duration,
149
+ status: 'completed'
150
+ };
151
+ } catch (error) {
152
+ this.logger.error('Forked session failed', {
153
+ sessionId,
154
+ agentId: config.agentId,
155
+ error: error instanceof Error ? error.message : String(error)
156
+ });
157
+ const session = this.activeSessions.get(sessionId);
158
+ if (session) {
159
+ session.status = 'failed';
160
+ session.error = error;
161
+ session.endTime = Date.now();
162
+ }
163
+ throw error;
86
164
  }
87
165
  }
88
- async commitFork(forkId, parentId) {
89
- const fork = this.sessions.get(forkId);
90
- const parent = this.sessions.get(parentId);
91
- if (!fork || !parent) {
92
- throw new Error('Fork or parent session not found');
166
+ buildAgentPrompt(config) {
167
+ const sections = [];
168
+ sections.push(`You are ${config.agentType} agent (ID: ${config.agentId}).`);
169
+ sections.push('');
170
+ if (config.capabilities && config.capabilities.length > 0) {
171
+ sections.push('Your capabilities:');
172
+ config.capabilities.forEach((cap)=>sections.push(`- ${cap}`));
173
+ sections.push('');
93
174
  }
94
- const diff = this.calculateDiff(forkId, parentId);
95
- const forkMessages = fork.messages.slice(1);
96
- parent.messages.push(...forkMessages);
97
- this.emit('fork:committed', {
98
- forkId,
99
- parentId,
100
- diff
101
- });
102
- this.sessions.delete(forkId);
175
+ sections.push('Your task:');
176
+ sections.push(config.task);
177
+ sections.push('');
178
+ sections.push('Execute this task efficiently and report your results clearly.');
179
+ return sections.join('\n');
103
180
  }
104
- async rollbackFork(forkId) {
105
- const fork = this.sessions.get(forkId);
106
- if (!fork) {
107
- throw new Error('Fork not found');
108
- }
109
- this.emit('fork:rolled_back', {
110
- forkId,
111
- parentId: fork.parentId
181
+ sortByPriority(configs) {
182
+ const priorityOrder = {
183
+ critical: 0,
184
+ high: 1,
185
+ medium: 2,
186
+ low: 3
187
+ };
188
+ return [
189
+ ...configs
190
+ ].sort((a, b)=>{
191
+ const aPriority = priorityOrder[a.priority || 'medium'];
192
+ const bPriority = priorityOrder[b.priority || 'medium'];
193
+ return aPriority - bPriority;
112
194
  });
113
- this.sessions.delete(forkId);
114
195
  }
115
- calculateDiff(forkId, parentId) {
116
- const fork = this.sessions.get(forkId);
117
- const parent = this.sessions.get(parentId);
118
- if (!fork || !parent) {
119
- throw new Error('Session not found');
196
+ createBatches(items, batchSize) {
197
+ const batches = [];
198
+ for(let i = 0; i < items.length; i += batchSize){
199
+ batches.push(items.slice(i, i + batchSize));
120
200
  }
121
- const addedMessages = fork.messages.length - 1;
122
- const filesModified = new Set();
123
- for (const msg of fork.messages){
124
- if (msg.type === 'assistant' && 'message' in msg) {
125
- const content = msg.message.content;
126
- for (const block of content){
127
- if (block.type === 'tool_use') {
128
- if (block.name === 'Edit' || block.name === 'Write') {
129
- const input = block.input;
130
- if (input.file_path) {
131
- filesModified.add(input.file_path);
132
- }
133
- }
134
- }
135
- }
136
- }
137
- }
138
- return {
139
- addedMessages,
140
- filesModified: Array.from(filesModified),
141
- timestamp: Date.now()
142
- };
201
+ return batches;
202
+ }
203
+ updateMetrics(agentCount, duration) {
204
+ this.executionMetrics.totalAgentsSpawned += agentCount;
205
+ this.executionMetrics.parallelExecutions += 1;
206
+ const avgSpawnTime = duration / agentCount;
207
+ this.executionMetrics.avgSpawnTime = (this.executionMetrics.avgSpawnTime + avgSpawnTime) / 2;
208
+ const estimatedSequentialTime = agentCount * 750;
209
+ this.executionMetrics.performanceGain = estimatedSequentialTime / duration;
143
210
  }
144
211
  getActiveSessions() {
145
- return Array.from(this.sessions.keys());
212
+ return new Map(this.activeSessions);
146
213
  }
147
- getSessionInfo(sessionId) {
148
- return this.sessions.get(sessionId);
214
+ getSessionHistory(sessionId) {
215
+ return this.sessionHistory.get(sessionId);
149
216
  }
150
- getForks(parentId) {
151
- return Array.from(this.sessions.values()).filter((s)=>s.parentId === parentId).map((s)=>s.sessionId);
217
+ getMetrics() {
218
+ return {
219
+ ...this.executionMetrics
220
+ };
221
+ }
222
+ cleanupSessions(olderThan = 3600000) {
223
+ const cutoff = Date.now() - olderThan;
224
+ for (const [sessionId, session] of this.activeSessions.entries()){
225
+ if (session.endTime && session.endTime < cutoff) {
226
+ this.activeSessions.delete(sessionId);
227
+ this.sessionHistory.delete(sessionId);
228
+ }
229
+ }
152
230
  }
153
231
  }
154
- export const sessionForking = new RealSessionForking();
155
232
 
156
233
  //# sourceMappingURL=session-forking.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/sdk/session-forking.ts"],"sourcesContent":["/**\n * Real Session Forking - 100% SDK-Powered\n * Claude-Flow v2.5-alpha.130+\n *\n * Uses ONLY Claude Code SDK primitives - no fake implementations:\n * - forkSession: true (SDK creates new session ID)\n * - resume: sessionId (SDK loads parent history)\n * - resumeSessionAt: messageId (SDK starts from exact point)\n *\n * VERIFIED: All features use actual SDK capabilities\n */\n\nimport { query, type Query, type SDKMessage, type Options } from '@anthropic-ai/claude-code';\nimport { EventEmitter } from 'events';\n\nexport interface ForkedSession {\n sessionId: string;\n parentSessionId: string;\n query: Query;\n messageHistory: SDKMessage[];\n\n // Commit changes back to parent\n commit(): Promise<void>;\n\n // Discard fork\n rollback(): Promise<void>;\n\n // Get divergence from parent\n getDiff(): SessionDiff;\n}\n\nexport interface SessionDiff {\n addedMessages: number;\n filesModified: string[];\n timestamp: number;\n}\n\ninterface SessionSnapshot {\n sessionId: string;\n parentId: string | null;\n messages: SDKMessage[];\n createdAt: number;\n forkedFrom?: string; // Message UUID where fork occurred\n}\n\n/**\n * Real Session Forking using ONLY SDK features\n * No custom parallel execution - use SDK's built-in capabilities\n */\nexport class RealSessionForking extends EventEmitter {\n private sessions = new Map<string, SessionSnapshot>();\n\n /**\n * Fork a session using SDK's forkSession + resume\n *\n * ✅ VERIFIED: Uses actual SDK primitives\n *\n * @param baseSessionId - Parent session to fork from\n * @param options - Additional SDK options\n * @returns Forked session with commit/rollback\n */\n async fork(\n baseSessionId: string,\n options: Partial<Options> = {}\n ): Promise<ForkedSession> {\n const baseSnapshot = this.sessions.get(baseSessionId);\n if (!baseSnapshot) {\n throw new Error(`Session not found: ${baseSessionId}`);\n }\n\n // Get last message UUID from parent session\n const lastMessage = baseSnapshot.messages[baseSnapshot.messages.length - 1];\n const forkPoint = lastMessage.uuid;\n\n // Create forked query using SDK primitives\n const forkedQuery = query({\n prompt: async function* () {\n // Empty initial prompt - just continue from fork point\n yield { type: 'user' as const, message: { role: 'user' as const, content: '' } };\n }(),\n options: {\n ...options,\n forkSession: true, // ✅ SDK creates new session ID\n resume: baseSessionId, // ✅ SDK loads parent's history\n resumeSessionAt: forkPoint, // ✅ SDK starts from this message\n }\n });\n\n // Extract new session ID from first system message\n let newSessionId: string | null = null;\n const messages: SDKMessage[] = [];\n\n // Get first message to extract session ID\n const firstMsg = await forkedQuery.next();\n if (!firstMsg.done && firstMsg.value) {\n newSessionId = firstMsg.value.session_id;\n messages.push(firstMsg.value);\n }\n\n if (!newSessionId) {\n throw new Error('Failed to create forked session');\n }\n\n // Create snapshot for forked session\n const forkedSnapshot: SessionSnapshot = {\n sessionId: newSessionId,\n parentId: baseSessionId,\n messages,\n createdAt: Date.now(),\n forkedFrom: forkPoint,\n };\n\n this.sessions.set(newSessionId, forkedSnapshot);\n\n this.emit('fork:created', {\n parentId: baseSessionId,\n forkId: newSessionId,\n forkPoint,\n });\n\n // Return forked session interface\n return {\n sessionId: newSessionId,\n parentSessionId: baseSessionId,\n query: forkedQuery,\n messageHistory: messages,\n\n commit: async () => {\n await this.commitFork(newSessionId, baseSessionId);\n },\n\n rollback: async () => {\n await this.rollbackFork(newSessionId);\n },\n\n getDiff: () => {\n return this.calculateDiff(newSessionId, baseSessionId);\n },\n };\n }\n\n /**\n * Track messages for a session\n * Call this to keep message history updated\n */\n async trackSession(sessionId: string, queryGenerator: Query) {\n let snapshot = this.sessions.get(sessionId);\n\n if (!snapshot) {\n // Create new session snapshot\n snapshot = {\n sessionId,\n parentId: null,\n messages: [],\n createdAt: Date.now(),\n };\n this.sessions.set(sessionId, snapshot);\n }\n\n for await (const message of queryGenerator) {\n snapshot.messages.push(message);\n\n this.emit('message', {\n sessionId,\n message,\n messageCount: snapshot.messages.length,\n });\n }\n }\n\n /**\n * Commit fork changes back to parent session\n * Creates a new query that applies fork's changes to parent\n */\n private async commitFork(forkId: string, parentId: string): Promise<void> {\n const fork = this.sessions.get(forkId);\n const parent = this.sessions.get(parentId);\n\n if (!fork || !parent) {\n throw new Error('Fork or parent session not found');\n }\n\n // Calculate what changed in fork\n const diff = this.calculateDiff(forkId, parentId);\n\n // Apply fork's messages to parent\n const forkMessages = fork.messages.slice(1); // Skip initial message\n parent.messages.push(...forkMessages);\n\n this.emit('fork:committed', {\n forkId,\n parentId,\n diff,\n });\n\n // Clean up fork\n this.sessions.delete(forkId);\n }\n\n /**\n * Rollback (discard) a fork\n */\n private async rollbackFork(forkId: string): Promise<void> {\n const fork = this.sessions.get(forkId);\n if (!fork) {\n throw new Error('Fork not found');\n }\n\n this.emit('fork:rolled_back', {\n forkId,\n parentId: fork.parentId,\n });\n\n // Simply delete the fork - SDK handles cleanup\n this.sessions.delete(forkId);\n }\n\n /**\n * Calculate diff between fork and parent\n */\n private calculateDiff(forkId: string, parentId: string): SessionDiff {\n const fork = this.sessions.get(forkId);\n const parent = this.sessions.get(parentId);\n\n if (!fork || !parent) {\n throw new Error('Session not found');\n }\n\n // Count new messages in fork\n const addedMessages = fork.messages.length - 1; // Exclude initial message\n\n // Extract file modifications from tool uses\n const filesModified = new Set<string>();\n\n for (const msg of fork.messages) {\n if (msg.type === 'assistant' && 'message' in msg) {\n const content = msg.message.content;\n for (const block of content) {\n if (block.type === 'tool_use') {\n // Check for file operations\n if (block.name === 'Edit' || block.name === 'Write') {\n const input = block.input as { file_path?: string };\n if (input.file_path) {\n filesModified.add(input.file_path);\n }\n }\n }\n }\n }\n }\n\n return {\n addedMessages,\n filesModified: Array.from(filesModified),\n timestamp: Date.now(),\n };\n }\n\n /**\n * Get all active sessions\n */\n getActiveSessions(): string[] {\n return Array.from(this.sessions.keys());\n }\n\n /**\n * Get session info\n */\n getSessionInfo(sessionId: string): SessionSnapshot | undefined {\n return this.sessions.get(sessionId);\n }\n\n /**\n * List all forks of a parent session\n */\n getForks(parentId: string): string[] {\n return Array.from(this.sessions.values())\n .filter(s => s.parentId === parentId)\n .map(s => s.sessionId);\n }\n}\n\n// Export singleton instance\nexport const sessionForking = new RealSessionForking();\n"],"names":["query","EventEmitter","RealSessionForking","sessions","Map","fork","baseSessionId","options","baseSnapshot","get","Error","lastMessage","messages","length","forkPoint","uuid","forkedQuery","prompt","type","message","role","content","forkSession","resume","resumeSessionAt","newSessionId","firstMsg","next","done","value","session_id","push","forkedSnapshot","sessionId","parentId","createdAt","Date","now","forkedFrom","set","emit","forkId","parentSessionId","messageHistory","commit","commitFork","rollback","rollbackFork","getDiff","calculateDiff","trackSession","queryGenerator","snapshot","messageCount","parent","diff","forkMessages","slice","delete","addedMessages","filesModified","Set","msg","block","name","input","file_path","add","Array","from","timestamp","getActiveSessions","keys","getSessionInfo","getForks","values","filter","s","map","sessionForking"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/sdk/session-forking.ts"],"sourcesContent":["/**\n * Session Forking & Parallel Agent Execution\n * Claude-Flow v2.5-alpha.130\n *\n * Implements session forking for 10-20x faster parallel agent spawning\n * using Claude Code SDK's forkSession: true option\n */\n\nimport { query, type Options, type SDKMessage, type Query } from '@anthropic-ai/claude-code';\nimport { EventEmitter } from 'events';\nimport { Logger } from '../core/logger.js';\nimport { generateId } from '../utils/helpers.js';\n\nexport interface ParallelAgentConfig {\n agentId: string;\n agentType: string;\n task: string;\n capabilities?: string[];\n priority?: 'low' | 'medium' | 'high' | 'critical';\n timeout?: number;\n}\n\nexport interface ForkedSession {\n sessionId: string;\n agentId: string;\n agentType: string;\n query: Query;\n messages: SDKMessage[];\n status: 'spawning' | 'active' | 'paused' | 'completed' | 'failed' | 'terminated';\n startTime: number;\n endTime?: number;\n error?: Error;\n}\n\nexport interface ParallelExecutionResult {\n success: boolean;\n agentResults: Map<string, {\n agentId: string;\n output: string;\n messages: SDKMessage[];\n duration: number;\n status: 'completed' | 'failed' | 'terminated';\n error?: Error;\n }>;\n totalDuration: number;\n failedAgents: string[];\n successfulAgents: string[];\n}\n\nexport interface SessionForkOptions {\n maxParallelAgents?: number;\n baseSessionId?: string;\n resumeFromMessage?: string;\n sharedMemory?: boolean;\n timeout?: number;\n model?: string;\n mcpServers?: Record<string, any>;\n}\n\n/**\n * ParallelSwarmExecutor - Spawns agents in parallel using session forking\n * Achieves 10-20x performance gain over sequential spawning\n */\nexport class ParallelSwarmExecutor extends EventEmitter {\n private logger: Logger;\n private activeSessions: Map<string, ForkedSession> = new Map();\n private sessionHistory: Map<string, SDKMessage[]> = new Map();\n private executionMetrics: {\n totalAgentsSpawned: number;\n parallelExecutions: number;\n avgSpawnTime: number;\n performanceGain: number;\n };\n\n constructor() {\n super();\n this.logger = new Logger(\n { level: 'info', format: 'text', destination: 'console' },\n { component: 'ParallelSwarmExecutor' }\n );\n\n this.executionMetrics = {\n totalAgentsSpawned: 0,\n parallelExecutions: 0,\n avgSpawnTime: 0,\n performanceGain: 1.0\n };\n }\n\n /**\n * Spawn multiple agents in parallel using session forking\n * This is 10-20x faster than sequential spawning\n */\n async spawnParallelAgents(\n agentConfigs: ParallelAgentConfig[],\n options: SessionForkOptions = {}\n ): Promise<ParallelExecutionResult> {\n const startTime = Date.now();\n const executionId = generateId('parallel-exec');\n\n this.logger.info('Starting parallel agent spawning', {\n executionId,\n agentCount: agentConfigs.length,\n forkingEnabled: true\n });\n\n // Sort by priority\n const sortedConfigs = this.sortByPriority(agentConfigs);\n\n // Limit parallel execution\n const maxParallel = options.maxParallelAgents || 10;\n const batches = this.createBatches(sortedConfigs, maxParallel);\n\n const agentResults = new Map();\n const failedAgents: string[] = [];\n const successfulAgents: string[] = [];\n\n // Execute in batches to avoid overwhelming the system\n for (const batch of batches) {\n const batchPromises = batch.map(config =>\n this.spawnSingleAgent(config, options, executionId)\n );\n\n const batchResults = await Promise.allSettled(batchPromises);\n\n batchResults.forEach((result, index) => {\n const config = batch[index];\n\n if (result.status === 'fulfilled') {\n agentResults.set(config.agentId, result.value);\n successfulAgents.push(config.agentId);\n } else {\n failedAgents.push(config.agentId);\n agentResults.set(config.agentId, {\n agentId: config.agentId,\n output: '',\n messages: [],\n duration: Date.now() - startTime,\n status: 'failed',\n error: result.reason\n });\n }\n });\n }\n\n const totalDuration = Date.now() - startTime;\n\n // Calculate performance metrics\n this.updateMetrics(agentConfigs.length, totalDuration);\n\n const result: ParallelExecutionResult = {\n success: failedAgents.length === 0,\n agentResults,\n totalDuration,\n failedAgents,\n successfulAgents\n };\n\n this.logger.info('Parallel agent spawning completed', {\n executionId,\n totalAgents: agentConfigs.length,\n successful: successfulAgents.length,\n failed: failedAgents.length,\n duration: totalDuration,\n performanceGain: this.executionMetrics.performanceGain\n });\n\n this.emit('parallel:complete', result);\n\n return result;\n }\n\n /**\n * Spawn a single agent using session forking\n */\n private async spawnSingleAgent(\n config: ParallelAgentConfig,\n options: SessionForkOptions,\n executionId: string\n ): Promise<any> {\n const sessionId = generateId('fork-session');\n const startTime = Date.now();\n\n this.logger.debug('Spawning forked session', {\n sessionId,\n agentId: config.agentId,\n agentType: config.agentType\n });\n\n try {\n // Create forked session with SDK\n const sdkOptions: Options = {\n forkSession: true, // KEY FEATURE: Enable session forking\n resume: options.baseSessionId, // Resume from base session if provided\n resumeSessionAt: options.resumeFromMessage, // Resume from specific message\n model: options.model || 'claude-sonnet-4',\n maxTurns: 50,\n timeout: config.timeout || options.timeout || 60000,\n mcpServers: options.mcpServers || {},\n cwd: process.cwd()\n };\n\n // Build agent prompt\n const prompt = this.buildAgentPrompt(config);\n\n // Create forked query\n const forkedQuery = query({\n prompt,\n options: sdkOptions\n });\n\n // Track forked session\n const forkedSession: ForkedSession = {\n sessionId,\n agentId: config.agentId,\n agentType: config.agentType,\n query: forkedQuery,\n messages: [],\n status: 'spawning',\n startTime\n };\n\n this.activeSessions.set(sessionId, forkedSession);\n this.emit('session:forked', { sessionId, agentId: config.agentId });\n\n // Collect messages from forked session\n const messages: SDKMessage[] = [];\n let outputText = '';\n\n for await (const message of forkedQuery) {\n messages.push(message);\n forkedSession.messages.push(message);\n\n // Extract output text from assistant messages\n if (message.type === 'assistant') {\n const textContent = message.message.content\n .filter((c: any) => c.type === 'text')\n .map((c: any) => c.text)\n .join('\\n');\n outputText += textContent;\n }\n\n // Update session status\n forkedSession.status = 'active';\n this.emit('session:message', { sessionId, message });\n }\n\n // Mark as completed\n forkedSession.status = 'completed';\n forkedSession.endTime = Date.now();\n\n // Store session history\n this.sessionHistory.set(sessionId, messages);\n\n const duration = Date.now() - startTime;\n\n this.logger.debug('Forked session completed', {\n sessionId,\n agentId: config.agentId,\n duration,\n messageCount: messages.length\n });\n\n return {\n agentId: config.agentId,\n output: outputText,\n messages,\n duration,\n status: 'completed'\n };\n\n } catch (error) {\n this.logger.error('Forked session failed', {\n sessionId,\n agentId: config.agentId,\n error: error instanceof Error ? error.message : String(error)\n });\n\n const session = this.activeSessions.get(sessionId);\n if (session) {\n session.status = 'failed';\n session.error = error as Error;\n session.endTime = Date.now();\n }\n\n throw error;\n }\n }\n\n /**\n * Build prompt for agent based on configuration\n */\n private buildAgentPrompt(config: ParallelAgentConfig): string {\n const sections: string[] = [];\n\n sections.push(`You are ${config.agentType} agent (ID: ${config.agentId}).`);\n sections.push('');\n\n if (config.capabilities && config.capabilities.length > 0) {\n sections.push('Your capabilities:');\n config.capabilities.forEach(cap => sections.push(`- ${cap}`));\n sections.push('');\n }\n\n sections.push('Your task:');\n sections.push(config.task);\n sections.push('');\n\n sections.push('Execute this task efficiently and report your results clearly.');\n\n return sections.join('\\n');\n }\n\n /**\n * Sort agent configs by priority\n */\n private sortByPriority(configs: ParallelAgentConfig[]): ParallelAgentConfig[] {\n const priorityOrder = { critical: 0, high: 1, medium: 2, low: 3 };\n return [...configs].sort((a, b) => {\n const aPriority = priorityOrder[a.priority || 'medium'];\n const bPriority = priorityOrder[b.priority || 'medium'];\n return aPriority - bPriority;\n });\n }\n\n /**\n * Create batches for parallel execution\n */\n private createBatches<T>(items: T[], batchSize: number): T[][] {\n const batches: T[][] = [];\n for (let i = 0; i < items.length; i += batchSize) {\n batches.push(items.slice(i, i + batchSize));\n }\n return batches;\n }\n\n /**\n * Update performance metrics\n */\n private updateMetrics(agentCount: number, duration: number): void {\n this.executionMetrics.totalAgentsSpawned += agentCount;\n this.executionMetrics.parallelExecutions += 1;\n\n // Calculate average spawn time per agent\n const avgSpawnTime = duration / agentCount;\n this.executionMetrics.avgSpawnTime =\n (this.executionMetrics.avgSpawnTime + avgSpawnTime) / 2;\n\n // Estimate performance gain vs sequential execution\n // Sequential would be ~500-1000ms per agent\n const estimatedSequentialTime = agentCount * 750; // 750ms average\n this.executionMetrics.performanceGain = estimatedSequentialTime / duration;\n }\n\n /**\n * Get active sessions\n */\n getActiveSessions(): Map<string, ForkedSession> {\n return new Map(this.activeSessions);\n }\n\n /**\n * Get session history\n */\n getSessionHistory(sessionId: string): SDKMessage[] | undefined {\n return this.sessionHistory.get(sessionId);\n }\n\n /**\n * Get performance metrics\n */\n getMetrics() {\n return { ...this.executionMetrics };\n }\n\n /**\n * Clean up completed sessions\n */\n cleanupSessions(olderThan: number = 3600000): void {\n const cutoff = Date.now() - olderThan;\n\n for (const [sessionId, session] of this.activeSessions.entries()) {\n if (session.endTime && session.endTime < cutoff) {\n this.activeSessions.delete(sessionId);\n this.sessionHistory.delete(sessionId);\n }\n }\n }\n}"],"names":["query","EventEmitter","Logger","generateId","ParallelSwarmExecutor","logger","activeSessions","Map","sessionHistory","executionMetrics","level","format","destination","component","totalAgentsSpawned","parallelExecutions","avgSpawnTime","performanceGain","spawnParallelAgents","agentConfigs","options","startTime","Date","now","executionId","info","agentCount","length","forkingEnabled","sortedConfigs","sortByPriority","maxParallel","maxParallelAgents","batches","createBatches","agentResults","failedAgents","successfulAgents","batch","batchPromises","map","config","spawnSingleAgent","batchResults","Promise","allSettled","forEach","result","index","status","set","agentId","value","push","output","messages","duration","error","reason","totalDuration","updateMetrics","success","totalAgents","successful","failed","emit","sessionId","debug","agentType","sdkOptions","forkSession","resume","baseSessionId","resumeSessionAt","resumeFromMessage","model","maxTurns","timeout","mcpServers","cwd","process","prompt","buildAgentPrompt","forkedQuery","forkedSession","outputText","message","type","textContent","content","filter","c","text","join","endTime","messageCount","Error","String","session","get","sections","capabilities","cap","task","configs","priorityOrder","critical","high","medium","low","sort","a","b","aPriority","priority","bPriority","items","batchSize","i","slice","estimatedSequentialTime","getActiveSessions","getSessionHistory","getMetrics","cleanupSessions","olderThan","cutoff","entries","delete"],"mappings":"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"}
@@ -0,0 +1,108 @@
1
+ export class KeyRedactor {
2
+ static API_KEY_PATTERNS = [
3
+ /sk-ant-[a-zA-Z0-9_-]{95,}/gi,
4
+ /sk-or-[a-zA-Z0-9_-]{32,}/gi,
5
+ /AIza[a-zA-Z0-9_-]{35}/gi,
6
+ /[a-zA-Z0-9_-]{20,}API[a-zA-Z0-9_-]{20,}/gi,
7
+ /Bearer\s+[a-zA-Z0-9_\-\.]{20,}/gi,
8
+ /([A-Z_]+_API_KEY|[A-Z_]+_TOKEN|[A-Z_]+_SECRET)=["']?([^"'\s]+)["']?/gi,
9
+ /eyJ[a-zA-Z0-9_-]*\.eyJ[a-zA-Z0-9_-]*\.[a-zA-Z0-9_-]*/gi
10
+ ];
11
+ static SENSITIVE_FIELDS = [
12
+ 'apiKey',
13
+ 'api_key',
14
+ 'token',
15
+ 'secret',
16
+ 'password',
17
+ 'private_key',
18
+ 'privateKey',
19
+ 'accessToken',
20
+ 'access_token',
21
+ 'refreshToken',
22
+ 'refresh_token'
23
+ ];
24
+ static redact(text, showPrefix = true) {
25
+ if (!text) return text;
26
+ let redacted = text;
27
+ this.API_KEY_PATTERNS.forEach((pattern)=>{
28
+ redacted = redacted.replace(pattern, (match)=>{
29
+ if (showPrefix && match.length > 8) {
30
+ const prefix = match.substring(0, 8);
31
+ return `${prefix}...[REDACTED]`;
32
+ }
33
+ return '[REDACTED_API_KEY]';
34
+ });
35
+ });
36
+ return redacted;
37
+ }
38
+ static redactObject(obj, deep = true) {
39
+ if (!obj || typeof obj !== 'object') return obj;
40
+ const redacted = {
41
+ ...obj
42
+ };
43
+ Object.keys(redacted).forEach((key)=>{
44
+ const lowerKey = key.toLowerCase();
45
+ const isSensitive = this.SENSITIVE_FIELDS.some((field)=>lowerKey.includes(field));
46
+ if (isSensitive && typeof redacted[key] === 'string') {
47
+ const value = redacted[key];
48
+ if (value && value.length > 8) {
49
+ redacted[key] = `${value.substring(0, 4)}...[REDACTED]`;
50
+ } else {
51
+ redacted[key] = '[REDACTED]';
52
+ }
53
+ } else if (deep && typeof redacted[key] === 'object' && redacted[key] !== null) {
54
+ redacted[key] = this.redactObject(redacted[key], deep);
55
+ } else if (typeof redacted[key] === 'string') {
56
+ redacted[key] = this.redact(redacted[key]);
57
+ }
58
+ });
59
+ return redacted;
60
+ }
61
+ static sanitize(text) {
62
+ return this.redact(text, true);
63
+ }
64
+ static sanitizeArgs(args) {
65
+ return args.map((arg)=>{
66
+ if (arg.includes('key') || arg.includes('token') || arg.includes('secret')) {
67
+ return this.redact(arg);
68
+ }
69
+ return arg;
70
+ });
71
+ }
72
+ static containsSensitiveData(text) {
73
+ return this.API_KEY_PATTERNS.some((pattern)=>pattern.test(text));
74
+ }
75
+ static validate(text) {
76
+ const warnings = [];
77
+ this.API_KEY_PATTERNS.forEach((pattern, index)=>{
78
+ if (pattern.test(text)) {
79
+ warnings.push(`Potential API key detected (pattern ${index + 1})`);
80
+ }
81
+ });
82
+ return {
83
+ safe: warnings.length === 0,
84
+ warnings
85
+ };
86
+ }
87
+ static redactEnv(env) {
88
+ const redacted = {};
89
+ Object.keys(env).forEach((key)=>{
90
+ const value = env[key];
91
+ if (!value) {
92
+ redacted[key] = '';
93
+ return;
94
+ }
95
+ const lowerKey = key.toLowerCase();
96
+ const isSensitive = lowerKey.includes('key') || lowerKey.includes('token') || lowerKey.includes('secret') || lowerKey.includes('password');
97
+ if (isSensitive) {
98
+ redacted[key] = value.length > 8 ? `${value.substring(0, 4)}...[REDACTED]` : '[REDACTED]';
99
+ } else {
100
+ redacted[key] = value;
101
+ }
102
+ });
103
+ return redacted;
104
+ }
105
+ }
106
+ export const redactor = KeyRedactor;
107
+
108
+ //# sourceMappingURL=key-redactor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/utils/key-redactor.js"],"sourcesContent":["/**\n * API Key Redaction Utility\n * Prevents sensitive data from leaking into logs, memory, or git commits\n */\n\nexport class KeyRedactor {\n static API_KEY_PATTERNS = [\n // Anthropic API keys\n /sk-ant-[a-zA-Z0-9_-]{95,}/gi,\n\n // OpenRouter API keys\n /sk-or-[a-zA-Z0-9_-]{32,}/gi,\n\n // Google/Gemini API keys\n /AIza[a-zA-Z0-9_-]{35}/gi,\n\n // Generic API keys\n /[a-zA-Z0-9_-]{20,}API[a-zA-Z0-9_-]{20,}/gi,\n\n // Bearer tokens\n /Bearer\\s+[a-zA-Z0-9_\\-\\.]{20,}/gi,\n\n // Environment variable format\n /([A-Z_]+_API_KEY|[A-Z_]+_TOKEN|[A-Z_]+_SECRET)=[\"']?([^\"'\\s]+)[\"']?/gi,\n\n // Supabase keys\n /eyJ[a-zA-Z0-9_-]*\\.eyJ[a-zA-Z0-9_-]*\\.[a-zA-Z0-9_-]*/gi,\n ];\n\n static SENSITIVE_FIELDS = [\n 'apiKey',\n 'api_key',\n 'token',\n 'secret',\n 'password',\n 'private_key',\n 'privateKey',\n 'accessToken',\n 'access_token',\n 'refreshToken',\n 'refresh_token',\n ];\n\n /**\n * Redact API keys and sensitive data from text\n */\n static redact(text, showPrefix = true) {\n if (!text) return text;\n\n let redacted = text;\n\n // Redact using patterns\n this.API_KEY_PATTERNS.forEach(pattern => {\n redacted = redacted.replace(pattern, (match) => {\n if (showPrefix && match.length > 8) {\n const prefix = match.substring(0, 8);\n return `${prefix}...[REDACTED]`;\n }\n return '[REDACTED_API_KEY]';\n });\n });\n\n return redacted;\n }\n\n /**\n * Redact sensitive fields in objects\n */\n static redactObject(obj, deep = true) {\n if (!obj || typeof obj !== 'object') return obj;\n\n const redacted = { ...obj };\n\n Object.keys(redacted).forEach(key => {\n const lowerKey = key.toLowerCase();\n\n // Check if field name is sensitive\n const isSensitive = this.SENSITIVE_FIELDS.some(field =>\n lowerKey.includes(field)\n );\n\n if (isSensitive && typeof redacted[key] === 'string') {\n const value = redacted[key];\n if (value && value.length > 8) {\n redacted[key] = `${value.substring(0, 4)}...[REDACTED]`;\n } else {\n redacted[key] = '[REDACTED]';\n }\n } else if (deep && typeof redacted[key] === 'object' && redacted[key] !== null) {\n redacted[key] = this.redactObject(redacted[key], deep);\n } else if (typeof redacted[key] === 'string') {\n // Redact any API keys in string values\n redacted[key] = this.redact(redacted[key]);\n }\n });\n\n return redacted;\n }\n\n /**\n * Sanitize text for safe logging\n */\n static sanitize(text) {\n return this.redact(text, true);\n }\n\n /**\n * Sanitize command arguments\n */\n static sanitizeArgs(args) {\n return args.map(arg => {\n // Check if arg is a flag value pair\n if (arg.includes('key') || arg.includes('token') || arg.includes('secret')) {\n return this.redact(arg);\n }\n return arg;\n });\n }\n\n /**\n * Check if text contains unredacted sensitive data\n */\n static containsSensitiveData(text) {\n return this.API_KEY_PATTERNS.some(pattern => pattern.test(text));\n }\n\n /**\n * Validate that text is safe for logging/storage\n */\n static validate(text) {\n const warnings = [];\n\n this.API_KEY_PATTERNS.forEach((pattern, index) => {\n if (pattern.test(text)) {\n warnings.push(`Potential API key detected (pattern ${index + 1})`);\n }\n });\n\n return {\n safe: warnings.length === 0,\n warnings,\n };\n }\n\n /**\n * Redact environment variables\n */\n static redactEnv(env) {\n const redacted = {};\n\n Object.keys(env).forEach(key => {\n const value = env[key];\n if (!value) {\n redacted[key] = '';\n return;\n }\n\n const lowerKey = key.toLowerCase();\n const isSensitive = lowerKey.includes('key') ||\n lowerKey.includes('token') ||\n lowerKey.includes('secret') ||\n lowerKey.includes('password');\n\n if (isSensitive) {\n redacted[key] = value.length > 8\n ? `${value.substring(0, 4)}...[REDACTED]`\n : '[REDACTED]';\n } else {\n redacted[key] = value;\n }\n });\n\n return redacted;\n }\n}\n\n// Export singleton instance\nexport const redactor = KeyRedactor;\n"],"names":["KeyRedactor","API_KEY_PATTERNS","SENSITIVE_FIELDS","redact","text","showPrefix","redacted","forEach","pattern","replace","match","length","prefix","substring","redactObject","obj","deep","Object","keys","key","lowerKey","toLowerCase","isSensitive","some","field","includes","value","sanitize","sanitizeArgs","args","map","arg","containsSensitiveData","test","validate","warnings","index","push","safe","redactEnv","env","redactor"],"mappings":"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"}