claude-flow 2.7.29 → 2.7.30
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.
- package/CHANGELOG.md +73 -0
- package/bin/claude-flow +1 -1
- package/dist/src/cli/help-formatter.js +0 -5
- package/dist/src/cli/simple-cli.js +0 -104
- package/dist/src/cli/simple-cli.js.map +1 -1
- package/dist/src/cli/validation-helper.js.map +1 -1
- package/dist/src/core/version.js +1 -1
- package/dist/src/core/version.js.map +1 -1
- package/dist/src/utils/key-redactor.js.map +1 -1
- package/dist/src/utils/metrics-reader.js +29 -41
- package/dist/src/utils/metrics-reader.js.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/cli/validation-helper.
|
|
1
|
+
{"version":3,"sources":["../../../src/cli/validation-helper.ts"],"sourcesContent":["/**\n * CLI Parameter Validation Helper\n * Provides standardized error messages for invalid parameters\n */\n\nimport { HelpFormatter } from './help-formatter.js';\n\nexport class ValidationHelper {\n /**\n * Validate enum parameter\n */\n static validateEnum(\n value: string,\n paramName: string,\n validOptions: string[],\n commandPath: string,\n ): void {\n if (!validOptions.includes(value)) {\n console.error(\n HelpFormatter.formatValidationError(value, paramName, validOptions, commandPath),\n );\n process.exit(1);\n }\n }\n\n /**\n * Validate numeric parameter\n */\n static validateNumber(\n value: string,\n paramName: string,\n min?: number,\n max?: number,\n commandPath?: string,\n ): number {\n const num = parseInt(value, 10);\n\n if (isNaN(num)) {\n console.error(\n HelpFormatter.formatError(\n `'${value}' is not a valid number for ${paramName}.`,\n commandPath || 'claude-flow',\n ),\n );\n process.exit(1);\n }\n\n if (min !== undefined && num < min) {\n console.error(\n HelpFormatter.formatError(\n `${paramName} must be at least ${min}. Got: ${num}`,\n commandPath || 'claude-flow',\n ),\n );\n process.exit(1);\n }\n\n if (max !== undefined && num > max) {\n console.error(\n HelpFormatter.formatError(\n `${paramName} must be at most ${max}. Got: ${num}`,\n commandPath || 'claude-flow',\n ),\n );\n process.exit(1);\n }\n\n return num;\n }\n\n /**\n * Validate required parameter\n */\n static validateRequired(value: any, paramName: string, commandPath?: string): void {\n if (!value || (typeof value === 'string' && value.trim() === '')) {\n console.error(\n HelpFormatter.formatError(\n `Missing required parameter: ${paramName}`,\n commandPath || 'claude-flow',\n ),\n );\n process.exit(1);\n }\n }\n\n /**\n * Validate file path exists\n */\n static async validateFilePath(\n path: string,\n paramName: string,\n commandPath?: string,\n ): Promise<void> {\n try {\n const fs = await import('fs/promises');\n await fs.access(path);\n } catch (error) {\n console.error(\n HelpFormatter.formatError(\n `File not found for ${paramName}: ${path}`,\n commandPath || 'claude-flow',\n ),\n );\n process.exit(1);\n }\n }\n\n /**\n * Validate boolean flag\n */\n static validateBoolean(value: string, paramName: string, commandPath?: string): boolean {\n const lowerValue = value.toLowerCase();\n if (lowerValue === 'true' || lowerValue === '1' || lowerValue === 'yes') {\n return true;\n }\n if (lowerValue === 'false' || lowerValue === '0' || lowerValue === 'no') {\n return false;\n }\n\n console.error(\n HelpFormatter.formatError(\n `'${value}' is not a valid boolean for ${paramName}. Use: true, false, yes, no, 1, or 0.`,\n commandPath || 'claude-flow',\n ),\n );\n process.exit(1);\n }\n}\n"],"names":["HelpFormatter","ValidationHelper","validateEnum","value","paramName","validOptions","commandPath","includes","console","error","formatValidationError","process","exit","validateNumber","min","max","num","parseInt","isNaN","formatError","undefined","validateRequired","trim","validateFilePath","path","fs","access","validateBoolean","lowerValue","toLowerCase"],"mappings":"AAKA,SAASA,aAAa,QAAQ,sBAAsB;AAEpD,OAAO,MAAMC;IAIX,OAAOC,aACLC,KAAa,EACbC,SAAiB,EACjBC,YAAsB,EACtBC,WAAmB,EACb;QACN,IAAI,CAACD,aAAaE,QAAQ,CAACJ,QAAQ;YACjCK,QAAQC,KAAK,CACXT,cAAcU,qBAAqB,CAACP,OAAOC,WAAWC,cAAcC;YAEtEK,QAAQC,IAAI,CAAC;QACf;IACF;IAKA,OAAOC,eACLV,KAAa,EACbC,SAAiB,EACjBU,GAAY,EACZC,GAAY,EACZT,WAAoB,EACZ;QACR,MAAMU,MAAMC,SAASd,OAAO;QAE5B,IAAIe,MAAMF,MAAM;YACdR,QAAQC,KAAK,CACXT,cAAcmB,WAAW,CACvB,CAAC,CAAC,EAAEhB,MAAM,4BAA4B,EAAEC,UAAU,CAAC,CAAC,EACpDE,eAAe;YAGnBK,QAAQC,IAAI,CAAC;QACf;QAEA,IAAIE,QAAQM,aAAaJ,MAAMF,KAAK;YAClCN,QAAQC,KAAK,CACXT,cAAcmB,WAAW,CACvB,GAAGf,UAAU,kBAAkB,EAAEU,IAAI,OAAO,EAAEE,KAAK,EACnDV,eAAe;YAGnBK,QAAQC,IAAI,CAAC;QACf;QAEA,IAAIG,QAAQK,aAAaJ,MAAMD,KAAK;YAClCP,QAAQC,KAAK,CACXT,cAAcmB,WAAW,CACvB,GAAGf,UAAU,iBAAiB,EAAEW,IAAI,OAAO,EAAEC,KAAK,EAClDV,eAAe;YAGnBK,QAAQC,IAAI,CAAC;QACf;QAEA,OAAOI;IACT;IAKA,OAAOK,iBAAiBlB,KAAU,EAAEC,SAAiB,EAAEE,WAAoB,EAAQ;QACjF,IAAI,CAACH,SAAU,OAAOA,UAAU,YAAYA,MAAMmB,IAAI,OAAO,IAAK;YAChEd,QAAQC,KAAK,CACXT,cAAcmB,WAAW,CACvB,CAAC,4BAA4B,EAAEf,WAAW,EAC1CE,eAAe;YAGnBK,QAAQC,IAAI,CAAC;QACf;IACF;IAKA,aAAaW,iBACXC,IAAY,EACZpB,SAAiB,EACjBE,WAAoB,EACL;QACf,IAAI;YACF,MAAMmB,KAAK,MAAM,MAAM,CAAC;YACxB,MAAMA,GAAGC,MAAM,CAACF;QAClB,EAAE,OAAOf,OAAO;YACdD,QAAQC,KAAK,CACXT,cAAcmB,WAAW,CACvB,CAAC,mBAAmB,EAAEf,UAAU,EAAE,EAAEoB,MAAM,EAC1ClB,eAAe;YAGnBK,QAAQC,IAAI,CAAC;QACf;IACF;IAKA,OAAOe,gBAAgBxB,KAAa,EAAEC,SAAiB,EAAEE,WAAoB,EAAW;QACtF,MAAMsB,aAAazB,MAAM0B,WAAW;QACpC,IAAID,eAAe,UAAUA,eAAe,OAAOA,eAAe,OAAO;YACvE,OAAO;QACT;QACA,IAAIA,eAAe,WAAWA,eAAe,OAAOA,eAAe,MAAM;YACvE,OAAO;QACT;QAEApB,QAAQC,KAAK,CACXT,cAAcmB,WAAW,CACvB,CAAC,CAAC,EAAEhB,MAAM,6BAA6B,EAAEC,UAAU,qCAAqC,CAAC,EACzFE,eAAe;QAGnBK,QAAQC,IAAI,CAAC;IACf;AACF"}
|
package/dist/src/core/version.js
CHANGED
|
@@ -12,7 +12,7 @@ try {
|
|
|
12
12
|
BUILD_DATE = new Date().toISOString().split('T')[0];
|
|
13
13
|
} catch (error) {
|
|
14
14
|
console.warn('Warning: Could not read version from package.json, using fallback');
|
|
15
|
-
VERSION = '2.0.0-alpha.
|
|
15
|
+
VERSION = '2.0.0-alpha.101';
|
|
16
16
|
BUILD_DATE = new Date().toISOString().split('T')[0];
|
|
17
17
|
}
|
|
18
18
|
export { VERSION, BUILD_DATE };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/version.
|
|
1
|
+
{"version":3,"sources":["../../../src/core/version.js"],"sourcesContent":["/**\n * Centralized version management (JavaScript version)\n * Reads version from package.json to ensure consistency\n */\n\nimport { readFileSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { fileURLToPath } from 'url';\n\n// Get the directory of this module\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n// Read version from package.json\nlet VERSION;\nlet BUILD_DATE;\n\ntry {\n // Navigate to project root and read package.json\n const packageJsonPath = join(__dirname, '../../package.json');\n const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\n VERSION = packageJson.version;\n BUILD_DATE = new Date().toISOString().split('T')[0];\n} catch (error) {\n // Fallback version if package.json can't be read\n console.warn('Warning: Could not read version from package.json, using fallback');\n VERSION = '2.0.0-alpha.101';\n BUILD_DATE = new Date().toISOString().split('T')[0];\n}\n\nexport { VERSION, BUILD_DATE };\n\n// Helper function to get formatted version string\nexport function getVersionString(includeV = true) {\n return includeV ? `v${VERSION}` : VERSION;\n}\n\n// Helper function for version display in CLI\nexport function displayVersion() {\n console.log(getVersionString());\n}"],"names":["readFileSync","join","dirname","fileURLToPath","__filename","url","__dirname","VERSION","BUILD_DATE","packageJsonPath","packageJson","JSON","parse","version","Date","toISOString","split","error","console","warn","getVersionString","includeV","displayVersion","log"],"mappings":"AAKA,SAASA,YAAY,QAAQ,KAAK;AAClC,SAASC,IAAI,EAAEC,OAAO,QAAQ,OAAO;AACrC,SAASC,aAAa,QAAQ,MAAM;AAGpC,MAAMC,aAAaD,cAAc,YAAYE,GAAG;AAChD,MAAMC,YAAYJ,QAAQE;AAG1B,IAAIG;AACJ,IAAIC;AAEJ,IAAI;IAEF,MAAMC,kBAAkBR,KAAKK,WAAW;IACxC,MAAMI,cAAcC,KAAKC,KAAK,CAACZ,aAAaS,iBAAiB;IAC7DF,UAAUG,YAAYG,OAAO;IAC7BL,aAAa,IAAIM,OAAOC,WAAW,GAAGC,KAAK,CAAC,IAAI,CAAC,EAAE;AACrD,EAAE,OAAOC,OAAO;IAEdC,QAAQC,IAAI,CAAC;IACbZ,UAAU;IACVC,aAAa,IAAIM,OAAOC,WAAW,GAAGC,KAAK,CAAC,IAAI,CAAC,EAAE;AACrD;AAEA,SAAST,OAAO,EAAEC,UAAU,GAAG;AAG/B,OAAO,SAASY,iBAAiBC,WAAW,IAAI;IAC9C,OAAOA,WAAW,CAAC,CAAC,EAAEd,SAAS,GAAGA;AACpC;AAGA,OAAO,SAASe;IACdJ,QAAQK,GAAG,CAACH;AACd"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/utils/key-redactor.
|
|
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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"},GAAG,CAACrB,IAAI;YACtB,IAAI,CAACO,OAAO;gBACVpB,QAAQ,CAACa,IAAI,GAAG;gBAChB;YACF;YAEA,MAAMC,WAAWD,IAAIE,WAAW;YAChC,MAAMC,cAAcF,SAASK,QAAQ,CAAC,UACnBL,SAASK,QAAQ,CAAC,YAClBL,SAASK,QAAQ,CAAC,aAClBL,SAASK,QAAQ,CAAC;YAErC,IAAIH,aAAa;gBACfhB,QAAQ,CAACa,IAAI,GAAGO,MAAMf,MAAM,GAAG,IAC3B,GAAGe,MAAMb,SAAS,CAAC,GAAG,GAAG,aAAa,CAAC,GACvC;YACN,OAAO;gBACLP,QAAQ,CAACa,IAAI,GAAGO;YAClB;QACF;QAEA,OAAOpB;IACT;AACF;AAGA,OAAO,MAAMmC,WAAWzC,YAAY"}
|
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
import
|
|
2
|
-
import path from 'path';
|
|
1
|
+
import * as fs from 'fs/promises';
|
|
2
|
+
import * as path from 'path';
|
|
3
3
|
import { exec } from 'child_process';
|
|
4
4
|
import { promisify } from 'util';
|
|
5
5
|
const execAsync = promisify(exec);
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
this.sessionsDir = '.claude-flow/sessions';
|
|
10
|
-
}
|
|
6
|
+
export class MetricsReader {
|
|
7
|
+
metricsDir = '.claude-flow/metrics';
|
|
8
|
+
sessionsDir = '.claude-flow/sessions';
|
|
11
9
|
async getSystemMetrics() {
|
|
12
10
|
try {
|
|
13
11
|
const filePath = path.join(this.metricsDir, 'system-metrics.json');
|
|
@@ -18,15 +16,6 @@ let MetricsReader = class MetricsReader {
|
|
|
18
16
|
return null;
|
|
19
17
|
}
|
|
20
18
|
}
|
|
21
|
-
async getTaskQueue() {
|
|
22
|
-
try {
|
|
23
|
-
const queueFile = '.claude-flow/tasks/queue.json';
|
|
24
|
-
const content = await fs.readFile(queueFile, 'utf8');
|
|
25
|
-
return JSON.parse(content);
|
|
26
|
-
} catch (error) {
|
|
27
|
-
return [];
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
19
|
async getTaskMetrics() {
|
|
31
20
|
try {
|
|
32
21
|
const filePath = path.join(this.metricsDir, 'task-metrics.json');
|
|
@@ -47,30 +36,30 @@ let MetricsReader = class MetricsReader {
|
|
|
47
36
|
}
|
|
48
37
|
async getActiveAgents() {
|
|
49
38
|
try {
|
|
39
|
+
const perfMetrics = await this.getPerformanceMetrics();
|
|
40
|
+
const sessionFiles = await this.getSessionFiles();
|
|
50
41
|
const agents = [];
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
if (
|
|
56
|
-
|
|
57
|
-
const content = await fs.readFile(path.join(agentsDir, file), 'utf8');
|
|
58
|
-
const agent = JSON.parse(content);
|
|
59
|
-
agents.push(agent);
|
|
60
|
-
} catch {}
|
|
42
|
+
for (const file of sessionFiles){
|
|
43
|
+
try {
|
|
44
|
+
const content = await fs.readFile(path.join(this.sessionsDir, 'pair', file), 'utf8');
|
|
45
|
+
const sessionData = JSON.parse(content);
|
|
46
|
+
if (sessionData.agents && Array.isArray(sessionData.agents)) {
|
|
47
|
+
agents.push(...sessionData.agents);
|
|
61
48
|
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
if (agents.length === 0) {
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
49
|
+
} catch {}
|
|
50
|
+
}
|
|
51
|
+
if (agents.length === 0 && perfMetrics) {
|
|
52
|
+
const activeCount = perfMetrics.activeAgents || 0;
|
|
53
|
+
const totalCount = perfMetrics.totalAgents || 0;
|
|
54
|
+
for(let i = 0; i < totalCount; i++){
|
|
55
|
+
agents.push({
|
|
56
|
+
id: `agent-${i + 1}`,
|
|
57
|
+
name: `Agent ${i + 1}`,
|
|
58
|
+
type: i === 0 ? 'orchestrator' : 'worker',
|
|
59
|
+
status: i < activeCount ? 'active' : 'idle',
|
|
60
|
+
activeTasks: i < activeCount ? 1 : 0,
|
|
61
|
+
lastActivity: Date.now() - i * 1000
|
|
62
|
+
});
|
|
74
63
|
}
|
|
75
64
|
}
|
|
76
65
|
return agents;
|
|
@@ -146,7 +135,7 @@ let MetricsReader = class MetricsReader {
|
|
|
146
135
|
}
|
|
147
136
|
async getMCPServerStatus() {
|
|
148
137
|
try {
|
|
149
|
-
const { stdout } = await execAsync('ps aux | grep -E "mcp" | grep -v grep | wc -l');
|
|
138
|
+
const { stdout } = await execAsync('ps aux | grep -E "mcp-server\\.js|claude-flow mcp start" | grep -v grep | wc -l');
|
|
150
139
|
const processCount = parseInt(stdout.trim(), 10);
|
|
151
140
|
const { stdout: orchestratorOut } = await execAsync('ps aux | grep -E "claude-flow start" | grep -v grep | wc -l');
|
|
152
141
|
const orchestratorRunning = parseInt(orchestratorOut.trim(), 10) > 0;
|
|
@@ -175,7 +164,6 @@ let MetricsReader = class MetricsReader {
|
|
|
175
164
|
};
|
|
176
165
|
}
|
|
177
166
|
}
|
|
178
|
-
}
|
|
179
|
-
export { MetricsReader };
|
|
167
|
+
}
|
|
180
168
|
|
|
181
169
|
//# sourceMappingURL=metrics-reader.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/utils/metrics-reader.js"],"sourcesContent":["import { promises as fs } from 'fs';\nimport path from 'path';\nimport { exec } from 'child_process';\nimport { promisify } from 'util';\n\nconst execAsync = promisify(exec);\n\nclass MetricsReader {\n constructor() {\n this.metricsDir = '.claude-flow/metrics';\n this.sessionsDir = '.claude-flow/sessions';\n }\n\n async getSystemMetrics() {\n try {\n const filePath = path.join(this.metricsDir, 'system-metrics.json');\n const content = await fs.readFile(filePath, 'utf8');\n const metrics = JSON.parse(content);\n \n // Return the most recent metric\n return metrics.length > 0 ? metrics[metrics.length - 1] : null;\n } catch (error) {\n return null;\n }\n }\n\n async getTaskQueue() {\n try {\n const queueFile = '.claude-flow/tasks/queue.json';\n const content = await fs.readFile(queueFile, 'utf8');\n return JSON.parse(content);\n } catch (error) {\n return [];\n }\n }\n\n async getTaskMetrics() {\n try {\n const filePath = path.join(this.metricsDir, 'task-metrics.json');\n const content = await fs.readFile(filePath, 'utf8');\n return JSON.parse(content);\n } catch (error) {\n return [];\n }\n }\n\n async getPerformanceMetrics() {\n try {\n const filePath = path.join(this.metricsDir, 'performance.json');\n const content = await fs.readFile(filePath, 'utf8');\n return JSON.parse(content);\n } catch (error) {\n return null;\n }\n }\n\n async getActiveAgents() {\n try {\n const agents = [];\n \n // Check for agents in the .claude-flow/agents directory\n const agentsDir = '.claude-flow/agents';\n try {\n const agentFiles = await fs.readdir(agentsDir);\n for (const file of agentFiles) {\n if (file.endsWith('.json')) {\n try {\n const content = await fs.readFile(path.join(agentsDir, file), 'utf8');\n const agent = JSON.parse(content);\n agents.push(agent);\n } catch {\n // Skip invalid agent files\n }\n }\n }\n } catch {\n // Agents directory doesn't exist yet\n }\n \n // If no agents found in directory, check session files\n if (agents.length === 0) {\n const sessionFiles = await this.getSessionFiles();\n for (const file of sessionFiles) {\n try {\n const content = await fs.readFile(path.join(this.sessionsDir, 'pair', file), 'utf8');\n const sessionData = JSON.parse(content);\n \n if (sessionData.agents && Array.isArray(sessionData.agents)) {\n agents.push(...sessionData.agents);\n }\n } catch {\n // Skip invalid session files\n }\n }\n }\n \n return agents;\n } catch (error) {\n return [];\n }\n }\n\n async getSessionStatus() {\n try {\n const sessionFiles = await this.getSessionFiles();\n \n if (sessionFiles.length === 0) {\n return null;\n }\n \n // Get the most recent session\n const mostRecentFile = sessionFiles[sessionFiles.length - 1];\n const content = await fs.readFile(path.join(this.sessionsDir, 'pair', mostRecentFile), 'utf8');\n return JSON.parse(content);\n } catch (error) {\n return null;\n }\n }\n\n async getRecentTasks(limit = 10) {\n try {\n const taskMetrics = await this.getTaskMetrics();\n \n // Sort by timestamp descending and take the limit\n return taskMetrics\n .sort((a, b) => b.timestamp - a.timestamp)\n .slice(0, limit)\n .map(task => ({\n id: task.id,\n type: task.type,\n status: task.success ? 'completed' : 'failed',\n startTime: task.timestamp - task.duration,\n endTime: task.timestamp,\n duration: task.duration\n }));\n } catch (error) {\n return [];\n }\n }\n\n async getOverallHealth() {\n try {\n const systemMetrics = await this.getSystemMetrics();\n const perfMetrics = await this.getPerformanceMetrics();\n \n if (!systemMetrics && !perfMetrics) {\n return 'error';\n }\n \n // Check memory usage\n if (systemMetrics && systemMetrics.memoryUsagePercent > 90) {\n return 'error';\n }\n \n if (systemMetrics && systemMetrics.memoryUsagePercent > 75) {\n return 'warning';\n }\n \n // Check CPU load\n if (systemMetrics && systemMetrics.cpuLoad > 0.8) {\n return 'warning';\n }\n \n // Check task failure rate\n if (perfMetrics && perfMetrics.totalTasks > 0) {\n const failureRate = perfMetrics.failedTasks / perfMetrics.totalTasks;\n if (failureRate > 0.5) {\n return 'error';\n }\n if (failureRate > 0.2) {\n return 'warning';\n }\n }\n \n return 'healthy';\n } catch (error) {\n return 'error';\n }\n }\n\n async getSessionFiles() {\n try {\n const files = await fs.readdir(path.join(this.sessionsDir, 'pair'));\n return files.filter(f => f.endsWith('.json')).sort();\n } catch (error) {\n return [];\n }\n }\n\n async getMCPServerStatus() {\n try {\n // Check if MCP server process is running (including flow-nexus and other MCP variants)\n const { stdout } = await execAsync('ps aux | grep -E \"mcp\" | grep -v grep | wc -l');\n const processCount = parseInt(stdout.trim(), 10);\n \n // Check for orchestrator running\n const { stdout: orchestratorOut } = await execAsync('ps aux | grep -E \"claude-flow start\" | grep -v grep | wc -l');\n const orchestratorRunning = parseInt(orchestratorOut.trim(), 10) > 0;\n \n // Determine status\n const isRunning = processCount > 0;\n \n // Try to get port from process (default is 3000)\n let port = 3000;\n try {\n const { stdout: portOut } = await execAsync('lsof -i :3000 2>/dev/null | grep LISTEN | wc -l');\n if (parseInt(portOut.trim(), 10) === 0) {\n // If port 3000 not listening, check other common ports\n port = null;\n }\n } catch {\n // lsof might not be available or port not in use\n }\n \n return {\n running: isRunning,\n processCount,\n orchestratorRunning,\n port,\n connections: processCount > 0 ? Math.max(1, processCount - 1) : 0 // Estimate connections\n };\n } catch (error) {\n // Fallback if commands fail\n return {\n running: false,\n processCount: 0,\n orchestratorRunning: false,\n port: null,\n connections: 0\n };\n }\n }\n}\n\nexport { MetricsReader };"],"names":["promises","fs","path","exec","promisify","execAsync","MetricsReader","metricsDir","sessionsDir","getSystemMetrics","filePath","join","content","readFile","metrics","JSON","parse","length","error","getTaskQueue","queueFile","getTaskMetrics","getPerformanceMetrics","getActiveAgents","agents","agentsDir","agentFiles","readdir","file","endsWith","agent","push","sessionFiles","getSessionFiles","sessionData","Array","isArray","getSessionStatus","mostRecentFile","getRecentTasks","limit","taskMetrics","sort","a","b","timestamp","slice","map","task","id","type","status","success","startTime","duration","endTime","getOverallHealth","systemMetrics","perfMetrics","memoryUsagePercent","cpuLoad","totalTasks","failureRate","failedTasks","files","filter","f","getMCPServerStatus","stdout","processCount","parseInt","trim","orchestratorOut","orchestratorRunning","isRunning","port","portOut","running","connections","Math","max"],"mappings":"AAAA,SAASA,YAAYC,EAAE,QAAQ,KAAK;AACpC,OAAOC,UAAU,OAAO;AACxB,SAASC,IAAI,QAAQ,gBAAgB;AACrC,SAASC,SAAS,QAAQ,OAAO;AAEjC,MAAMC,YAAYD,UAAUD;AAE5B,IAAA,AAAMG,gBAAN,MAAMA;IACJ,aAAc;QACZ,IAAI,CAACC,UAAU,GAAG;QAClB,IAAI,CAACC,WAAW,GAAG;IACrB;IAEA,MAAMC,mBAAmB;QACvB,IAAI;YACF,MAAMC,WAAWR,KAAKS,IAAI,CAAC,IAAI,CAACJ,UAAU,EAAE;YAC5C,MAAMK,UAAU,MAAMX,GAAGY,QAAQ,CAACH,UAAU;YAC5C,MAAMI,UAAUC,KAAKC,KAAK,CAACJ;YAG3B,OAAOE,QAAQG,MAAM,GAAG,IAAIH,OAAO,CAACA,QAAQG,MAAM,GAAG,EAAE,GAAG;QAC5D,EAAE,OAAOC,OAAO;YACd,OAAO;QACT;IACF;IAEA,MAAMC,eAAe;QACnB,IAAI;YACF,MAAMC,YAAY;YAClB,MAAMR,UAAU,MAAMX,GAAGY,QAAQ,CAACO,WAAW;YAC7C,OAAOL,KAAKC,KAAK,CAACJ;QACpB,EAAE,OAAOM,OAAO;YACd,OAAO,EAAE;QACX;IACF;IAEA,MAAMG,iBAAiB;QACrB,IAAI;YACF,MAAMX,WAAWR,KAAKS,IAAI,CAAC,IAAI,CAACJ,UAAU,EAAE;YAC5C,MAAMK,UAAU,MAAMX,GAAGY,QAAQ,CAACH,UAAU;YAC5C,OAAOK,KAAKC,KAAK,CAACJ;QACpB,EAAE,OAAOM,OAAO;YACd,OAAO,EAAE;QACX;IACF;IAEA,MAAMI,wBAAwB;QAC5B,IAAI;YACF,MAAMZ,WAAWR,KAAKS,IAAI,CAAC,IAAI,CAACJ,UAAU,EAAE;YAC5C,MAAMK,UAAU,MAAMX,GAAGY,QAAQ,CAACH,UAAU;YAC5C,OAAOK,KAAKC,KAAK,CAACJ;QACpB,EAAE,OAAOM,OAAO;YACd,OAAO;QACT;IACF;IAEA,MAAMK,kBAAkB;QACtB,IAAI;YACF,MAAMC,SAAS,EAAE;YAGjB,MAAMC,YAAY;YAClB,IAAI;gBACF,MAAMC,aAAa,MAAMzB,GAAG0B,OAAO,CAACF;gBACpC,KAAK,MAAMG,QAAQF,WAAY;oBAC7B,IAAIE,KAAKC,QAAQ,CAAC,UAAU;wBAC1B,IAAI;4BACF,MAAMjB,UAAU,MAAMX,GAAGY,QAAQ,CAACX,KAAKS,IAAI,CAACc,WAAWG,OAAO;4BAC9D,MAAME,QAAQf,KAAKC,KAAK,CAACJ;4BACzBY,OAAOO,IAAI,CAACD;wBACd,EAAE,OAAM,CAER;oBACF;gBACF;YACF,EAAE,OAAM,CAER;YAGA,IAAIN,OAAOP,MAAM,KAAK,GAAG;gBACvB,MAAMe,eAAe,MAAM,IAAI,CAACC,eAAe;gBAC/C,KAAK,MAAML,QAAQI,aAAc;oBAC/B,IAAI;wBACF,MAAMpB,UAAU,MAAMX,GAAGY,QAAQ,CAACX,KAAKS,IAAI,CAAC,IAAI,CAACH,WAAW,EAAE,QAAQoB,OAAO;wBAC7E,MAAMM,cAAcnB,KAAKC,KAAK,CAACJ;wBAE/B,IAAIsB,YAAYV,MAAM,IAAIW,MAAMC,OAAO,CAACF,YAAYV,MAAM,GAAG;4BAC3DA,OAAOO,IAAI,IAAIG,YAAYV,MAAM;wBACnC;oBACF,EAAE,OAAM,CAER;gBACF;YACF;YAEA,OAAOA;QACT,EAAE,OAAON,OAAO;YACd,OAAO,EAAE;QACX;IACF;IAEA,MAAMmB,mBAAmB;QACvB,IAAI;YACF,MAAML,eAAe,MAAM,IAAI,CAACC,eAAe;YAE/C,IAAID,aAAaf,MAAM,KAAK,GAAG;gBAC7B,OAAO;YACT;YAGA,MAAMqB,iBAAiBN,YAAY,CAACA,aAAaf,MAAM,GAAG,EAAE;YAC5D,MAAML,UAAU,MAAMX,GAAGY,QAAQ,CAACX,KAAKS,IAAI,CAAC,IAAI,CAACH,WAAW,EAAE,QAAQ8B,iBAAiB;YACvF,OAAOvB,KAAKC,KAAK,CAACJ;QACpB,EAAE,OAAOM,OAAO;YACd,OAAO;QACT;IACF;IAEA,MAAMqB,eAAeC,QAAQ,EAAE,EAAE;QAC/B,IAAI;YACF,MAAMC,cAAc,MAAM,IAAI,CAACpB,cAAc;YAG7C,OAAOoB,YACJC,IAAI,CAAC,CAACC,GAAGC,IAAMA,EAAEC,SAAS,GAAGF,EAAEE,SAAS,EACxCC,KAAK,CAAC,GAAGN,OACTO,GAAG,CAACC,CAAAA,OAAS,CAAA;oBACZC,IAAID,KAAKC,EAAE;oBACXC,MAAMF,KAAKE,IAAI;oBACfC,QAAQH,KAAKI,OAAO,GAAG,cAAc;oBACrCC,WAAWL,KAAKH,SAAS,GAAGG,KAAKM,QAAQ;oBACzCC,SAASP,KAAKH,SAAS;oBACvBS,UAAUN,KAAKM,QAAQ;gBACzB,CAAA;QACJ,EAAE,OAAOpC,OAAO;YACd,OAAO,EAAE;QACX;IACF;IAEA,MAAMsC,mBAAmB;QACvB,IAAI;YACF,MAAMC,gBAAgB,MAAM,IAAI,CAAChD,gBAAgB;YACjD,MAAMiD,cAAc,MAAM,IAAI,CAACpC,qBAAqB;YAEpD,IAAI,CAACmC,iBAAiB,CAACC,aAAa;gBAClC,OAAO;YACT;YAGA,IAAID,iBAAiBA,cAAcE,kBAAkB,GAAG,IAAI;gBAC1D,OAAO;YACT;YAEA,IAAIF,iBAAiBA,cAAcE,kBAAkB,GAAG,IAAI;gBAC1D,OAAO;YACT;YAGA,IAAIF,iBAAiBA,cAAcG,OAAO,GAAG,KAAK;gBAChD,OAAO;YACT;YAGA,IAAIF,eAAeA,YAAYG,UAAU,GAAG,GAAG;gBAC7C,MAAMC,cAAcJ,YAAYK,WAAW,GAAGL,YAAYG,UAAU;gBACpE,IAAIC,cAAc,KAAK;oBACrB,OAAO;gBACT;gBACA,IAAIA,cAAc,KAAK;oBACrB,OAAO;gBACT;YACF;YAEA,OAAO;QACT,EAAE,OAAO5C,OAAO;YACd,OAAO;QACT;IACF;IAEA,MAAMe,kBAAkB;QACtB,IAAI;YACF,MAAM+B,QAAQ,MAAM/D,GAAG0B,OAAO,CAACzB,KAAKS,IAAI,CAAC,IAAI,CAACH,WAAW,EAAE;YAC3D,OAAOwD,MAAMC,MAAM,CAACC,CAAAA,IAAKA,EAAErC,QAAQ,CAAC,UAAUa,IAAI;QACpD,EAAE,OAAOxB,OAAO;YACd,OAAO,EAAE;QACX;IACF;IAEA,MAAMiD,qBAAqB;QACzB,IAAI;YAEF,MAAM,EAAEC,MAAM,EAAE,GAAG,MAAM/D,UAAU;YACnC,MAAMgE,eAAeC,SAASF,OAAOG,IAAI,IAAI;YAG7C,MAAM,EAAEH,QAAQI,eAAe,EAAE,GAAG,MAAMnE,UAAU;YACpD,MAAMoE,sBAAsBH,SAASE,gBAAgBD,IAAI,IAAI,MAAM;YAGnE,MAAMG,YAAYL,eAAe;YAGjC,IAAIM,OAAO;YACX,IAAI;gBACF,MAAM,EAAEP,QAAQQ,OAAO,EAAE,GAAG,MAAMvE,UAAU;gBAC5C,IAAIiE,SAASM,QAAQL,IAAI,IAAI,QAAQ,GAAG;oBAEtCI,OAAO;gBACT;YACF,EAAE,OAAM,CAER;YAEA,OAAO;gBACLE,SAASH;gBACTL;gBACAI;gBACAE;gBACAG,aAAaT,eAAe,IAAIU,KAAKC,GAAG,CAAC,GAAGX,eAAe,KAAK;YAClE;QACF,EAAE,OAAOnD,OAAO;YAEd,OAAO;gBACL2D,SAAS;gBACTR,cAAc;gBACdI,qBAAqB;gBACrBE,MAAM;gBACNG,aAAa;YACf;QACF;IACF;AACF;AAEA,SAASxE,aAAa,GAAG"}AG,KAAK;gBAChD,OAAO;YACT;YAGA,IAAIzC,eAAeA,YAAY0C,UAAU,GAAG,GAAG;gBAC7C,MAAMC,cAAc3C,YAAY4C,WAAW,GAAG5C,YAAY0C,UAAU;gBACpE,IAAIC,cAAc,KAAK;oBACrB,OAAO;gBACT;gBACA,IAAIA,cAAc,KAAK;oBACrB,OAAO;gBACT;YACF;YAEA,OAAO;QACT,EAAE,OAAO/C,OAAO;YACd,OAAO;QACT;IACF;IAEA,MAAcM,kBAAqC;QACjD,IAAI;YACF,MAAM2C,QAAQ,MAAMlE,GAAGmE,OAAO,CAAClE,KAAKS,IAAI,CAAC,IAAI,CAACH,WAAW,EAAE;YAC3D,OAAO2D,MAAME,MAAM,CAACC,CAAAA,IAAKA,EAAEC,QAAQ,CAAC,UAAUtB,IAAI;QACpD,EAAE,OAAO/B,OAAO;YACd,OAAO,EAAE;QACX;IACF;IAEA,MAAMsD,qBAA+C;QACnD,IAAI;YAEF,MAAM,EAAEC,MAAM,EAAE,GAAG,MAAMpE,UAAU;YACnC,MAAMqE,eAAeC,SAASF,OAAOG,IAAI,IAAI;YAG7C,MAAM,EAAEH,QAAQI,eAAe,EAAE,GAAG,MAAMxE,UAAU;YACpD,MAAMyE,sBAAsBH,SAASE,gBAAgBD,IAAI,IAAI,MAAM;YAGnE,MAAMG,YAAYL,eAAe;YAGjC,IAAIM,OAAsB;YAC1B,IAAI;gBACF,MAAM,EAAEP,QAAQQ,OAAO,EAAE,GAAG,MAAM5E,UAAU;gBAC5C,IAAIsE,SAASM,QAAQL,IAAI,IAAI,QAAQ,GAAG;oBAEtCI,OAAO;gBACT;YACF,EAAE,OAAM,CAER;YAEA,OAAO;gBACLE,SAASH;gBACTL;gBACAI;gBACAE;gBACAG,aAAaT,eAAe,IAAIU,KAAKC,GAAG,CAAC,GAAGX,eAAe,KAAK;YAClE;QACF,EAAE,OAAOxD,OAAO;YAEd,OAAO;gBACLgE,SAAS;gBACTR,cAAc;gBACdI,qBAAqB;gBACrBE,MAAM;gBACNG,aAAa;YACf;QACF;IACF;AACF"}
|
|
1
|
+
{"version":3,"sources":["../../../src/utils/metrics-reader.ts"],"sourcesContent":["import * as fs from 'fs/promises';\nimport * as path from 'path';\nimport { exec } from 'child_process';\nimport { promisify } from 'util';\n\nconst execAsync = promisify(exec);\n\ninterface SystemMetrics {\n timestamp: number;\n memoryTotal: number;\n memoryUsed: number;\n memoryFree: number;\n memoryUsagePercent: number;\n memoryEfficiency: number;\n cpuCount: number;\n cpuLoad: number;\n platform: string;\n uptime: number;\n}\n\ninterface TaskMetric {\n id: string;\n type: string;\n success: boolean;\n duration: number;\n timestamp: number;\n metadata: Record<string, any>;\n}\n\ninterface PerformanceMetrics {\n startTime: number;\n totalTasks: number;\n successfulTasks: number;\n failedTasks: number;\n totalAgents: number;\n activeAgents: number;\n neuralEvents: number;\n}\n\ninterface Agent {\n id: string;\n name: string;\n type: string;\n status: 'active' | 'idle' | 'busy';\n activeTasks: number;\n lastActivity?: number;\n}\n\ninterface SessionData {\n id: string;\n startTime: number;\n endTime?: number;\n agents: Agent[];\n tasks: any[];\n status: 'active' | 'completed' | 'paused';\n}\n\ninterface MCPServerStatus {\n running: boolean;\n processCount: number;\n orchestratorRunning: boolean;\n port: number | null;\n connections: number;\n}\n\nexport class MetricsReader {\n private metricsDir = '.claude-flow/metrics';\n private sessionsDir = '.claude-flow/sessions';\n\n async getSystemMetrics(): Promise<SystemMetrics | null> {\n try {\n const filePath = path.join(this.metricsDir, 'system-metrics.json');\n const content = await fs.readFile(filePath, 'utf8');\n const metrics: SystemMetrics[] = JSON.parse(content);\n \n // Return the most recent metric\n return metrics.length > 0 ? metrics[metrics.length - 1] : null;\n } catch (error) {\n return null;\n }\n }\n\n async getTaskMetrics(): Promise<TaskMetric[]> {\n try {\n const filePath = path.join(this.metricsDir, 'task-metrics.json');\n const content = await fs.readFile(filePath, 'utf8');\n return JSON.parse(content);\n } catch (error) {\n return [];\n }\n }\n\n async getPerformanceMetrics(): Promise<PerformanceMetrics | null> {\n try {\n const filePath = path.join(this.metricsDir, 'performance.json');\n const content = await fs.readFile(filePath, 'utf8');\n return JSON.parse(content);\n } catch (error) {\n return null;\n }\n }\n\n async getActiveAgents(): Promise<Agent[]> {\n try {\n // First check performance metrics for agent count\n const perfMetrics = await this.getPerformanceMetrics();\n \n // Also check session files for more detailed agent info\n const sessionFiles = await this.getSessionFiles();\n const agents: Agent[] = [];\n \n for (const file of sessionFiles) {\n try {\n const content = await fs.readFile(path.join(this.sessionsDir, 'pair', file), 'utf8');\n const sessionData = JSON.parse(content);\n \n if (sessionData.agents && Array.isArray(sessionData.agents)) {\n agents.push(...sessionData.agents);\n }\n } catch {\n // Skip invalid session files\n }\n }\n \n // If no agents found in sessions, create mock agents based on performance metrics\n if (agents.length === 0 && perfMetrics) {\n const activeCount = perfMetrics.activeAgents || 0;\n const totalCount = perfMetrics.totalAgents || 0;\n \n for (let i = 0; i < totalCount; i++) {\n agents.push({\n id: `agent-${i + 1}`,\n name: `Agent ${i + 1}`,\n type: i === 0 ? 'orchestrator' : 'worker',\n status: i < activeCount ? 'active' : 'idle',\n activeTasks: i < activeCount ? 1 : 0,\n lastActivity: Date.now() - (i * 1000)\n });\n }\n }\n \n return agents;\n } catch (error) {\n return [];\n }\n }\n\n async getSessionStatus(): Promise<SessionData | null> {\n try {\n const sessionFiles = await this.getSessionFiles();\n \n if (sessionFiles.length === 0) {\n return null;\n }\n \n // Get the most recent session\n const mostRecentFile = sessionFiles[sessionFiles.length - 1];\n const content = await fs.readFile(path.join(this.sessionsDir, 'pair', mostRecentFile), 'utf8');\n return JSON.parse(content);\n } catch (error) {\n return null;\n }\n }\n\n async getRecentTasks(limit: number = 10): Promise<any[]> {\n try {\n const taskMetrics = await this.getTaskMetrics();\n \n // Sort by timestamp descending and take the limit\n return taskMetrics\n .sort((a, b) => b.timestamp - a.timestamp)\n .slice(0, limit)\n .map(task => ({\n id: task.id,\n type: task.type,\n status: task.success ? 'completed' : 'failed',\n startTime: task.timestamp - task.duration,\n endTime: task.timestamp,\n duration: task.duration\n }));\n } catch (error) {\n return [];\n }\n }\n\n async getOverallHealth(): Promise<'healthy' | 'warning' | 'error'> {\n try {\n const systemMetrics = await this.getSystemMetrics();\n const perfMetrics = await this.getPerformanceMetrics();\n \n if (!systemMetrics && !perfMetrics) {\n return 'error';\n }\n \n // Check memory usage\n if (systemMetrics && systemMetrics.memoryUsagePercent > 90) {\n return 'error';\n }\n \n if (systemMetrics && systemMetrics.memoryUsagePercent > 75) {\n return 'warning';\n }\n \n // Check CPU load\n if (systemMetrics && systemMetrics.cpuLoad > 0.8) {\n return 'warning';\n }\n \n // Check task failure rate\n if (perfMetrics && perfMetrics.totalTasks > 0) {\n const failureRate = perfMetrics.failedTasks / perfMetrics.totalTasks;\n if (failureRate > 0.5) {\n return 'error';\n }\n if (failureRate > 0.2) {\n return 'warning';\n }\n }\n \n return 'healthy';\n } catch (error) {\n return 'error';\n }\n }\n\n private async getSessionFiles(): Promise<string[]> {\n try {\n const files = await fs.readdir(path.join(this.sessionsDir, 'pair'));\n return files.filter(f => f.endsWith('.json')).sort();\n } catch (error) {\n return [];\n }\n }\n\n async getMCPServerStatus(): Promise<MCPServerStatus> {\n try {\n // Check if MCP server process is running\n const { stdout } = await execAsync('ps aux | grep -E \"mcp-server\\\\.js|claude-flow mcp start\" | grep -v grep | wc -l');\n const processCount = parseInt(stdout.trim(), 10);\n \n // Check for orchestrator running\n const { stdout: orchestratorOut } = await execAsync('ps aux | grep -E \"claude-flow start\" | grep -v grep | wc -l');\n const orchestratorRunning = parseInt(orchestratorOut.trim(), 10) > 0;\n \n // Determine status\n const isRunning = processCount > 0;\n \n // Try to get port from process (default is 3000)\n let port: number | null = 3000;\n try {\n const { stdout: portOut } = await execAsync('lsof -i :3000 2>/dev/null | grep LISTEN | wc -l');\n if (parseInt(portOut.trim(), 10) === 0) {\n // If port 3000 not listening, check other common ports\n port = null;\n }\n } catch {\n // lsof might not be available or port not in use\n }\n \n return {\n running: isRunning,\n processCount,\n orchestratorRunning,\n port,\n connections: processCount > 0 ? Math.max(1, processCount - 1) : 0 // Estimate connections\n };\n } catch (error) {\n // Fallback if commands fail\n return {\n running: false,\n processCount: 0,\n orchestratorRunning: false,\n port: null,\n connections: 0\n };\n }\n }\n}"],"names":["fs","path","exec","promisify","execAsync","MetricsReader","metricsDir","sessionsDir","getSystemMetrics","filePath","join","content","readFile","metrics","JSON","parse","length","error","getTaskMetrics","getPerformanceMetrics","getActiveAgents","perfMetrics","sessionFiles","getSessionFiles","agents","file","sessionData","Array","isArray","push","activeCount","activeAgents","totalCount","totalAgents","i","id","name","type","status","activeTasks","lastActivity","Date","now","getSessionStatus","mostRecentFile","getRecentTasks","limit","taskMetrics","sort","a","b","timestamp","slice","map","task","success","startTime","duration","endTime","getOverallHealth","systemMetrics","memoryUsagePercent","cpuLoad","totalTasks","failureRate","failedTasks","files","readdir","filter","f","endsWith","getMCPServerStatus","stdout","processCount","parseInt","trim","orchestratorOut","orchestratorRunning","isRunning","port","portOut","running","connections","Math","max"],"mappings":"AAAA,YAAYA,QAAQ,cAAc;AAClC,YAAYC,UAAU,OAAO;AAC7B,SAASC,IAAI,QAAQ,gBAAgB;AACrC,SAASC,SAAS,QAAQ,OAAO;AAEjC,MAAMC,YAAYD,UAAUD;AA4D5B,OAAO,MAAMG;IACHC,aAAa,uBAAuB;IACpCC,cAAc,wBAAwB;IAE9C,MAAMC,mBAAkD;QACtD,IAAI;YACF,MAAMC,WAAWR,KAAKS,IAAI,CAAC,IAAI,CAACJ,UAAU,EAAE;YAC5C,MAAMK,UAAU,MAAMX,GAAGY,QAAQ,CAACH,UAAU;YAC5C,MAAMI,UAA2BC,KAAKC,KAAK,CAACJ;YAG5C,OAAOE,QAAQG,MAAM,GAAG,IAAIH,OAAO,CAACA,QAAQG,MAAM,GAAG,EAAE,GAAG;QAC5D,EAAE,OAAOC,OAAO;YACd,OAAO;QACT;IACF;IAEA,MAAMC,iBAAwC;QAC5C,IAAI;YACF,MAAMT,WAAWR,KAAKS,IAAI,CAAC,IAAI,CAACJ,UAAU,EAAE;YAC5C,MAAMK,UAAU,MAAMX,GAAGY,QAAQ,CAACH,UAAU;YAC5C,OAAOK,KAAKC,KAAK,CAACJ;QACpB,EAAE,OAAOM,OAAO;YACd,OAAO,EAAE;QACX;IACF;IAEA,MAAME,wBAA4D;QAChE,IAAI;YACF,MAAMV,WAAWR,KAAKS,IAAI,CAAC,IAAI,CAACJ,UAAU,EAAE;YAC5C,MAAMK,UAAU,MAAMX,GAAGY,QAAQ,CAACH,UAAU;YAC5C,OAAOK,KAAKC,KAAK,CAACJ;QACpB,EAAE,OAAOM,OAAO;YACd,OAAO;QACT;IACF;IAEA,MAAMG,kBAAoC;QACxC,IAAI;YAEF,MAAMC,cAAc,MAAM,IAAI,CAACF,qBAAqB;YAGpD,MAAMG,eAAe,MAAM,IAAI,CAACC,eAAe;YAC/C,MAAMC,SAAkB,EAAE;YAE1B,KAAK,MAAMC,QAAQH,aAAc;gBAC/B,IAAI;oBACF,MAAMX,UAAU,MAAMX,GAAGY,QAAQ,CAACX,KAAKS,IAAI,CAAC,IAAI,CAACH,WAAW,EAAE,QAAQkB,OAAO;oBAC7E,MAAMC,cAAcZ,KAAKC,KAAK,CAACJ;oBAE/B,IAAIe,YAAYF,MAAM,IAAIG,MAAMC,OAAO,CAACF,YAAYF,MAAM,GAAG;wBAC3DA,OAAOK,IAAI,IAAIH,YAAYF,MAAM;oBACnC;gBACF,EAAE,OAAM,CAER;YACF;YAGA,IAAIA,OAAOR,MAAM,KAAK,KAAKK,aAAa;gBACtC,MAAMS,cAAcT,YAAYU,YAAY,IAAI;gBAChD,MAAMC,aAAaX,YAAYY,WAAW,IAAI;gBAE9C,IAAK,IAAIC,IAAI,GAAGA,IAAIF,YAAYE,IAAK;oBACnCV,OAAOK,IAAI,CAAC;wBACVM,IAAI,CAAC,MAAM,EAAED,IAAI,GAAG;wBACpBE,MAAM,CAAC,MAAM,EAAEF,IAAI,GAAG;wBACtBG,MAAMH,MAAM,IAAI,iBAAiB;wBACjCI,QAAQJ,IAAIJ,cAAc,WAAW;wBACrCS,aAAaL,IAAIJ,cAAc,IAAI;wBACnCU,cAAcC,KAAKC,GAAG,KAAMR,IAAI;oBAClC;gBACF;YACF;YAEA,OAAOV;QACT,EAAE,OAAOP,OAAO;YACd,OAAO,EAAE;QACX;IACF;IAEA,MAAM0B,mBAAgD;QACpD,IAAI;YACF,MAAMrB,eAAe,MAAM,IAAI,CAACC,eAAe;YAE/C,IAAID,aAAaN,MAAM,KAAK,GAAG;gBAC7B,OAAO;YACT;YAGA,MAAM4B,iBAAiBtB,YAAY,CAACA,aAAaN,MAAM,GAAG,EAAE;YAC5D,MAAML,UAAU,MAAMX,GAAGY,QAAQ,CAACX,KAAKS,IAAI,CAAC,IAAI,CAACH,WAAW,EAAE,QAAQqC,iBAAiB;YACvF,OAAO9B,KAAKC,KAAK,CAACJ;QACpB,EAAE,OAAOM,OAAO;YACd,OAAO;QACT;IACF;IAEA,MAAM4B,eAAeC,QAAgB,EAAE,EAAkB;QACvD,IAAI;YACF,MAAMC,cAAc,MAAM,IAAI,CAAC7B,cAAc;YAG7C,OAAO6B,YACJC,IAAI,CAAC,CAACC,GAAGC,IAAMA,EAAEC,SAAS,GAAGF,EAAEE,SAAS,EACxCC,KAAK,CAAC,GAAGN,OACTO,GAAG,CAACC,CAAAA,OAAS,CAAA;oBACZnB,IAAImB,KAAKnB,EAAE;oBACXE,MAAMiB,KAAKjB,IAAI;oBACfC,QAAQgB,KAAKC,OAAO,GAAG,cAAc;oBACrCC,WAAWF,KAAKH,SAAS,GAAGG,KAAKG,QAAQ;oBACzCC,SAASJ,KAAKH,SAAS;oBACvBM,UAAUH,KAAKG,QAAQ;gBACzB,CAAA;QACJ,EAAE,OAAOxC,OAAO;YACd,OAAO,EAAE;QACX;IACF;IAEA,MAAM0C,mBAA6D;QACjE,IAAI;YACF,MAAMC,gBAAgB,MAAM,IAAI,CAACpD,gBAAgB;YACjD,MAAMa,cAAc,MAAM,IAAI,CAACF,qBAAqB;YAEpD,IAAI,CAACyC,iBAAiB,CAACvC,aAAa;gBAClC,OAAO;YACT;YAGA,IAAIuC,iBAAiBA,cAAcC,kBAAkB,GAAG,IAAI;gBAC1D,OAAO;YACT;YAEA,IAAID,iBAAiBA,cAAcC,kBAAkB,GAAG,IAAI;gBAC1D,OAAO;YACT;YAGA,IAAID,iBAAiBA,cAAcE,OAAO,GAAG,KAAK;gBAChD,OAAO;YACT;YAGA,IAAIzC,eAAeA,YAAY0C,UAAU,GAAG,GAAG;gBAC7C,MAAMC,cAAc3C,YAAY4C,WAAW,GAAG5C,YAAY0C,UAAU;gBACpE,IAAIC,cAAc,KAAK;oBACrB,OAAO;gBACT;gBACA,IAAIA,cAAc,KAAK;oBACrB,OAAO;gBACT;YACF;YAEA,OAAO;QACT,EAAE,OAAO/C,OAAO;YACd,OAAO;QACT;IACF;IAEA,MAAcM,kBAAqC;QACjD,IAAI;YACF,MAAM2C,QAAQ,MAAMlE,GAAGmE,OAAO,CAAClE,KAAKS,IAAI,CAAC,IAAI,CAACH,WAAW,EAAE;YAC3D,OAAO2D,MAAME,MAAM,CAACC,CAAAA,IAAKA,EAAEC,QAAQ,CAAC,UAAUtB,IAAI;QACpD,EAAE,OAAO/B,OAAO;YACd,OAAO,EAAE;QACX;IACF;IAEA,MAAMsD,qBAA+C;QACnD,IAAI;YAEF,MAAM,EAAEC,MAAM,EAAE,GAAG,MAAMpE,UAAU;YACnC,MAAMqE,eAAeC,SAASF,OAAOG,IAAI,IAAI;YAG7C,MAAM,EAAEH,QAAQI,eAAe,EAAE,GAAG,MAAMxE,UAAU;YACpD,MAAMyE,sBAAsBH,SAASE,gBAAgBD,IAAI,IAAI,MAAM;YAGnE,MAAMG,YAAYL,eAAe;YAGjC,IAAIM,OAAsB;YAC1B,IAAI;gBACF,MAAM,EAAEP,QAAQQ,OAAO,EAAE,GAAG,MAAM5E,UAAU;gBAC5C,IAAIsE,SAASM,QAAQL,IAAI,IAAI,QAAQ,GAAG;oBAEtCI,OAAO;gBACT;YACF,EAAE,OAAM,CAER;YAEA,OAAO;gBACLE,SAASH;gBACTL;gBACAI;gBACAE;gBACAG,aAAaT,eAAe,IAAIU,KAAKC,GAAG,CAAC,GAAGX,eAAe,KAAK;YAClE;QACF,EAAE,OAAOxD,OAAO;YAEd,OAAO;gBACLgE,SAAS;gBACTR,cAAc;gBACdI,qBAAqB;gBACrBE,MAAM;gBACNG,aAAa;YACf;QACF;IACF;AACF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-flow",
|
|
3
|
-
"version": "2.7.
|
|
3
|
+
"version": "2.7.30",
|
|
4
4
|
"description": "Enterprise-grade AI agent orchestration with WASM-powered ReasoningBank memory and AgentDB vector database (always uses latest agentic-flow)",
|
|
5
5
|
"mcpName": "io.github.ruvnet/claude-flow",
|
|
6
6
|
"main": "cli.mjs",
|
|
@@ -143,7 +143,7 @@
|
|
|
143
143
|
},
|
|
144
144
|
"optionalDependencies": {
|
|
145
145
|
"@types/better-sqlite3": "^7.6.13",
|
|
146
|
-
"agentdb": "^1.
|
|
146
|
+
"agentdb": "^1.6.1",
|
|
147
147
|
"better-sqlite3": "^12.2.0",
|
|
148
148
|
"diskusage": "^1.1.3",
|
|
149
149
|
"node-pty": "^1.0.0"
|