fraim 2.0.100
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/README.md +445 -0
- package/bin/fraim.js +23 -0
- package/dist/src/cli/api/get-provider-client.js +41 -0
- package/dist/src/cli/api/provider-client.js +107 -0
- package/dist/src/cli/commands/add-ide.js +430 -0
- package/dist/src/cli/commands/add-provider.js +233 -0
- package/dist/src/cli/commands/doctor.js +149 -0
- package/dist/src/cli/commands/init-project.js +301 -0
- package/dist/src/cli/commands/list-overridable.js +184 -0
- package/dist/src/cli/commands/list.js +57 -0
- package/dist/src/cli/commands/login.js +84 -0
- package/dist/src/cli/commands/mcp.js +15 -0
- package/dist/src/cli/commands/migrate-project-fraim.js +42 -0
- package/dist/src/cli/commands/override.js +177 -0
- package/dist/src/cli/commands/setup.js +651 -0
- package/dist/src/cli/commands/sync.js +162 -0
- package/dist/src/cli/commands/test-mcp.js +171 -0
- package/dist/src/cli/doctor/check-runner.js +199 -0
- package/dist/src/cli/doctor/checks/global-setup-checks.js +220 -0
- package/dist/src/cli/doctor/checks/ide-config-checks.js +250 -0
- package/dist/src/cli/doctor/checks/mcp-connectivity-checks.js +381 -0
- package/dist/src/cli/doctor/checks/project-setup-checks.js +282 -0
- package/dist/src/cli/doctor/checks/scripts-checks.js +157 -0
- package/dist/src/cli/doctor/checks/workflow-checks.js +251 -0
- package/dist/src/cli/doctor/reporters/console-reporter.js +96 -0
- package/dist/src/cli/doctor/reporters/json-reporter.js +11 -0
- package/dist/src/cli/doctor/types.js +6 -0
- package/dist/src/cli/fraim.js +100 -0
- package/dist/src/cli/internal/device-flow-service.js +83 -0
- package/dist/src/cli/mcp/ide-formats.js +243 -0
- package/dist/src/cli/mcp/mcp-server-builder.js +48 -0
- package/dist/src/cli/mcp/mcp-server-registry.js +160 -0
- package/dist/src/cli/mcp/types.js +3 -0
- package/dist/src/cli/providers/local-provider-registry.js +166 -0
- package/dist/src/cli/providers/provider-registry.js +230 -0
- package/dist/src/cli/setup/auto-mcp-setup.js +331 -0
- package/dist/src/cli/setup/codex-local-config.js +37 -0
- package/dist/src/cli/setup/first-run.js +242 -0
- package/dist/src/cli/setup/ide-detector.js +179 -0
- package/dist/src/cli/setup/mcp-config-generator.js +192 -0
- package/dist/src/cli/setup/provider-prompts.js +339 -0
- package/dist/src/cli/utils/agent-adapters.js +126 -0
- package/dist/src/cli/utils/digest-utils.js +47 -0
- package/dist/src/cli/utils/fraim-gitignore.js +40 -0
- package/dist/src/cli/utils/platform-detection.js +258 -0
- package/dist/src/cli/utils/project-bootstrap.js +93 -0
- package/dist/src/cli/utils/remote-sync.js +315 -0
- package/dist/src/cli/utils/script-sync-utils.js +221 -0
- package/dist/src/cli/utils/version-utils.js +32 -0
- package/dist/src/core/ai-mentor.js +230 -0
- package/dist/src/core/config-loader.js +114 -0
- package/dist/src/core/config-writer.js +75 -0
- package/dist/src/core/types.js +23 -0
- package/dist/src/core/utils/git-utils.js +95 -0
- package/dist/src/core/utils/include-resolver.js +92 -0
- package/dist/src/core/utils/inheritance-parser.js +288 -0
- package/dist/src/core/utils/job-parser.js +176 -0
- package/dist/src/core/utils/local-registry-resolver.js +616 -0
- package/dist/src/core/utils/object-utils.js +11 -0
- package/dist/src/core/utils/project-fraim-migration.js +103 -0
- package/dist/src/core/utils/project-fraim-paths.js +38 -0
- package/dist/src/core/utils/provider-utils.js +18 -0
- package/dist/src/core/utils/server-startup.js +34 -0
- package/dist/src/core/utils/stub-generator.js +147 -0
- package/dist/src/core/utils/workflow-parser.js +174 -0
- package/dist/src/local-mcp-server/learning-context-builder.js +229 -0
- package/dist/src/local-mcp-server/stdio-server.js +1698 -0
- package/dist/src/local-mcp-server/usage-collector.js +264 -0
- package/index.js +85 -0
- package/package.json +139 -0
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.UsageCollector = void 0;
|
|
7
|
+
const mongodb_1 = require("mongodb");
|
|
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');
|
|
12
|
+
/**
|
|
13
|
+
* Usage event collector for local MCP proxy
|
|
14
|
+
* Collects usage events and batches them for upload
|
|
15
|
+
*/
|
|
16
|
+
class UsageCollector {
|
|
17
|
+
constructor() {
|
|
18
|
+
this.events = [];
|
|
19
|
+
this.apiKeyId = null;
|
|
20
|
+
}
|
|
21
|
+
static resolveMentoringJobName(args) {
|
|
22
|
+
if (!args || typeof args !== 'object') {
|
|
23
|
+
return 'unknown';
|
|
24
|
+
}
|
|
25
|
+
if (typeof args.jobName === 'string' && args.jobName.trim().length > 0) {
|
|
26
|
+
return args.jobName.trim();
|
|
27
|
+
}
|
|
28
|
+
// Backward compatibility for older callers and docs that still use workflowType.
|
|
29
|
+
if (typeof args.workflowType === 'string' && args.workflowType.trim().length > 0) {
|
|
30
|
+
return args.workflowType.trim();
|
|
31
|
+
}
|
|
32
|
+
if (typeof args.job === 'string' && args.job.trim().length > 0) {
|
|
33
|
+
return args.job.trim();
|
|
34
|
+
}
|
|
35
|
+
return 'unknown';
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Set the API key ID for this session
|
|
39
|
+
*/
|
|
40
|
+
setApiKeyId(apiKeyId) {
|
|
41
|
+
this.apiKeyId = apiKeyId;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Collect MCP tool call event
|
|
45
|
+
*/
|
|
46
|
+
collectMCPCall(toolName, args, sessionId, success = true) {
|
|
47
|
+
const parsed = this.parseMCPCall(toolName, args);
|
|
48
|
+
if (!parsed) {
|
|
49
|
+
const errorMsg = `[UsageCollector] 🚫 Tool not tracked: ${toolName}`;
|
|
50
|
+
console.error(errorMsg);
|
|
51
|
+
// Also log to stderr for better visibility in main logs
|
|
52
|
+
process.stderr.write(errorMsg + '\n');
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
// Extract useful args for analytics
|
|
56
|
+
const analyticsArgs = this.extractAnalyticsArgs(toolName, args);
|
|
57
|
+
const event = {
|
|
58
|
+
type: parsed.type,
|
|
59
|
+
name: parsed.name,
|
|
60
|
+
// Use set apiKeyId if available, otherwise a placeholder.
|
|
61
|
+
// The server will override this with the correct value from the auth token.
|
|
62
|
+
apiKeyId: this.apiKeyId || PLACEHOLDER_API_KEY_ID,
|
|
63
|
+
sessionId,
|
|
64
|
+
success,
|
|
65
|
+
args: analyticsArgs
|
|
66
|
+
};
|
|
67
|
+
this.events.push(event);
|
|
68
|
+
const successMsg = `[UsageCollector] ✅ Collected event: ${parsed.type}/${parsed.name} (session: ${sessionId}, queue: ${this.events.length})`;
|
|
69
|
+
console.error(successMsg);
|
|
70
|
+
// Also log to stderr for better visibility in main logs
|
|
71
|
+
process.stderr.write(successMsg + '\n');
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Collect usage event directly (for backward compatibility with tests)
|
|
75
|
+
*/
|
|
76
|
+
collectEvent(type, name, sessionId, success = true, args) {
|
|
77
|
+
const event = {
|
|
78
|
+
type,
|
|
79
|
+
name,
|
|
80
|
+
// Use set apiKeyId if available, otherwise a placeholder.
|
|
81
|
+
// The server will override this with the correct value from the auth token.
|
|
82
|
+
apiKeyId: this.apiKeyId || PLACEHOLDER_API_KEY_ID,
|
|
83
|
+
sessionId,
|
|
84
|
+
success,
|
|
85
|
+
args
|
|
86
|
+
};
|
|
87
|
+
this.events.push(event);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Extract useful arguments for analytics tracking
|
|
91
|
+
*/
|
|
92
|
+
extractAnalyticsArgs(toolName, args) {
|
|
93
|
+
const analyticsArgs = {};
|
|
94
|
+
switch (toolName) {
|
|
95
|
+
case 'seekMentoring':
|
|
96
|
+
if (args.currentPhase)
|
|
97
|
+
analyticsArgs.currentPhase = args.currentPhase;
|
|
98
|
+
if (args.status)
|
|
99
|
+
analyticsArgs.status = args.status;
|
|
100
|
+
const mentoringJobName = UsageCollector.resolveMentoringJobName(args);
|
|
101
|
+
if (mentoringJobName !== 'unknown')
|
|
102
|
+
analyticsArgs.jobName = mentoringJobName;
|
|
103
|
+
if (args.issueNumber)
|
|
104
|
+
analyticsArgs.issueNumber = args.issueNumber;
|
|
105
|
+
break;
|
|
106
|
+
case 'get_fraim_file':
|
|
107
|
+
if (args.path) {
|
|
108
|
+
analyticsArgs.path = args.path;
|
|
109
|
+
// Extract category and subcategory from path
|
|
110
|
+
const pathParts = args.path.split('/');
|
|
111
|
+
if (pathParts.length >= 2) {
|
|
112
|
+
analyticsArgs.category = pathParts[1]; // skills, jobs, rules, workflows
|
|
113
|
+
if (pathParts.length >= 3) {
|
|
114
|
+
analyticsArgs.subcategory = pathParts[2]; // engineering, product-building, etc.
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
break;
|
|
119
|
+
case 'get_fraim_job':
|
|
120
|
+
if (args.job)
|
|
121
|
+
analyticsArgs.job = args.job;
|
|
122
|
+
break;
|
|
123
|
+
case 'fraim_connect':
|
|
124
|
+
if (args.agent?.name)
|
|
125
|
+
analyticsArgs.agentName = args.agent.name;
|
|
126
|
+
if (args.agent?.model)
|
|
127
|
+
analyticsArgs.agentModel = args.agent.model;
|
|
128
|
+
break;
|
|
129
|
+
default:
|
|
130
|
+
// For other tools, don't collect args to avoid PII
|
|
131
|
+
return undefined;
|
|
132
|
+
}
|
|
133
|
+
return Object.keys(analyticsArgs).length > 0 ? analyticsArgs : undefined;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Parse MCP tool call to extract usage analytics info
|
|
137
|
+
*/
|
|
138
|
+
parseMCPCall(toolName, args) {
|
|
139
|
+
switch (toolName) {
|
|
140
|
+
case 'get_fraim_job':
|
|
141
|
+
return { type: 'job', name: args.job || 'unknown' };
|
|
142
|
+
case 'get_fraim_file':
|
|
143
|
+
if (args.path) {
|
|
144
|
+
return UsageCollector.parseComponentName(args.path);
|
|
145
|
+
}
|
|
146
|
+
return null;
|
|
147
|
+
case 'seekMentoring':
|
|
148
|
+
return { type: 'mentoring', name: UsageCollector.resolveMentoringJobName(args) };
|
|
149
|
+
case 'list_fraim_jobs':
|
|
150
|
+
return { type: 'job', name: 'list' };
|
|
151
|
+
case 'fraim_connect':
|
|
152
|
+
return { type: 'session', name: 'connect' };
|
|
153
|
+
default:
|
|
154
|
+
return null;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Get collected events for upload and clear the queue
|
|
159
|
+
*/
|
|
160
|
+
getEventsForUpload() {
|
|
161
|
+
const eventsToUpload = [...this.events];
|
|
162
|
+
this.events = [];
|
|
163
|
+
return eventsToUpload;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Get current event count
|
|
167
|
+
*/
|
|
168
|
+
getEventCount() {
|
|
169
|
+
return this.events.length;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Flush events to the remote server via API
|
|
173
|
+
*/
|
|
174
|
+
async flush(remoteUrl, apiKey) {
|
|
175
|
+
if (this.events.length === 0) {
|
|
176
|
+
const noEventsMsg = `[UsageCollector] 📊 No events to flush`;
|
|
177
|
+
console.error(noEventsMsg);
|
|
178
|
+
process.stderr.write(noEventsMsg + '\n');
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
const events = [...this.events];
|
|
182
|
+
this.events = [];
|
|
183
|
+
const flushMsg = `[UsageCollector] 📤 Flushing ${events.length} events to ${remoteUrl}/api/analytics/events`;
|
|
184
|
+
console.error(flushMsg);
|
|
185
|
+
process.stderr.write(flushMsg + '\n');
|
|
186
|
+
try {
|
|
187
|
+
const response = await axios_1.default.post(`${remoteUrl}/api/analytics/events`, {
|
|
188
|
+
events,
|
|
189
|
+
apiKey
|
|
190
|
+
}, {
|
|
191
|
+
timeout: 5000,
|
|
192
|
+
headers: {
|
|
193
|
+
'x-api-key': apiKey,
|
|
194
|
+
'Content-Type': 'application/json'
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
const successMsg = `[UsageCollector] ✅ Successfully flushed ${events.length} events (HTTP ${response.status})`;
|
|
198
|
+
console.error(successMsg);
|
|
199
|
+
process.stderr.write(successMsg + '\n');
|
|
200
|
+
// Success - events are already cleared from the queue
|
|
201
|
+
}
|
|
202
|
+
catch (error) {
|
|
203
|
+
const status = error.response?.status;
|
|
204
|
+
const message = error.response?.data?.error || error.message;
|
|
205
|
+
const errorMsg = `[UsageCollector] ❌ Failed to flush usage events (HTTP ${status}): ${message}`;
|
|
206
|
+
console.error(errorMsg);
|
|
207
|
+
process.stderr.write(errorMsg + '\n');
|
|
208
|
+
// Log additional debug info
|
|
209
|
+
if (error.response?.data) {
|
|
210
|
+
const debugMsg = `[UsageCollector] 🔍 Response data: ${JSON.stringify(error.response.data)}`;
|
|
211
|
+
console.error(debugMsg);
|
|
212
|
+
process.stderr.write(debugMsg + '\n');
|
|
213
|
+
}
|
|
214
|
+
// Put events back at the beginning of the queue for next try
|
|
215
|
+
this.events = [...events, ...this.events];
|
|
216
|
+
// Re-throw the error so the main server can log it too
|
|
217
|
+
throw error;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Shutdown the collector
|
|
222
|
+
*/
|
|
223
|
+
shutdown() {
|
|
224
|
+
this.events = [];
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Parse component name from file path
|
|
228
|
+
*/
|
|
229
|
+
static parseComponentName(path) {
|
|
230
|
+
// Normalize path to have leading slash for consistent regex matching
|
|
231
|
+
const normalizedPath = path.startsWith('/') ? path : `/${path}`;
|
|
232
|
+
// Match skills files: /skills/category/skill-name.md
|
|
233
|
+
if (normalizedPath.includes('/skills/')) {
|
|
234
|
+
const skillMatch = normalizedPath.match(/\/skills\/[^/]+\/([^/]+)\.md$/);
|
|
235
|
+
if (skillMatch) {
|
|
236
|
+
return { type: 'skill', name: skillMatch[1] };
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
// Match job files: /jobs/category/subcategory/job-name.md
|
|
240
|
+
if (normalizedPath.includes('/jobs/')) {
|
|
241
|
+
const jobMatch = normalizedPath.match(/\/jobs\/[^/]+\/[^/]+\/([^/]+)\.md$/);
|
|
242
|
+
if (jobMatch) {
|
|
243
|
+
return { type: 'job', name: jobMatch[1] };
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
// Match rule files: /rules/category/rule-name.md
|
|
247
|
+
if (normalizedPath.includes('/rules/')) {
|
|
248
|
+
const ruleMatch = normalizedPath.match(/\/rules\/[^/]+\/([^/]+)\.md$/);
|
|
249
|
+
if (ruleMatch) {
|
|
250
|
+
return { type: 'rule', name: ruleMatch[1] };
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
// For other paths that don't match the expected patterns,
|
|
254
|
+
// we'll classify them as 'job' type with a generic name
|
|
255
|
+
// This ensures we track usage even for non-standard paths
|
|
256
|
+
const fileName = normalizedPath.split('/').pop();
|
|
257
|
+
if (fileName && fileName.endsWith('.md')) {
|
|
258
|
+
const baseName = fileName.replace(/\.md$/, '');
|
|
259
|
+
return { type: 'job', name: baseName };
|
|
260
|
+
}
|
|
261
|
+
return null;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
exports.UsageCollector = UsageCollector;
|
package/index.js
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* FRAIM Framework - Smart Entry Point
|
|
5
|
+
* This file handles both production (dist/) and development (src/) environments.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const path = require('path');
|
|
9
|
+
const fs = require('fs');
|
|
10
|
+
const { spawnSync } = require('child_process');
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Runs the CLI using either the compiled JS or the source TS via tsx
|
|
14
|
+
*/
|
|
15
|
+
function runCLI() {
|
|
16
|
+
const distPath = path.join(__dirname, 'dist', 'src', 'cli', 'fraim.js');
|
|
17
|
+
const srcPath = path.join(__dirname, 'src', 'cli', 'fraim.ts');
|
|
18
|
+
|
|
19
|
+
// 1. Check if we have a compiled version (Production / CI)
|
|
20
|
+
if (fs.existsSync(distPath)) {
|
|
21
|
+
require(distPath);
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// 2. Explicitly fail in production if dist/ is missing
|
|
26
|
+
if (process.env.NODE_ENV === 'production') {
|
|
27
|
+
console.error('❌ FRAIM Error: Production build (dist/) not found.');
|
|
28
|
+
console.error('In production environments, you must run the compiled version.');
|
|
29
|
+
console.error(`Expected: ${distPath}`);
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// 3. Fallback to source version using tsx (Development)
|
|
34
|
+
if (fs.existsSync(srcPath)) {
|
|
35
|
+
// We use spawnSync to run tsx so we don't have to require it in memory
|
|
36
|
+
// if it's not needed, and it handles the process arguments correctly.
|
|
37
|
+
//
|
|
38
|
+
// IMPORTANT FIX: Directory names with spaces and dashes (e.g., "FRAIM - Issue 166")
|
|
39
|
+
// cause argument parsing issues on Windows when shell: true is used.
|
|
40
|
+
// Without quoting, a path like "C:\...\FRAIM - Issue 166\src\cli\fraim.ts" gets
|
|
41
|
+
// split into multiple arguments, with the dash interpreted as a command flag,
|
|
42
|
+
// resulting in "error: unknown command '-'".
|
|
43
|
+
//
|
|
44
|
+
// Solution: On Windows with shell: true, quote paths containing spaces.
|
|
45
|
+
// On Unix with shell: false, pass the path unquoted (spawnSync handles it correctly).
|
|
46
|
+
const isWindows = process.platform === 'win32';
|
|
47
|
+
|
|
48
|
+
// On Windows with shell, quote paths with spaces to prevent shell misinterpretation
|
|
49
|
+
// On Unix without shell, pass path as-is (spawnSync handles spaces correctly)
|
|
50
|
+
const processedSrcPath = (isWindows && srcPath.includes(' '))
|
|
51
|
+
? `"${srcPath}"`
|
|
52
|
+
: srcPath;
|
|
53
|
+
|
|
54
|
+
const result = spawnSync(
|
|
55
|
+
'npx',
|
|
56
|
+
['tsx', processedSrcPath, ...process.argv.slice(2)],
|
|
57
|
+
{
|
|
58
|
+
stdio: 'inherit',
|
|
59
|
+
shell: isWindows, // Windows needs shell for npx, Unix doesn't
|
|
60
|
+
windowsHide: true
|
|
61
|
+
}
|
|
62
|
+
);
|
|
63
|
+
process.exit(result.status || 0);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
console.error('❌ FRAIM Error: Could not find CLI entry point.');
|
|
67
|
+
console.error('Expected one of:');
|
|
68
|
+
console.error(` - ${distPath}`);
|
|
69
|
+
console.error(` - ${srcPath}`);
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Global programmatic exports
|
|
74
|
+
module.exports = {
|
|
75
|
+
FRAIM_INFO: {
|
|
76
|
+
name: 'FRAIM',
|
|
77
|
+
version: '2.0.98',
|
|
78
|
+
repository: 'https://github.com/mathursrus/FRAIM'
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
// If this file is run directly (via npx or global link), run the CLI
|
|
83
|
+
if (require.main === module) {
|
|
84
|
+
runCLI();
|
|
85
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "fraim",
|
|
3
|
+
"version": "2.0.100",
|
|
4
|
+
"description": "FRAIM CLI - Framework for Rigor-based AI Management (alias for fraim-framework)",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"fraim": "./index.js",
|
|
8
|
+
"fraim-framework": "./index.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"dev": "tsx --watch src/fraim-mcp-server.ts > server.log 2>&1",
|
|
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 && 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
|
+
"build:stubs": "tsx scripts/build-stub-registry.ts",
|
|
15
|
+
"build:fraim-brain": "node scripts/generate-fraim-brain.js",
|
|
16
|
+
"test-all": "npm run test && npm run test:isolated && npm run test:ui",
|
|
17
|
+
"test": "node scripts/test-with-server.js",
|
|
18
|
+
"test:isolated": "npx tsx --test --test-reporter=spec tests/isolated/test-*.ts",
|
|
19
|
+
"test:smoke": "node scripts/test-with-server.js tests/test-*.ts --tags=smoke",
|
|
20
|
+
"test:stripe": "node scripts/test-with-server.js tests/test-stripe-payment-complete.ts",
|
|
21
|
+
"test:stripe:ui": "playwright test tests/ui/test-payment-ui.spec.ts",
|
|
22
|
+
"test:ui": "playwright test",
|
|
23
|
+
"test:ui:headed": "playwright test --headed",
|
|
24
|
+
"start:fraim": "tsx src/fraim-mcp-server.ts",
|
|
25
|
+
"dev:fraim": "tsx --watch src/fraim-mcp-server.ts",
|
|
26
|
+
"serve:website": "node fraim-pro/serve.js",
|
|
27
|
+
"watch:fraimlogs": "tsx scripts/watch-fraim-logs.ts > prodlogs.log 2>&1",
|
|
28
|
+
"manage-keys": "tsx scripts/fraim/manage-keys.ts",
|
|
29
|
+
"partner-discounts": "tsx scripts/fraim/manage-partner-discounts.ts",
|
|
30
|
+
"fix-key": "tsx scripts/fraim/fix-expired-key.ts",
|
|
31
|
+
"setup-stripe-webhook": "tsx scripts/fraim/setup-stripe-webhook.ts",
|
|
32
|
+
"view-signups": "tsx scripts/view-signups.ts",
|
|
33
|
+
"fraim:init": "npm run build && node index.js init",
|
|
34
|
+
"fraim:sync": "node index.js sync --local",
|
|
35
|
+
"postinstall": "fraim sync --skip-updates || echo 'FRAIM setup skipped.'",
|
|
36
|
+
"prepublishOnly": "npm run build",
|
|
37
|
+
"release": "npm version patch && npm run publish-both",
|
|
38
|
+
"publish-both": "node scripts/publish-both.js",
|
|
39
|
+
"publish-fraim-only": "node scripts/publish-fraim.js",
|
|
40
|
+
"publish-both-manual": "node scripts/publish-both.js",
|
|
41
|
+
"validate:registry": "tsx scripts/verify-registry-paths.ts && npm run validate:jobs && npm run validate:skills && npm run validate:registry-references && npm run validate:platform-agnostic && npm run validate:template-namespaces && npm run validate:config-fallbacks && npm run validate:bootstrap-config-coverage && npm run validate:provider-action-mappings && npm run validate:fidelity && npm run validate:config-tokens && npm run validate:brain-mapping && npm run validate:template-syntax",
|
|
42
|
+
"validate:registry-references": "tsx scripts/validate-registry-references.ts",
|
|
43
|
+
"validate:brain-mapping": "tsx scripts/validate-brain-mapping.ts",
|
|
44
|
+
"validate:fraim-pro-assets": "tsx scripts/validate-fraim-pro-assets.ts",
|
|
45
|
+
"validate:jobs": "tsx scripts/validate-jobs.ts",
|
|
46
|
+
"validate:platform-agnostic": "tsx scripts/validate-platform-agnostic.ts",
|
|
47
|
+
"validate:skills": "tsx scripts/validate-skills.ts",
|
|
48
|
+
"validate:template-namespaces": "tsx scripts/validate-template-namespaces.ts",
|
|
49
|
+
"validate:config-fallbacks": "tsx scripts/validate-config-fallbacks.ts",
|
|
50
|
+
"validate:bootstrap-config-coverage": "tsx scripts/validate-bootstrap-config-coverage.ts",
|
|
51
|
+
"validate:provider-action-mappings": "tsx scripts/validate-provider-action-mappings.ts",
|
|
52
|
+
"validate:fidelity": "tsx scripts/validate-fidelity.ts",
|
|
53
|
+
"validate:config-tokens": "tsx scripts/validate-config-tokens.ts",
|
|
54
|
+
"validate:template-syntax": "tsx scripts/validate-template-syntax.ts"
|
|
55
|
+
},
|
|
56
|
+
"repository": {
|
|
57
|
+
"type": "git",
|
|
58
|
+
"url": "git+https://github.com/mathursrus/FRAIM.git"
|
|
59
|
+
},
|
|
60
|
+
"keywords": [
|
|
61
|
+
"fraim",
|
|
62
|
+
"ai-management",
|
|
63
|
+
"ai-coordination",
|
|
64
|
+
"ai-agents",
|
|
65
|
+
"multi-agent",
|
|
66
|
+
"github",
|
|
67
|
+
"automation",
|
|
68
|
+
"gitops",
|
|
69
|
+
"cursor",
|
|
70
|
+
"claude",
|
|
71
|
+
"windsurf",
|
|
72
|
+
"rigor",
|
|
73
|
+
"enterprise",
|
|
74
|
+
"framework",
|
|
75
|
+
"ai-managers"
|
|
76
|
+
],
|
|
77
|
+
"author": "Sid Mathur <sid.mathur@gmail.com>",
|
|
78
|
+
"license": "MIT",
|
|
79
|
+
"bugs": {
|
|
80
|
+
"url": "https://github.com/mathursrus/FRAIM/issues"
|
|
81
|
+
},
|
|
82
|
+
"homepage": "https://github.com/mathursrus/FRAIM#readme",
|
|
83
|
+
"engines": {
|
|
84
|
+
"node": ">=16.0.0"
|
|
85
|
+
},
|
|
86
|
+
"devDependencies": {
|
|
87
|
+
"@playwright/test": "^1.58.2",
|
|
88
|
+
"@types/adm-zip": "^0.5.7",
|
|
89
|
+
"@types/cors": "^2.8.19",
|
|
90
|
+
"@types/express": "^5.0.6",
|
|
91
|
+
"@types/node": "^20.0.0",
|
|
92
|
+
"@types/prompts": "^2.4.9",
|
|
93
|
+
"@types/semver": "^7.7.1",
|
|
94
|
+
"fast-glob": "^3.3.3",
|
|
95
|
+
"html-to-docx": "^1.8.0",
|
|
96
|
+
"markdown-it": "^14.1.1",
|
|
97
|
+
"markdown-it-highlightjs": "^4.3.0",
|
|
98
|
+
"playwright": "^1.58.2",
|
|
99
|
+
"pptxgenjs": "^4.0.1",
|
|
100
|
+
"puppeteer": "^24.36.1",
|
|
101
|
+
"qrcode": "^1.5.4",
|
|
102
|
+
"sharp": "^0.34.5",
|
|
103
|
+
"tsx": "^4.0.0",
|
|
104
|
+
"typescript": "^5.0.0"
|
|
105
|
+
},
|
|
106
|
+
"files": [
|
|
107
|
+
"dist/src/local-mcp-server/",
|
|
108
|
+
"dist/src/cli/",
|
|
109
|
+
"dist/src/core/",
|
|
110
|
+
"bin/fraim.js",
|
|
111
|
+
"bin/fraim-mcp.js",
|
|
112
|
+
"index.js",
|
|
113
|
+
"README.md",
|
|
114
|
+
"CHANGELOG.md",
|
|
115
|
+
"LICENSE",
|
|
116
|
+
"package.json"
|
|
117
|
+
],
|
|
118
|
+
"publishConfig": {
|
|
119
|
+
"access": "public"
|
|
120
|
+
},
|
|
121
|
+
"dependencies": {
|
|
122
|
+
"adm-zip": "^0.5.16",
|
|
123
|
+
"axios": "^1.7.0",
|
|
124
|
+
"chalk": "4.1.2",
|
|
125
|
+
"commander": "^14.0.2",
|
|
126
|
+
"cors": "^2.8.5",
|
|
127
|
+
"dotenv": "^16.4.7",
|
|
128
|
+
"express": "^5.2.1",
|
|
129
|
+
"mongodb": "^7.0.0",
|
|
130
|
+
"node-edge-tts": "^1.2.10",
|
|
131
|
+
"prompts": "^2.4.2",
|
|
132
|
+
"resend": "^6.9.3",
|
|
133
|
+
"semver": "^7.7.4",
|
|
134
|
+
"stripe": "^20.3.1",
|
|
135
|
+
"toml": "^3.0.0",
|
|
136
|
+
"tree-kill": "^1.2.2",
|
|
137
|
+
"xml2js": "^0.6.2"
|
|
138
|
+
}
|
|
139
|
+
}
|