fraim-framework 2.0.93 → 2.0.94
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/dist/src/cli/commands/sync.js +8 -119
- package/dist/src/cli/mcp/mcp-server-registry.js +0 -3
- package/dist/src/cli/setup/auto-mcp-setup.js +1 -1
- package/dist/src/core/types.js +0 -2
- package/dist/src/local-mcp-server/stdio-server.js +0 -101
- package/dist/src/local-mcp-server/usage-collector.js +10 -8
- package/index.js +5 -5
- package/package.json +2 -3
|
@@ -41,7 +41,6 @@ const commander_1 = require("commander");
|
|
|
41
41
|
const fs_1 = __importDefault(require("fs"));
|
|
42
42
|
const path_1 = __importDefault(require("path"));
|
|
43
43
|
const chalk_1 = __importDefault(require("chalk"));
|
|
44
|
-
const child_process_1 = require("child_process");
|
|
45
44
|
const config_loader_1 = require("../../core/config-loader");
|
|
46
45
|
const version_utils_1 = require("../utils/version-utils");
|
|
47
46
|
const script_sync_utils_1 = require("../utils/script-sync-utils");
|
|
@@ -85,14 +84,13 @@ const runSync = async (options) => {
|
|
|
85
84
|
const projectRoot = process.cwd();
|
|
86
85
|
const config = (0, config_loader_1.loadFraimConfig)();
|
|
87
86
|
const fraimDir = path_1.default.join(projectRoot, '.fraim');
|
|
88
|
-
// Check
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
if (!options.skipUpdates
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
console.log(chalk_1.default.gray('⏭️ Skipping auto-update check during installation to prevent loops.'));
|
|
87
|
+
// Check if running via npx
|
|
88
|
+
const isNpx = process.env.npm_config_prefix === undefined || process.env.npm_lifecycle_event === 'npx';
|
|
89
|
+
const isGlobal = !isNpx && (process.env.npm_config_global === 'true' || process.env.npm_config_prefix);
|
|
90
|
+
if (isGlobal && !options.skipUpdates) {
|
|
91
|
+
console.log(chalk_1.default.yellow('⚠️ You are running a global installation of FRAIM.'));
|
|
92
|
+
console.log(chalk_1.default.gray(' Updates are not automatic in this mode.'));
|
|
93
|
+
console.log(chalk_1.default.cyan(' 💡 Recommended: Use "npx fraim-framework@latest sync" instead.\n'));
|
|
96
94
|
}
|
|
97
95
|
const { syncFromRemote } = await Promise.resolve().then(() => __importStar(require('../utils/remote-sync')));
|
|
98
96
|
// Path 1: --local flag → hit localhost MCP server
|
|
@@ -149,118 +147,9 @@ const runSync = async (options) => {
|
|
|
149
147
|
updateVersionInConfig(fraimDir);
|
|
150
148
|
};
|
|
151
149
|
exports.runSync = runSync;
|
|
152
|
-
async function checkAndUpdateCLI() {
|
|
153
|
-
try {
|
|
154
|
-
// Additional safety: check if we're in a global npm install context
|
|
155
|
-
const isGlobalInstall = process.env.npm_config_global === 'true' ||
|
|
156
|
-
process.env.npm_config_prefix ||
|
|
157
|
-
process.cwd().includes('node_modules');
|
|
158
|
-
if (isGlobalInstall) {
|
|
159
|
-
console.log(chalk_1.default.gray('⏭️ Skipping auto-update during global installation.'));
|
|
160
|
-
return;
|
|
161
|
-
}
|
|
162
|
-
console.log(chalk_1.default.blue('🔍 Checking for FRAIM CLI updates...'));
|
|
163
|
-
const currentVersion = (0, version_utils_1.getFraimVersion)();
|
|
164
|
-
const latestVersion = await getLatestNpmVersionHttp('fraim-framework');
|
|
165
|
-
if (!latestVersion) {
|
|
166
|
-
console.log(chalk_1.default.yellow('⚠️ Could not check for updates. Continuing with current version.'));
|
|
167
|
-
return;
|
|
168
|
-
}
|
|
169
|
-
if (isVersionUpToDate(currentVersion, latestVersion)) {
|
|
170
|
-
console.log(chalk_1.default.green(`✅ FRAIM CLI is up to date (${currentVersion})`));
|
|
171
|
-
return;
|
|
172
|
-
}
|
|
173
|
-
console.log(chalk_1.default.yellow(`📦 New version available: ${currentVersion} → ${latestVersion}`));
|
|
174
|
-
console.log(chalk_1.default.blue('🔄 Auto-updating FRAIM CLI...'));
|
|
175
|
-
const success = await updateGlobalPackageHttp('fraim-framework', latestVersion);
|
|
176
|
-
if (success) {
|
|
177
|
-
console.log(chalk_1.default.green(`✅ Successfully updated to FRAIM ${latestVersion}`));
|
|
178
|
-
console.log(chalk_1.default.gray(' Restart may be required for some changes to take effect.'));
|
|
179
|
-
}
|
|
180
|
-
else {
|
|
181
|
-
console.log(chalk_1.default.yellow('⚠️ Auto-update failed. Please run: npm install -g fraim-framework@latest'));
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
catch (error) {
|
|
185
|
-
console.log(chalk_1.default.yellow('⚠️ Could not check for updates. Continuing with current version.'));
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
async function getLatestNpmVersionHttp(packageName) {
|
|
189
|
-
try {
|
|
190
|
-
// Use Node.js built-in https module instead of spawn
|
|
191
|
-
const https = require('https');
|
|
192
|
-
return new Promise((resolve) => {
|
|
193
|
-
const req = https.get(`https://registry.npmjs.org/${packageName}/latest`, {
|
|
194
|
-
timeout: 5000,
|
|
195
|
-
headers: {
|
|
196
|
-
'User-Agent': 'fraim-framework-cli'
|
|
197
|
-
}
|
|
198
|
-
}, (res) => {
|
|
199
|
-
let data = '';
|
|
200
|
-
res.on('data', (chunk) => {
|
|
201
|
-
data += chunk;
|
|
202
|
-
});
|
|
203
|
-
res.on('end', () => {
|
|
204
|
-
try {
|
|
205
|
-
const packageInfo = JSON.parse(data);
|
|
206
|
-
resolve(packageInfo.version || null);
|
|
207
|
-
}
|
|
208
|
-
catch (e) {
|
|
209
|
-
resolve(null);
|
|
210
|
-
}
|
|
211
|
-
});
|
|
212
|
-
});
|
|
213
|
-
req.on('error', () => {
|
|
214
|
-
resolve(null);
|
|
215
|
-
});
|
|
216
|
-
req.on('timeout', () => {
|
|
217
|
-
req.destroy();
|
|
218
|
-
resolve(null);
|
|
219
|
-
});
|
|
220
|
-
});
|
|
221
|
-
}
|
|
222
|
-
catch (error) {
|
|
223
|
-
return null;
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
function isVersionUpToDate(current, latest) {
|
|
227
|
-
// Simple version comparison - assumes semantic versioning
|
|
228
|
-
const currentParts = current.split('.').map(n => parseInt(n, 10));
|
|
229
|
-
const latestParts = latest.split('.').map(n => parseInt(n, 10));
|
|
230
|
-
for (let i = 0; i < Math.max(currentParts.length, latestParts.length); i++) {
|
|
231
|
-
const currentPart = currentParts[i] || 0;
|
|
232
|
-
const latestPart = latestParts[i] || 0;
|
|
233
|
-
if (currentPart < latestPart)
|
|
234
|
-
return false;
|
|
235
|
-
if (currentPart > latestPart)
|
|
236
|
-
return true;
|
|
237
|
-
}
|
|
238
|
-
return true; // Versions are equal
|
|
239
|
-
}
|
|
240
|
-
async function updateGlobalPackageHttp(packageName, version) {
|
|
241
|
-
return new Promise((resolve) => {
|
|
242
|
-
console.log(chalk_1.default.gray(` Running: npm install -g ${packageName}@${version}`));
|
|
243
|
-
// Use npm.cmd on Windows, npm on Unix
|
|
244
|
-
const npmCommand = process.platform === 'win32' ? 'npm.cmd' : 'npm';
|
|
245
|
-
const npmProcess = (0, child_process_1.spawn)(npmCommand, ['install', '-g', `${packageName}@${version}`], {
|
|
246
|
-
stdio: ['ignore', 'ignore', 'ignore'] // Suppress output for cleaner experience
|
|
247
|
-
});
|
|
248
|
-
npmProcess.on('close', (code) => {
|
|
249
|
-
resolve(code === 0);
|
|
250
|
-
});
|
|
251
|
-
npmProcess.on('error', () => {
|
|
252
|
-
resolve(false);
|
|
253
|
-
});
|
|
254
|
-
// Timeout after 30 seconds
|
|
255
|
-
setTimeout(() => {
|
|
256
|
-
npmProcess.kill();
|
|
257
|
-
resolve(false);
|
|
258
|
-
}, 30000);
|
|
259
|
-
});
|
|
260
|
-
}
|
|
261
150
|
exports.syncCommand = new commander_1.Command('sync')
|
|
262
151
|
.description('Sync workflow stubs from the framework registry')
|
|
263
152
|
.option('-f, --force', 'Force sync even if digest matches')
|
|
264
|
-
.option('--skip-updates', 'Skip checking for CLI updates')
|
|
153
|
+
.option('--skip-updates', 'Skip checking for CLI updates (legacy)')
|
|
265
154
|
.option('--local', 'Sync from local development server (port derived from git branch)')
|
|
266
155
|
.action(exports.runSync);
|
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
// MCP Server Registry - Builds MCP servers from provider definitions
|
|
3
|
-
// This file NO LONGER contains hardcoded server configurations
|
|
4
|
-
// All provider MCP server configs come from the provider registry (server or local fallback)
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.BASE_MCP_SERVERS = void 0;
|
|
7
4
|
exports.buildProviderMCPServer = buildProviderMCPServer;
|
|
@@ -324,7 +324,7 @@ const autoConfigureMCP = async (fraimKey, tokenInput, selectedIDEs, providerConf
|
|
|
324
324
|
console.log(chalk_1.default.blue('\n🎯 Next steps:'));
|
|
325
325
|
console.log(chalk_1.default.cyan(' 1. Restart your configured IDEs'));
|
|
326
326
|
console.log(chalk_1.default.cyan(' 2. Go to any project directory'));
|
|
327
|
-
console.log(chalk_1.default.cyan(' 3. Run: fraim init-project'));
|
|
327
|
+
console.log(chalk_1.default.cyan(' 3. Run: npx fraim-framework@latest init-project'));
|
|
328
328
|
console.log(chalk_1.default.cyan(' 4. Ask your AI agent: "list fraim workflows"'));
|
|
329
329
|
}
|
|
330
330
|
};
|
package/dist/src/core/types.js
CHANGED
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* FRAIM Configuration Types
|
|
4
4
|
* TypeScript types for .fraim/config.json
|
|
5
|
-
*
|
|
6
|
-
* Each field includes rich metadata for agent detection and user interaction
|
|
7
5
|
*/
|
|
8
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
7
|
exports.DEFAULT_FRAIM_CONFIG = void 0;
|
|
@@ -243,14 +243,6 @@ class FraimLocalMCPServer {
|
|
|
243
243
|
this.machineInfo = null;
|
|
244
244
|
this.repoInfo = null;
|
|
245
245
|
this.engine = null;
|
|
246
|
-
this.fallbackRewriteCount = 0;
|
|
247
|
-
this.fallbackRewriteRequestCount = 0;
|
|
248
|
-
this.fallbackRewriteTokens = new Map();
|
|
249
|
-
this.pendingFallbackRequestCount = 0;
|
|
250
|
-
this.pendingFallbackTokenRewriteCount = 0;
|
|
251
|
-
this.pendingFallbackTokenCounts = new Map();
|
|
252
|
-
this.pendingFallbackEvents = [];
|
|
253
|
-
this.fallbackSummaryEmitted = false;
|
|
254
246
|
this.writer = writer || process.stdout.write.bind(process.stdout);
|
|
255
247
|
this.remoteUrl = process.env.FRAIM_REMOTE_URL || 'https://fraim.wellnessatwork.me';
|
|
256
248
|
this.apiKey = this.loadApiKey();
|
|
@@ -1043,7 +1035,6 @@ class FraimLocalMCPServer {
|
|
|
1043
1035
|
return response;
|
|
1044
1036
|
const rewritten = this.rewriteUnresolvedProxyPlaceholders(response.result);
|
|
1045
1037
|
if (rewritten.tokens.length > 0) {
|
|
1046
|
-
this.recordFallbackRewrite(rewritten.tokens);
|
|
1047
1038
|
this.logError(`[${FraimLocalMCPServer.FALLBACK_ALERT_MARKER}] Rewrote unresolved proxy placeholders to agent placeholders: ${rewritten.tokens.join(', ')}`);
|
|
1048
1039
|
}
|
|
1049
1040
|
return {
|
|
@@ -1051,79 +1042,6 @@ class FraimLocalMCPServer {
|
|
|
1051
1042
|
result: rewritten.value
|
|
1052
1043
|
};
|
|
1053
1044
|
}
|
|
1054
|
-
recordFallbackRewrite(tokens) {
|
|
1055
|
-
this.fallbackRewriteRequestCount += 1;
|
|
1056
|
-
this.fallbackRewriteCount += tokens.length;
|
|
1057
|
-
for (const token of tokens) {
|
|
1058
|
-
const existing = this.fallbackRewriteTokens.get(token) || 0;
|
|
1059
|
-
this.fallbackRewriteTokens.set(token, existing + 1);
|
|
1060
|
-
}
|
|
1061
|
-
this.pendingFallbackRequestCount += 1;
|
|
1062
|
-
this.pendingFallbackTokenRewriteCount += tokens.length;
|
|
1063
|
-
for (const token of tokens) {
|
|
1064
|
-
const existing = this.pendingFallbackTokenCounts.get(token) || 0;
|
|
1065
|
-
this.pendingFallbackTokenCounts.set(token, existing + 1);
|
|
1066
|
-
}
|
|
1067
|
-
this.pendingFallbackEvents.push({
|
|
1068
|
-
at: new Date().toISOString(),
|
|
1069
|
-
tokenCount: tokens.length,
|
|
1070
|
-
tokens: [...tokens]
|
|
1071
|
-
});
|
|
1072
|
-
if (this.pendingFallbackEvents.length > 250) {
|
|
1073
|
-
this.pendingFallbackEvents = this.pendingFallbackEvents.slice(-250);
|
|
1074
|
-
}
|
|
1075
|
-
}
|
|
1076
|
-
buildPendingFallbackTelemetryPayload() {
|
|
1077
|
-
if (this.pendingFallbackRequestCount === 0 &&
|
|
1078
|
-
this.pendingFallbackTokenRewriteCount === 0 &&
|
|
1079
|
-
this.pendingFallbackEvents.length === 0) {
|
|
1080
|
-
return null;
|
|
1081
|
-
}
|
|
1082
|
-
const tokenCounts = {};
|
|
1083
|
-
for (const [token, count] of this.pendingFallbackTokenCounts.entries()) {
|
|
1084
|
-
tokenCounts[token] = count;
|
|
1085
|
-
}
|
|
1086
|
-
return {
|
|
1087
|
-
requestFallbacks: this.pendingFallbackRequestCount,
|
|
1088
|
-
tokenRewrites: this.pendingFallbackTokenRewriteCount,
|
|
1089
|
-
tokenCounts,
|
|
1090
|
-
events: this.pendingFallbackEvents.map((event) => ({
|
|
1091
|
-
at: event.at,
|
|
1092
|
-
tokenCount: event.tokenCount,
|
|
1093
|
-
tokens: [...event.tokens]
|
|
1094
|
-
}))
|
|
1095
|
-
};
|
|
1096
|
-
}
|
|
1097
|
-
acknowledgePendingFallbackTelemetry(payload) {
|
|
1098
|
-
this.pendingFallbackRequestCount = Math.max(0, this.pendingFallbackRequestCount - payload.requestFallbacks);
|
|
1099
|
-
this.pendingFallbackTokenRewriteCount = Math.max(0, this.pendingFallbackTokenRewriteCount - payload.tokenRewrites);
|
|
1100
|
-
for (const [token, sentCount] of Object.entries(payload.tokenCounts)) {
|
|
1101
|
-
const current = this.pendingFallbackTokenCounts.get(token) || 0;
|
|
1102
|
-
const next = Math.max(0, current - Math.max(0, sentCount));
|
|
1103
|
-
if (next === 0) {
|
|
1104
|
-
this.pendingFallbackTokenCounts.delete(token);
|
|
1105
|
-
}
|
|
1106
|
-
else {
|
|
1107
|
-
this.pendingFallbackTokenCounts.set(token, next);
|
|
1108
|
-
}
|
|
1109
|
-
}
|
|
1110
|
-
if (payload.events.length > 0) {
|
|
1111
|
-
this.pendingFallbackEvents.splice(0, Math.min(payload.events.length, this.pendingFallbackEvents.length));
|
|
1112
|
-
}
|
|
1113
|
-
}
|
|
1114
|
-
emitFallbackSummary(reason) {
|
|
1115
|
-
if (this.fallbackSummaryEmitted)
|
|
1116
|
-
return;
|
|
1117
|
-
this.fallbackSummaryEmitted = true;
|
|
1118
|
-
if (this.fallbackRewriteCount === 0)
|
|
1119
|
-
return;
|
|
1120
|
-
const topTokens = Array.from(this.fallbackRewriteTokens.entries())
|
|
1121
|
-
.sort((a, b) => b[1] - a[1])
|
|
1122
|
-
.slice(0, 10)
|
|
1123
|
-
.map(([token, count]) => `${token}:${count}`)
|
|
1124
|
-
.join(', ');
|
|
1125
|
-
this.logError(`[${FraimLocalMCPServer.FALLBACK_SUMMARY_MARKER}] reason=${reason} requestFallbacks=${this.fallbackRewriteRequestCount} tokenRewrites=${this.fallbackRewriteCount} uniqueTokens=${this.fallbackRewriteTokens.size}${topTokens ? ` topTokens=${topTokens}` : ''}`);
|
|
1126
|
-
}
|
|
1127
1045
|
extractSessionIdFromRequest(request) {
|
|
1128
1046
|
const sessionIdFromParams = request.params?.sessionId;
|
|
1129
1047
|
if (typeof sessionIdFromParams === 'string' && sessionIdFromParams.trim().length > 0) {
|
|
@@ -1197,7 +1115,6 @@ class FraimLocalMCPServer {
|
|
|
1197
1115
|
* tool calls and recursive inclusion resolution.
|
|
1198
1116
|
*/
|
|
1199
1117
|
async _doProxyToRemote(request, requestId = (0, crypto_1.randomUUID)()) {
|
|
1200
|
-
let sentFallbackTelemetry = null;
|
|
1201
1118
|
try {
|
|
1202
1119
|
// Special handling for fraim_connect - automatically inject machine and repo info
|
|
1203
1120
|
if (request.method === 'tools/call' && request.params?.name === 'fraim_connect') {
|
|
@@ -1269,7 +1186,6 @@ class FraimLocalMCPServer {
|
|
|
1269
1186
|
// Update the request with injected info
|
|
1270
1187
|
request.params.arguments = args;
|
|
1271
1188
|
}
|
|
1272
|
-
sentFallbackTelemetry = this.buildPendingFallbackTelemetryPayload();
|
|
1273
1189
|
const headers = {
|
|
1274
1190
|
'Content-Type': 'application/json',
|
|
1275
1191
|
'x-api-key': this.apiKey,
|
|
@@ -1280,11 +1196,6 @@ class FraimLocalMCPServer {
|
|
|
1280
1196
|
if (sessionId) {
|
|
1281
1197
|
headers[FraimLocalMCPServer.SESSION_HEADER] = sessionId;
|
|
1282
1198
|
}
|
|
1283
|
-
if (sentFallbackTelemetry) {
|
|
1284
|
-
headers[FraimLocalMCPServer.FALLBACK_HEADER] = Buffer
|
|
1285
|
-
.from(JSON.stringify(sentFallbackTelemetry), 'utf8')
|
|
1286
|
-
.toString('base64');
|
|
1287
|
-
}
|
|
1288
1199
|
this.log(`[req:${requestId}] Proxying ${request.method} to ${this.remoteUrl}/mcp`);
|
|
1289
1200
|
// Resolve templates in the outgoing request so the remote server
|
|
1290
1201
|
// only ever sees finalized values.
|
|
@@ -1295,9 +1206,6 @@ class FraimLocalMCPServer {
|
|
|
1295
1206
|
headers,
|
|
1296
1207
|
timeout: 30000
|
|
1297
1208
|
});
|
|
1298
|
-
if (sentFallbackTelemetry) {
|
|
1299
|
-
this.acknowledgePendingFallbackTelemetry(sentFallbackTelemetry);
|
|
1300
|
-
}
|
|
1301
1209
|
return response.data;
|
|
1302
1210
|
}
|
|
1303
1211
|
catch (error) {
|
|
@@ -1322,10 +1230,6 @@ class FraimLocalMCPServer {
|
|
|
1322
1230
|
localMcpVersion: this.localVersion
|
|
1323
1231
|
};
|
|
1324
1232
|
}
|
|
1325
|
-
if (sentFallbackTelemetry) {
|
|
1326
|
-
// Request reached the server and produced a response; clear sent fallback delta.
|
|
1327
|
-
this.acknowledgePendingFallbackTelemetry(sentFallbackTelemetry);
|
|
1328
|
-
}
|
|
1329
1233
|
return forwarded;
|
|
1330
1234
|
}
|
|
1331
1235
|
return {
|
|
@@ -1652,19 +1556,16 @@ class FraimLocalMCPServer {
|
|
|
1652
1556
|
process.stdin.on('end', () => {
|
|
1653
1557
|
this.log('🛑 Stdin closed, shutting down...');
|
|
1654
1558
|
cleanup();
|
|
1655
|
-
this.emitFallbackSummary('stdin_end');
|
|
1656
1559
|
process.exit(0);
|
|
1657
1560
|
});
|
|
1658
1561
|
process.on('SIGTERM', () => {
|
|
1659
1562
|
this.log('🛑 SIGTERM received, shutting down...');
|
|
1660
1563
|
cleanup();
|
|
1661
|
-
this.emitFallbackSummary('sigterm');
|
|
1662
1564
|
process.exit(0);
|
|
1663
1565
|
});
|
|
1664
1566
|
process.on('SIGINT', () => {
|
|
1665
1567
|
this.log('🛑 SIGINT received, shutting down...');
|
|
1666
1568
|
cleanup();
|
|
1667
|
-
this.emitFallbackSummary('sigint');
|
|
1668
1569
|
process.exit(0);
|
|
1669
1570
|
});
|
|
1670
1571
|
this.log('✅ FRAIM Local MCP Server ready');
|
|
@@ -1692,8 +1593,6 @@ FraimLocalMCPServer.AGENT_RESOLUTION_NOTICE = [
|
|
|
1692
1593
|
'Replace all `agent.*` placeholders with the best value from repository context, user intent, and available project config.'
|
|
1693
1594
|
].join('\n');
|
|
1694
1595
|
FraimLocalMCPServer.FALLBACK_ALERT_MARKER = 'PROXY_FALLBACK_ALERT';
|
|
1695
|
-
FraimLocalMCPServer.FALLBACK_SUMMARY_MARKER = 'PROXY_FALLBACK_SUMMARY';
|
|
1696
|
-
FraimLocalMCPServer.FALLBACK_HEADER = 'x-fraim-proxy-fallback-telemetry';
|
|
1697
1596
|
FraimLocalMCPServer.SESSION_HEADER = 'x-fraim-session-id';
|
|
1698
1597
|
// Start server if run directly
|
|
1699
1598
|
if (require.main === module) {
|
|
@@ -4,7 +4,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.UsageCollector = void 0;
|
|
7
|
+
const mongodb_1 = require("mongodb");
|
|
7
8
|
const axios_1 = __importDefault(require("axios"));
|
|
9
|
+
// A placeholder ObjectId used when the real API key ID is not yet known.
|
|
10
|
+
// The server will override this with the correct ID from the authenticated API key.
|
|
11
|
+
const PLACEHOLDER_API_KEY_ID = new mongodb_1.ObjectId('000000000000000000000000');
|
|
8
12
|
/**
|
|
9
13
|
* Usage event collector for local MCP proxy
|
|
10
14
|
* Collects usage events and batches them for upload
|
|
@@ -24,16 +28,15 @@ class UsageCollector {
|
|
|
24
28
|
* Collect MCP tool call event
|
|
25
29
|
*/
|
|
26
30
|
collectMCPCall(toolName, args, sessionId, success = true, duration) {
|
|
27
|
-
if (!this.apiKeyId) {
|
|
28
|
-
return; // Silently skip if no API key
|
|
29
|
-
}
|
|
30
31
|
const parsed = this.parseMCPCall(toolName, args);
|
|
31
32
|
if (!parsed)
|
|
32
33
|
return;
|
|
33
34
|
const event = {
|
|
34
35
|
type: parsed.type,
|
|
35
36
|
name: parsed.name,
|
|
36
|
-
apiKeyId
|
|
37
|
+
// Use set apiKeyId if available, otherwise a placeholder.
|
|
38
|
+
// The server will override this with the correct value from the auth token.
|
|
39
|
+
apiKeyId: this.apiKeyId || PLACEHOLDER_API_KEY_ID,
|
|
37
40
|
sessionId,
|
|
38
41
|
success
|
|
39
42
|
};
|
|
@@ -46,13 +49,12 @@ class UsageCollector {
|
|
|
46
49
|
* Collect usage event directly (for backward compatibility with tests)
|
|
47
50
|
*/
|
|
48
51
|
collectEvent(type, name, sessionId, success = true, duration) {
|
|
49
|
-
if (!this.apiKeyId) {
|
|
50
|
-
return; // Silently skip if no API key
|
|
51
|
-
}
|
|
52
52
|
const event = {
|
|
53
53
|
type,
|
|
54
54
|
name,
|
|
55
|
-
apiKeyId
|
|
55
|
+
// Use set apiKeyId if available, otherwise a placeholder.
|
|
56
|
+
// The server will override this with the correct value from the auth token.
|
|
57
|
+
apiKeyId: this.apiKeyId || PLACEHOLDER_API_KEY_ID,
|
|
56
58
|
sessionId,
|
|
57
59
|
success
|
|
58
60
|
};
|
package/index.js
CHANGED
|
@@ -36,13 +36,13 @@ function runCLI() {
|
|
|
36
36
|
// Solution: On Windows with shell: true, quote paths containing spaces.
|
|
37
37
|
// On Unix with shell: false, pass the path unquoted (spawnSync handles it correctly).
|
|
38
38
|
const isWindows = process.platform === 'win32';
|
|
39
|
-
|
|
39
|
+
|
|
40
40
|
// On Windows with shell, quote paths with spaces to prevent shell misinterpretation
|
|
41
41
|
// On Unix without shell, pass path as-is (spawnSync handles spaces correctly)
|
|
42
|
-
const processedSrcPath = (isWindows && srcPath.includes(' '))
|
|
43
|
-
? `"${srcPath}"`
|
|
42
|
+
const processedSrcPath = (isWindows && srcPath.includes(' '))
|
|
43
|
+
? `"${srcPath}"`
|
|
44
44
|
: srcPath;
|
|
45
|
-
|
|
45
|
+
|
|
46
46
|
const result = spawnSync(
|
|
47
47
|
'npx',
|
|
48
48
|
['tsx', processedSrcPath, ...process.argv.slice(2)],
|
|
@@ -66,7 +66,7 @@ function runCLI() {
|
|
|
66
66
|
module.exports = {
|
|
67
67
|
FRAIM_INFO: {
|
|
68
68
|
name: 'FRAIM',
|
|
69
|
-
version: '2.0.
|
|
69
|
+
version: '2.0.93',
|
|
70
70
|
repository: 'https://github.com/mathursrus/FRAIM'
|
|
71
71
|
}
|
|
72
72
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fraim-framework",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.94",
|
|
4
4
|
"description": "FRAIM v2: Framework for Rigor-based AI Management - Transform from solo developer to AI manager orchestrating production-ready code with enterprise-grade discipline",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -10,10 +10,9 @@
|
|
|
10
10
|
"scripts": {
|
|
11
11
|
"dev": "tsx --watch src/fraim-mcp-server.ts > server.log 2>&1",
|
|
12
12
|
"dev:prod": "npm run build && node dist/src/fraim-mcp-server.js > server.log 2>&1",
|
|
13
|
-
"build": "tsc && npm run build:stubs && npm run build:fraim-brain &&
|
|
13
|
+
"build": "tsc && npm run build:stubs && npm run build:fraim-brain && node scripts/copy-registry.js && node -e \"require('fs').copyFileSync('src/core/types.ts', 'registry/templates/manager/fraim-config-schema.ts')\" && npm run validate:registry && npm run validate:fraim-pro-assets && tsx scripts/validate-purity.ts",
|
|
14
14
|
"build:stubs": "tsx scripts/build-stub-registry.ts",
|
|
15
15
|
"build:fraim-brain": "node scripts/generate-fraim-brain.js",
|
|
16
|
-
"build:config-schema": "tsx scripts/generate-config-schema-template.ts",
|
|
17
16
|
"test-all": "npm run test && npm run test:isolated && npm run test:ui",
|
|
18
17
|
"test": "node scripts/test-with-server.js",
|
|
19
18
|
"test:isolated": "npx tsx --test --test-reporter=spec tests/isolated/test-*.ts",
|