claude-flow-novice 2.14.15 → 2.14.16

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.
@@ -0,0 +1,382 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Agent Token Management CLI
4
+ * Generate, register, and manage agent tokens for MCP authentication
5
+ */ const crypto = require('crypto');
6
+ const Redis = require('redis');
7
+ const fs = require('fs').promises;
8
+ const path = require('path');
9
+ let AgentTokenManager = class AgentTokenManager {
10
+ constructor(options = {}){
11
+ this.redisUrl = options.redisUrl || process.env.MCP_REDIS_URL || 'redis://localhost:6379';
12
+ this.redis = null;
13
+ this.agentConfigPath = options.agentConfigPath || './config/agent-whitelist.json';
14
+ this.defaultExpiry = options.defaultExpiry || '24h';
15
+ }
16
+ async initialize() {
17
+ try {
18
+ this.redis = Redis.createClient({
19
+ url: this.redisUrl
20
+ });
21
+ await this.redis.connect();
22
+ console.log('Connected to Redis for token management');
23
+ } catch (error) {
24
+ console.error('Failed to connect to Redis:', error);
25
+ throw error;
26
+ }
27
+ }
28
+ async loadAgentConfig() {
29
+ try {
30
+ const configPath = path.resolve(this.agentConfigPath);
31
+ const config = await fs.readFile(configPath, 'utf8');
32
+ return JSON.parse(config);
33
+ } catch (error) {
34
+ console.error('Failed to load agent config:', error);
35
+ throw error;
36
+ }
37
+ }
38
+ generateToken() {
39
+ return crypto.randomBytes(32).toString('hex');
40
+ }
41
+ parseExpiry(expiry) {
42
+ if (typeof expiry === 'number') {
43
+ return expiry;
44
+ }
45
+ const match = expiry.match(/^(\d+)([smhd])$/);
46
+ if (!match) {
47
+ return 86400; // Default to 24 hours
48
+ }
49
+ const value = parseInt(match[1]);
50
+ const unit = match[2];
51
+ const multipliers = {
52
+ s: 1,
53
+ m: 60,
54
+ h: 3600,
55
+ d: 86400
56
+ };
57
+ return value * (multipliers[unit] || 86400);
58
+ }
59
+ async registerAgentToken(agentType, options = {}) {
60
+ try {
61
+ const config = await this.loadAgentConfig();
62
+ const agentConfig = config.agents.find((a)=>a.type === agentType);
63
+ if (!agentConfig) {
64
+ throw new Error(`Unknown agent type: ${agentType}. Available types: ${config.agents.map((a)=>a.type).join(', ')}`);
65
+ }
66
+ const token = this.generateToken();
67
+ const expiresIn = options.expiresIn || this.defaultExpiry;
68
+ const expiresAt = Date.now() + this.parseExpiry(expiresIn) * 1000;
69
+ const tokenData = {
70
+ token,
71
+ agentType,
72
+ displayName: agentConfig.displayName,
73
+ skills: agentConfig.skills,
74
+ allowedMcpServers: agentConfig.allowedMcpServers,
75
+ resourceLimits: agentConfig.resourceLimits,
76
+ expiresAt,
77
+ createdAt: Date.now(),
78
+ createdBy: options.createdBy || 'cli',
79
+ description: options.description || `Token for ${agentConfig.displayName}`
80
+ };
81
+ // Store in Redis
82
+ const key = `mcp:agent:${agentType}:${token}`;
83
+ const value = JSON.stringify(tokenData);
84
+ const ttlSeconds = this.parseExpiry(expiresIn);
85
+ await this.redis.setEx(key, ttlSeconds, value);
86
+ console.log(`✅ Token registered successfully!`);
87
+ console.log(` Agent Type: ${agentConfig.displayName} (${agentType})`);
88
+ console.log(` Token: ${token}`);
89
+ console.log(` Skills: ${agentConfig.skills.join(', ')}`);
90
+ console.log(` Allowed MCP Servers: ${agentConfig.allowedMcpServers.join(', ')}`);
91
+ console.log(` Expires: ${new Date(expiresAt).toISOString()}`);
92
+ console.log(` Memory Limit: ${agentConfig.resourceLimits.maxMemoryMB}MB`);
93
+ console.log(` Rate Limit: ${agentConfig.resourceLimits.maxRequestsPerMinute}/min`);
94
+ return tokenData;
95
+ } catch (error) {
96
+ console.error('❌ Failed to register token:', error.message);
97
+ throw error;
98
+ }
99
+ }
100
+ async listActiveTokens(agentType = null) {
101
+ try {
102
+ const pattern = agentType ? `mcp:agent:${agentType}:*` : 'mcp:agent:*';
103
+ const keys = await this.redis.keys(pattern);
104
+ const tokens = [];
105
+ for (const key of keys){
106
+ const value = await this.redis.get(key);
107
+ if (value) {
108
+ const tokenData = JSON.parse(value);
109
+ tokens.push({
110
+ ...tokenData,
111
+ key,
112
+ status: tokenData.expiresAt > Date.now() ? 'active' : 'expired'
113
+ });
114
+ }
115
+ }
116
+ if (tokens.length === 0) {
117
+ console.log('No active tokens found');
118
+ return [];
119
+ }
120
+ console.log(`\nActive Tokens (${tokens.length}):\n`);
121
+ console.log('Agent Type | Token | Expires At | Status');
122
+ console.log('-------------------|------------------------------------|------------------------------|--------');
123
+ for (const token of tokens){
124
+ const expiresAt = new Date(token.expiresAt).toISOString();
125
+ const tokenShort = token.token.substring(0, 32);
126
+ console.log(`${token.agentType.padEnd(17)} | ${tokenShort} | ${expiresAt} | ${token.status}`);
127
+ }
128
+ return tokens;
129
+ } catch (error) {
130
+ console.error('❌ Failed to list tokens:', error.message);
131
+ throw error;
132
+ }
133
+ }
134
+ async revokeToken(agentType, token) {
135
+ try {
136
+ const key = `mcp:agent:${agentType}:${token}`;
137
+ const exists = await this.redis.exists(key);
138
+ if (!exists) {
139
+ throw new Error(`Token not found for agent ${agentType}`);
140
+ }
141
+ await this.redis.del(key);
142
+ console.log(`✅ Token revoked successfully for agent ${agentType}`);
143
+ console.log(` Token: ${token}`);
144
+ } catch (error) {
145
+ console.error('❌ Failed to revoke token:', error.message);
146
+ throw error;
147
+ }
148
+ }
149
+ async revokeAllTokens(agentType = null) {
150
+ try {
151
+ const pattern = agentType ? `mcp:agent:${agentType}:*` : 'mcp:agent:*';
152
+ const keys = await this.redis.keys(pattern);
153
+ if (keys.length === 0) {
154
+ console.log('No tokens found to revoke');
155
+ return 0;
156
+ }
157
+ await this.redis.del(keys);
158
+ console.log(`✅ Revoked ${keys.length} tokens${agentType ? ` for agent ${agentType}` : ''}`);
159
+ return keys.length;
160
+ } catch (error) {
161
+ console.error('❌ Failed to revoke tokens:', error.message);
162
+ throw error;
163
+ }
164
+ }
165
+ async validateToken(agentType, token) {
166
+ try {
167
+ const key = `mcp:agent:${agentType}:${token}`;
168
+ const value = await this.redis.get(key);
169
+ if (!value) {
170
+ return {
171
+ valid: false,
172
+ reason: 'Token not found'
173
+ };
174
+ }
175
+ const tokenData = JSON.parse(value);
176
+ if (Date.now() > tokenData.expiresAt) {
177
+ await this.redis.del(key);
178
+ return {
179
+ valid: false,
180
+ reason: 'Token expired'
181
+ };
182
+ }
183
+ return {
184
+ valid: true,
185
+ tokenData
186
+ };
187
+ } catch (error) {
188
+ return {
189
+ valid: false,
190
+ reason: error.message
191
+ };
192
+ }
193
+ }
194
+ async getAgentInfo(agentType) {
195
+ try {
196
+ const config = await this.loadAgentConfig();
197
+ const agentConfig = config.agents.find((a)=>a.type === agentType);
198
+ if (!agentConfig) {
199
+ throw new Error(`Unknown agent type: ${agentType}`);
200
+ }
201
+ console.log(`\nAgent Information: ${agentConfig.displayName}`);
202
+ console.log('='.repeat(50));
203
+ console.log(`Type: ${agentConfig.type}`);
204
+ console.log(`Skills: ${agentConfig.skills.join(', ')}`);
205
+ console.log(`Allowed MCP Servers: ${agentConfig.allowedMcpServers.join(', ')}`);
206
+ console.log(`Memory Limit: ${agentConfig.resourceLimits.maxMemoryMB}MB`);
207
+ console.log(`Rate Limit: ${agentConfig.resourceLimits.maxRequestsPerMinute}/min`);
208
+ console.log(`Max Concurrent: ${agentConfig.resourceLimits.maxConcurrentRequests}`);
209
+ console.log(`Description: ${agentConfig.description}`);
210
+ return agentConfig;
211
+ } catch (error) {
212
+ console.error('❌ Failed to get agent info:', error.message);
213
+ throw error;
214
+ }
215
+ }
216
+ async listAgentTypes() {
217
+ try {
218
+ const config = await this.loadAgentConfig();
219
+ console.log(`\nAvailable Agent Types (${config.agents.length}):\n`);
220
+ console.log('Agent Type | Display Name | Skills Count');
221
+ console.log('------------------------|--------------------------------|-------------');
222
+ for (const agent of config.agents){
223
+ const type = agent.type.padEnd(22);
224
+ const name = agent.displayName.padEnd(32);
225
+ const skills = agent.skills.length;
226
+ console.log(`${type} | ${name} | ${skills}`);
227
+ }
228
+ return config.agents.map((a)=>a.type);
229
+ } catch (error) {
230
+ console.error('❌ Failed to list agent types:', error.message);
231
+ throw error;
232
+ }
233
+ }
234
+ async shutdown() {
235
+ if (this.redis) {
236
+ await this.redis.quit();
237
+ }
238
+ }
239
+ };
240
+ // CLI interface
241
+ async function main() {
242
+ const args = process.argv.slice(2);
243
+ const command = args[0];
244
+ if (!command) {
245
+ console.log(`
246
+ Agent Token Management CLI
247
+
248
+ Usage: node agent-token-manager.js <command> [options]
249
+
250
+ Commands:
251
+ register <agent-type> [options] Register a new token for an agent
252
+ list [agent-type] List active tokens
253
+ revoke <agent-type> <token> Revoke a specific token
254
+ revoke-all [agent-type] Revoke all tokens (optionally for specific agent)
255
+ validate <agent-type> <token> Validate a token
256
+ info <agent-type> Show agent information
257
+ types List available agent types
258
+
259
+ Options for 'register' command:
260
+ --expires-in <duration> Token expiry (e.g., 1h, 30m, 7d) [default: 24h]
261
+ --description <text> Token description
262
+ --created-by <identifier> Creator identifier
263
+
264
+ Examples:
265
+ # Register token for frontend engineer
266
+ node agent-token-manager.js register react-frontend-engineer
267
+
268
+ # Register token with custom expiry
269
+ node agent-token-manager.js register backend-developer --expires-in 2h
270
+
271
+ # List all active tokens
272
+ node agent-token-manager.js list
273
+
274
+ # List tokens for specific agent
275
+ node agent-token-manager.js list react-frontend-engineer
276
+
277
+ # Revoke a specific token
278
+ node agent-token-manager.js revoke react-frontend-engineer abc123...
279
+
280
+ # Get agent information
281
+ node agent-token-manager.js info security-specialist
282
+ `);
283
+ process.exit(0);
284
+ }
285
+ const tokenManager = new AgentTokenManager();
286
+ try {
287
+ await tokenManager.initialize();
288
+ switch(command){
289
+ case 'register':
290
+ {
291
+ const agentType = args[1];
292
+ if (!agentType) {
293
+ throw new Error('Agent type is required for register command');
294
+ }
295
+ const options = {};
296
+ for(let i = 2; i < args.length; i++){
297
+ if (args[i] === '--expires-in') {
298
+ options.expiresIn = args[++i];
299
+ } else if (args[i] === '--description') {
300
+ options.description = args[++i];
301
+ } else if (args[i] === '--created-by') {
302
+ options.createdBy = args[++i];
303
+ }
304
+ }
305
+ await tokenManager.registerAgentToken(agentType, options);
306
+ break;
307
+ }
308
+ case 'list':
309
+ {
310
+ const agentType = args[1];
311
+ await tokenManager.listActiveTokens(agentType);
312
+ break;
313
+ }
314
+ case 'revoke':
315
+ {
316
+ const agentType = args[1];
317
+ const token = args[2];
318
+ if (!agentType || !token) {
319
+ throw new Error('Agent type and token are required for revoke command');
320
+ }
321
+ await tokenManager.revokeToken(agentType, token);
322
+ break;
323
+ }
324
+ case 'revoke-all':
325
+ {
326
+ const agentType = args[1];
327
+ const count = await tokenManager.revokeAllTokens(agentType);
328
+ console.log(`Revoked ${count} tokens`);
329
+ break;
330
+ }
331
+ case 'validate':
332
+ {
333
+ const agentType = args[1];
334
+ const token = args[2];
335
+ if (!agentType || !token) {
336
+ throw new Error('Agent type and token are required for validate command');
337
+ }
338
+ const result = await tokenManager.validateToken(agentType, token);
339
+ if (result.valid) {
340
+ console.log('✅ Token is valid');
341
+ console.log(` Agent Type: ${result.tokenData.agentType}`);
342
+ console.log(` Skills: ${result.tokenData.skills.join(', ')}`);
343
+ console.log(` Expires: ${new Date(result.tokenData.expiresAt).toISOString()}`);
344
+ } else {
345
+ console.log('❌ Token is invalid');
346
+ console.log(` Reason: ${result.reason}`);
347
+ }
348
+ break;
349
+ }
350
+ case 'info':
351
+ {
352
+ const agentType = args[1];
353
+ if (!agentType) {
354
+ throw new Error('Agent type is required for info command');
355
+ }
356
+ await tokenManager.getAgentInfo(agentType);
357
+ break;
358
+ }
359
+ case 'types':
360
+ {
361
+ await tokenManager.listAgentTypes();
362
+ break;
363
+ }
364
+ default:
365
+ throw new Error(`Unknown command: ${command}`);
366
+ }
367
+ } catch (error) {
368
+ console.error('❌ Error:', error.message);
369
+ process.exit(1);
370
+ } finally{
371
+ await tokenManager.shutdown();
372
+ }
373
+ }
374
+ if (require.main === module) {
375
+ main().catch((error)=>{
376
+ console.error('Fatal error:', error);
377
+ process.exit(1);
378
+ });
379
+ }
380
+ module.exports = AgentTokenManager;
381
+
382
+ //# sourceMappingURL=agent-token-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/cli/agent-token-manager.js"],"sourcesContent":["#!/usr/bin/env node\r\n\r\n/**\r\n * Agent Token Management CLI\r\n * Generate, register, and manage agent tokens for MCP authentication\r\n */\r\n\r\nconst crypto = require('crypto');\r\nconst Redis = require('redis');\r\nconst fs = require('fs').promises;\r\nconst path = require('path');\r\n\r\nclass AgentTokenManager {\r\n constructor(options = {}) {\r\n this.redisUrl = options.redisUrl || process.env.MCP_REDIS_URL || 'redis://localhost:6379';\r\n this.redis = null;\r\n this.agentConfigPath = options.agentConfigPath || './config/agent-whitelist.json';\r\n this.defaultExpiry = options.defaultExpiry || '24h';\r\n }\r\n\r\n async initialize() {\r\n try {\r\n this.redis = Redis.createClient({ url: this.redisUrl });\r\n await this.redis.connect();\r\n console.log('Connected to Redis for token management');\r\n } catch (error) {\r\n console.error('Failed to connect to Redis:', error);\r\n throw error;\r\n }\r\n }\r\n\r\n async loadAgentConfig() {\r\n try {\r\n const configPath = path.resolve(this.agentConfigPath);\r\n const config = await fs.readFile(configPath, 'utf8');\r\n return JSON.parse(config);\r\n } catch (error) {\r\n console.error('Failed to load agent config:', error);\r\n throw error;\r\n }\r\n }\r\n\r\n generateToken() {\r\n return crypto.randomBytes(32).toString('hex');\r\n }\r\n\r\n parseExpiry(expiry) {\r\n if (typeof expiry === 'number') {\r\n return expiry;\r\n }\r\n\r\n const match = expiry.match(/^(\\d+)([smhd])$/);\r\n if (!match) {\r\n return 86400; // Default to 24 hours\r\n }\r\n\r\n const value = parseInt(match[1]);\r\n const unit = match[2];\r\n const multipliers = { s: 1, m: 60, h: 3600, d: 86400 };\r\n\r\n return value * (multipliers[unit] || 86400);\r\n }\r\n\r\n async registerAgentToken(agentType, options = {}) {\r\n try {\r\n const config = await this.loadAgentConfig();\r\n const agentConfig = config.agents.find(a => a.type === agentType);\r\n\r\n if (!agentConfig) {\r\n throw new Error(`Unknown agent type: ${agentType}. Available types: ${config.agents.map(a => a.type).join(', ')}`);\r\n }\r\n\r\n const token = this.generateToken();\r\n const expiresIn = options.expiresIn || this.defaultExpiry;\r\n const expiresAt = Date.now() + (this.parseExpiry(expiresIn) * 1000);\r\n\r\n const tokenData = {\r\n token,\r\n agentType,\r\n displayName: agentConfig.displayName,\r\n skills: agentConfig.skills,\r\n allowedMcpServers: agentConfig.allowedMcpServers,\r\n resourceLimits: agentConfig.resourceLimits,\r\n expiresAt,\r\n createdAt: Date.now(),\r\n createdBy: options.createdBy || 'cli',\r\n description: options.description || `Token for ${agentConfig.displayName}`\r\n };\r\n\r\n // Store in Redis\r\n const key = `mcp:agent:${agentType}:${token}`;\r\n const value = JSON.stringify(tokenData);\r\n const ttlSeconds = this.parseExpiry(expiresIn);\r\n\r\n await this.redis.setEx(key, ttlSeconds, value);\r\n\r\n console.log(`✅ Token registered successfully!`);\r\n console.log(` Agent Type: ${agentConfig.displayName} (${agentType})`);\r\n console.log(` Token: ${token}`);\r\n console.log(` Skills: ${agentConfig.skills.join(', ')}`);\r\n console.log(` Allowed MCP Servers: ${agentConfig.allowedMcpServers.join(', ')}`);\r\n console.log(` Expires: ${new Date(expiresAt).toISOString()}`);\r\n console.log(` Memory Limit: ${agentConfig.resourceLimits.maxMemoryMB}MB`);\r\n console.log(` Rate Limit: ${agentConfig.resourceLimits.maxRequestsPerMinute}/min`);\r\n\r\n return tokenData;\r\n\r\n } catch (error) {\r\n console.error('❌ Failed to register token:', error.message);\r\n throw error;\r\n }\r\n }\r\n\r\n async listActiveTokens(agentType = null) {\r\n try {\r\n const pattern = agentType ? `mcp:agent:${agentType}:*` : 'mcp:agent:*';\r\n const keys = await this.redis.keys(pattern);\r\n const tokens = [];\r\n\r\n for (const key of keys) {\r\n const value = await this.redis.get(key);\r\n if (value) {\r\n const tokenData = JSON.parse(value);\r\n tokens.push({\r\n ...tokenData,\r\n key,\r\n status: tokenData.expiresAt > Date.now() ? 'active' : 'expired'\r\n });\r\n }\r\n }\r\n\r\n if (tokens.length === 0) {\r\n console.log('No active tokens found');\r\n return [];\r\n }\r\n\r\n console.log(`\\nActive Tokens (${tokens.length}):\\n`);\r\n console.log('Agent Type | Token | Expires At | Status');\r\n console.log('-------------------|------------------------------------|------------------------------|--------');\r\n\r\n for (const token of tokens) {\r\n const expiresAt = new Date(token.expiresAt).toISOString();\r\n const tokenShort = token.token.substring(0, 32);\r\n console.log(`${token.agentType.padEnd(17)} | ${tokenShort} | ${expiresAt} | ${token.status}`);\r\n }\r\n\r\n return tokens;\r\n\r\n } catch (error) {\r\n console.error('❌ Failed to list tokens:', error.message);\r\n throw error;\r\n }\r\n }\r\n\r\n async revokeToken(agentType, token) {\r\n try {\r\n const key = `mcp:agent:${agentType}:${token}`;\r\n const exists = await this.redis.exists(key);\r\n\r\n if (!exists) {\r\n throw new Error(`Token not found for agent ${agentType}`);\r\n }\r\n\r\n await this.redis.del(key);\r\n console.log(`✅ Token revoked successfully for agent ${agentType}`);\r\n console.log(` Token: ${token}`);\r\n\r\n } catch (error) {\r\n console.error('❌ Failed to revoke token:', error.message);\r\n throw error;\r\n }\r\n }\r\n\r\n async revokeAllTokens(agentType = null) {\r\n try {\r\n const pattern = agentType ? `mcp:agent:${agentType}:*` : 'mcp:agent:*';\r\n const keys = await this.redis.keys(pattern);\r\n\r\n if (keys.length === 0) {\r\n console.log('No tokens found to revoke');\r\n return 0;\r\n }\r\n\r\n await this.redis.del(keys);\r\n console.log(`✅ Revoked ${keys.length} tokens${agentType ? ` for agent ${agentType}` : ''}`);\r\n return keys.length;\r\n\r\n } catch (error) {\r\n console.error('❌ Failed to revoke tokens:', error.message);\r\n throw error;\r\n }\r\n }\r\n\r\n async validateToken(agentType, token) {\r\n try {\r\n const key = `mcp:agent:${agentType}:${token}`;\r\n const value = await this.redis.get(key);\r\n\r\n if (!value) {\r\n return { valid: false, reason: 'Token not found' };\r\n }\r\n\r\n const tokenData = JSON.parse(value);\r\n\r\n if (Date.now() > tokenData.expiresAt) {\r\n await this.redis.del(key);\r\n return { valid: false, reason: 'Token expired' };\r\n }\r\n\r\n return {\r\n valid: true,\r\n tokenData\r\n };\r\n\r\n } catch (error) {\r\n return { valid: false, reason: error.message };\r\n }\r\n }\r\n\r\n async getAgentInfo(agentType) {\r\n try {\r\n const config = await this.loadAgentConfig();\r\n const agentConfig = config.agents.find(a => a.type === agentType);\r\n\r\n if (!agentConfig) {\r\n throw new Error(`Unknown agent type: ${agentType}`);\r\n }\r\n\r\n console.log(`\\nAgent Information: ${agentConfig.displayName}`);\r\n console.log('='.repeat(50));\r\n console.log(`Type: ${agentConfig.type}`);\r\n console.log(`Skills: ${agentConfig.skills.join(', ')}`);\r\n console.log(`Allowed MCP Servers: ${agentConfig.allowedMcpServers.join(', ')}`);\r\n console.log(`Memory Limit: ${agentConfig.resourceLimits.maxMemoryMB}MB`);\r\n console.log(`Rate Limit: ${agentConfig.resourceLimits.maxRequestsPerMinute}/min`);\r\n console.log(`Max Concurrent: ${agentConfig.resourceLimits.maxConcurrentRequests}`);\r\n console.log(`Description: ${agentConfig.description}`);\r\n\r\n return agentConfig;\r\n\r\n } catch (error) {\r\n console.error('❌ Failed to get agent info:', error.message);\r\n throw error;\r\n }\r\n }\r\n\r\n async listAgentTypes() {\r\n try {\r\n const config = await this.loadAgentConfig();\r\n\r\n console.log(`\\nAvailable Agent Types (${config.agents.length}):\\n`);\r\n console.log('Agent Type | Display Name | Skills Count');\r\n console.log('------------------------|--------------------------------|-------------');\r\n\r\n for (const agent of config.agents) {\r\n const type = agent.type.padEnd(22);\r\n const name = agent.displayName.padEnd(32);\r\n const skills = agent.skills.length;\r\n console.log(`${type} | ${name} | ${skills}`);\r\n }\r\n\r\n return config.agents.map(a => a.type);\r\n\r\n } catch (error) {\r\n console.error('❌ Failed to list agent types:', error.message);\r\n throw error;\r\n }\r\n }\r\n\r\n async shutdown() {\r\n if (this.redis) {\r\n await this.redis.quit();\r\n }\r\n }\r\n}\r\n\r\n// CLI interface\r\nasync function main() {\r\n const args = process.argv.slice(2);\r\n const command = args[0];\r\n\r\n if (!command) {\r\n console.log(`\r\nAgent Token Management CLI\r\n\r\nUsage: node agent-token-manager.js <command> [options]\r\n\r\nCommands:\r\n register <agent-type> [options] Register a new token for an agent\r\n list [agent-type] List active tokens\r\n revoke <agent-type> <token> Revoke a specific token\r\n revoke-all [agent-type] Revoke all tokens (optionally for specific agent)\r\n validate <agent-type> <token> Validate a token\r\n info <agent-type> Show agent information\r\n types List available agent types\r\n\r\nOptions for 'register' command:\r\n --expires-in <duration> Token expiry (e.g., 1h, 30m, 7d) [default: 24h]\r\n --description <text> Token description\r\n --created-by <identifier> Creator identifier\r\n\r\nExamples:\r\n # Register token for frontend engineer\r\n node agent-token-manager.js register react-frontend-engineer\r\n\r\n # Register token with custom expiry\r\n node agent-token-manager.js register backend-developer --expires-in 2h\r\n\r\n # List all active tokens\r\n node agent-token-manager.js list\r\n\r\n # List tokens for specific agent\r\n node agent-token-manager.js list react-frontend-engineer\r\n\r\n # Revoke a specific token\r\n node agent-token-manager.js revoke react-frontend-engineer abc123...\r\n\r\n # Get agent information\r\n node agent-token-manager.js info security-specialist\r\n`);\r\n process.exit(0);\r\n }\r\n\r\n const tokenManager = new AgentTokenManager();\r\n\r\n try {\r\n await tokenManager.initialize();\r\n\r\n switch (command) {\r\n case 'register': {\r\n const agentType = args[1];\r\n if (!agentType) {\r\n throw new Error('Agent type is required for register command');\r\n }\r\n\r\n const options = {};\r\n for (let i = 2; i < args.length; i++) {\r\n if (args[i] === '--expires-in') {\r\n options.expiresIn = args[++i];\r\n } else if (args[i] === '--description') {\r\n options.description = args[++i];\r\n } else if (args[i] === '--created-by') {\r\n options.createdBy = args[++i];\r\n }\r\n }\r\n\r\n await tokenManager.registerAgentToken(agentType, options);\r\n break;\r\n }\r\n\r\n case 'list': {\r\n const agentType = args[1];\r\n await tokenManager.listActiveTokens(agentType);\r\n break;\r\n }\r\n\r\n case 'revoke': {\r\n const agentType = args[1];\r\n const token = args[2];\r\n if (!agentType || !token) {\r\n throw new Error('Agent type and token are required for revoke command');\r\n }\r\n await tokenManager.revokeToken(agentType, token);\r\n break;\r\n }\r\n\r\n case 'revoke-all': {\r\n const agentType = args[1];\r\n const count = await tokenManager.revokeAllTokens(agentType);\r\n console.log(`Revoked ${count} tokens`);\r\n break;\r\n }\r\n\r\n case 'validate': {\r\n const agentType = args[1];\r\n const token = args[2];\r\n if (!agentType || !token) {\r\n throw new Error('Agent type and token are required for validate command');\r\n }\r\n\r\n const result = await tokenManager.validateToken(agentType, token);\r\n if (result.valid) {\r\n console.log('✅ Token is valid');\r\n console.log(` Agent Type: ${result.tokenData.agentType}`);\r\n console.log(` Skills: ${result.tokenData.skills.join(', ')}`);\r\n console.log(` Expires: ${new Date(result.tokenData.expiresAt).toISOString()}`);\r\n } else {\r\n console.log('❌ Token is invalid');\r\n console.log(` Reason: ${result.reason}`);\r\n }\r\n break;\r\n }\r\n\r\n case 'info': {\r\n const agentType = args[1];\r\n if (!agentType) {\r\n throw new Error('Agent type is required for info command');\r\n }\r\n await tokenManager.getAgentInfo(agentType);\r\n break;\r\n }\r\n\r\n case 'types': {\r\n await tokenManager.listAgentTypes();\r\n break;\r\n }\r\n\r\n default:\r\n throw new Error(`Unknown command: ${command}`);\r\n }\r\n\r\n } catch (error) {\r\n console.error('❌ Error:', error.message);\r\n process.exit(1);\r\n } finally {\r\n await tokenManager.shutdown();\r\n }\r\n}\r\n\r\nif (require.main === module) {\r\n main().catch(error => {\r\n console.error('Fatal error:', error);\r\n process.exit(1);\r\n });\r\n}\r\n\r\nmodule.exports = AgentTokenManager;"],"names":["crypto","require","Redis","fs","promises","path","AgentTokenManager","options","redisUrl","process","env","MCP_REDIS_URL","redis","agentConfigPath","defaultExpiry","initialize","createClient","url","connect","console","log","error","loadAgentConfig","configPath","resolve","config","readFile","JSON","parse","generateToken","randomBytes","toString","parseExpiry","expiry","match","value","parseInt","unit","multipliers","s","m","h","d","registerAgentToken","agentType","agentConfig","agents","find","a","type","Error","map","join","token","expiresIn","expiresAt","Date","now","tokenData","displayName","skills","allowedMcpServers","resourceLimits","createdAt","createdBy","description","key","stringify","ttlSeconds","setEx","toISOString","maxMemoryMB","maxRequestsPerMinute","message","listActiveTokens","pattern","keys","tokens","get","push","status","length","tokenShort","substring","padEnd","revokeToken","exists","del","revokeAllTokens","validateToken","valid","reason","getAgentInfo","repeat","maxConcurrentRequests","listAgentTypes","agent","name","shutdown","quit","main","args","argv","slice","command","exit","tokenManager","i","count","result","module","catch","exports"],"mappings":"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"}
@@ -1,118 +1,100 @@
1
- "use strict";
2
- var __awaiter = this && this.__awaiter || function(thisArg, _arguments, P, generator) {
3
- function adopt(value) {
4
- return value instanceof P ? value : new P(function(resolve) {
5
- resolve(value);
6
- });
1
+ import * as fs from "fs/promises";
2
+ import * as path from "path";
3
+ import Ajv from "ajv";
4
+ import * as lodash from "lodash";
5
+ let ConfigManager = class ConfigManager {
6
+ static _instance = null;
7
+ configPath;
8
+ schemaPath;
9
+ ajv;
10
+ constructor(){
11
+ this.configPath = path.join(process.env.HOME || "", ".claude-flow-config.json");
12
+ this.schemaPath = path.join(__dirname, "../../.claude/skills/config-management/config.json");
13
+ this.ajv = new Ajv();
7
14
  }
8
- return new (P || (P = Promise))(function(resolve, reject) {
9
- function fulfilled(value) {
10
- try {
11
- step(generator.next(value));
12
- } catch (e) {
13
- reject(e);
14
- }
15
+ static getInstance() {
16
+ if (!ConfigManager._instance) {
17
+ ConfigManager._instance = new ConfigManager();
15
18
  }
16
- function rejected(value) {
17
- try {
18
- step(generator["throw"](value));
19
- } catch (e) {
20
- reject(e);
21
- }
19
+ return ConfigManager._instance;
20
+ }
21
+ async readConfig() {
22
+ try {
23
+ const configContent = await fs.readFile(this.configPath, "utf-8");
24
+ return JSON.parse(configContent);
25
+ } catch (error) {
26
+ // If config doesn't exist, create from schema
27
+ return this.resetToDefaults();
22
28
  }
23
- function step(result) {
24
- result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
29
+ }
30
+ async writeConfig(config) {
31
+ const schemaContent = await fs.readFile(this.schemaPath, "utf-8");
32
+ const schema = JSON.parse(schemaContent);
33
+ const validate = this.ajv.compile(schema);
34
+ if (!validate(config)) {
35
+ throw new Error("Invalid configuration: " + this.ajv.errorsText(validate.errors));
25
36
  }
26
- step((generator = generator.apply(thisArg, _arguments || [])).next());
27
- });
28
- };
29
- var __generator = this && this.__generator || function(thisArg, body) {
30
- var _ = {
31
- label: 0,
32
- sent: function() {
33
- if (t[0] & 1) throw t[1];
34
- return t[1];
35
- },
36
- trys: [],
37
- ops: []
38
- }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
39
- return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() {
40
- return this;
41
- }), g;
42
- function verb(n) {
43
- return function(v) {
44
- return step([
45
- n,
46
- v
47
- ]);
48
- };
37
+ await fs.writeFile(this.configPath, JSON.stringify(config, null, 2), "utf-8");
49
38
  }
50
- function step(op) {
51
- if (f) throw new TypeError("Generator is already executing.");
52
- while(g && (g = 0, op[0] && (_ = 0)), _)try {
53
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
54
- if (y = 0, t) op = [
55
- op[0] & 2,
56
- t.value
57
- ];
58
- switch(op[0]){
59
- case 0:
60
- case 1:
61
- t = op;
62
- break;
63
- case 4:
64
- _.label++;
65
- return {
66
- value: op[1],
67
- done: false
68
- };
69
- case 5:
70
- _.label++;
71
- y = op[1];
72
- op = [
73
- 0
74
- ];
75
- continue;
76
- case 7:
77
- op = _.ops.pop();
78
- _.trys.pop();
79
- continue;
80
- default:
81
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
82
- _ = 0;
83
- continue;
84
- }
85
- if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
86
- _.label = op[1];
87
- break;
88
- }
89
- if (op[0] === 6 && _.label < t[1]) {
90
- _.label = t[1];
91
- t = op;
92
- break;
93
- }
94
- if (t && _.label < t[2]) {
95
- _.label = t[2];
96
- _.ops.push(op);
97
- break;
98
- }
99
- if (t[2]) _.ops.pop();
100
- _.trys.pop();
101
- continue;
102
- }
103
- op = body.call(thisArg, _);
104
- } catch (e) {
105
- op = [
106
- 6,
107
- e
108
- ];
109
- y = 0;
110
- } finally{
111
- f = t = 0;
39
+ async getValue(keyPath) {
40
+ const config = await this.readConfig();
41
+ const value = lodash.get(config, keyPath);
42
+ if (value === undefined) {
43
+ // Check if it's a custom key path not in the schema
44
+ const customConfig = await this.readCustomConfig();
45
+ return lodash.get(customConfig, keyPath);
112
46
  }
113
- if (op[0] & 5) throw op[1];
114
- return {
115
- value: op[0] ? op[1] : void 0,
47
+ return value;
48
+ }
49
+ async readCustomConfig() {
50
+ try {
51
+ const customConfigPath = path.join(process.env.HOME || "", ".claude-flow-custom-config.json");
52
+ const customConfigContent = await fs.readFile(customConfigPath, "utf-8");
53
+ return JSON.parse(customConfigContent);
54
+ } catch (error) {
55
+ // If custom config doesn't exist or can't be read, return empty object
56
+ return {};
57
+ }
58
+ }
59
+ async set(key, value) {
60
+ const config = await this.readConfig();
61
+ // Type assertion to handle full object
62
+ if (typeof value === "object" && value !== null) {
63
+ config[key] = value;
64
+ } else {
65
+ throw new Error("Invalid configuration value");
66
+ }
67
+ await this.writeConfig(config);
68
+ }
69
+ async getAll() {
70
+ return this.readConfig();
71
+ }
72
+ async resetToDefaults() {
73
+ const schemaContent = await fs.readFile(this.schemaPath, "utf-8");
74
+ const schema = JSON.parse(schemaContent);
75
+ // Extract default values from the schema
76
+ const defaultConfig = {
77
+ redis: {
78
+ host: schema.properties.redis.properties.host.default,
79
+ port: schema.properties.redis.properties.port.default
80
+ },
81
+ agent: {
82
+ default_strategy: schema.properties.agent.properties.default_strategy.default,
83
+ max_concurrent_agents: schema.properties.agent.properties.max_concurrent_agents.default,
84
+ log_level: schema.properties.agent.properties.log_level.default
85
+ },
86
+ security: {
87
+ enabled: schema.properties.security.properties.enabled.default,
88
+ max_retry_attempts: schema.properties.security.properties.max_retry_attempts.default
89
+ }
90
+ };
91
+ await this.writeConfig(defaultConfig);
92
+ return defaultConfig;
93
+ }
94
+ };
95
+ export default ConfigManager;
96
+
97
+ //# sourceMappingURL=config-manager.js.mapop[1] : void 0,
116
98
  done: true
117
99
  };
118
100
  }