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.
Files changed (70) hide show
  1. package/README.md +445 -0
  2. package/bin/fraim.js +23 -0
  3. package/dist/src/cli/api/get-provider-client.js +41 -0
  4. package/dist/src/cli/api/provider-client.js +107 -0
  5. package/dist/src/cli/commands/add-ide.js +430 -0
  6. package/dist/src/cli/commands/add-provider.js +233 -0
  7. package/dist/src/cli/commands/doctor.js +149 -0
  8. package/dist/src/cli/commands/init-project.js +301 -0
  9. package/dist/src/cli/commands/list-overridable.js +184 -0
  10. package/dist/src/cli/commands/list.js +57 -0
  11. package/dist/src/cli/commands/login.js +84 -0
  12. package/dist/src/cli/commands/mcp.js +15 -0
  13. package/dist/src/cli/commands/migrate-project-fraim.js +42 -0
  14. package/dist/src/cli/commands/override.js +177 -0
  15. package/dist/src/cli/commands/setup.js +651 -0
  16. package/dist/src/cli/commands/sync.js +162 -0
  17. package/dist/src/cli/commands/test-mcp.js +171 -0
  18. package/dist/src/cli/doctor/check-runner.js +199 -0
  19. package/dist/src/cli/doctor/checks/global-setup-checks.js +220 -0
  20. package/dist/src/cli/doctor/checks/ide-config-checks.js +250 -0
  21. package/dist/src/cli/doctor/checks/mcp-connectivity-checks.js +381 -0
  22. package/dist/src/cli/doctor/checks/project-setup-checks.js +282 -0
  23. package/dist/src/cli/doctor/checks/scripts-checks.js +157 -0
  24. package/dist/src/cli/doctor/checks/workflow-checks.js +251 -0
  25. package/dist/src/cli/doctor/reporters/console-reporter.js +96 -0
  26. package/dist/src/cli/doctor/reporters/json-reporter.js +11 -0
  27. package/dist/src/cli/doctor/types.js +6 -0
  28. package/dist/src/cli/fraim.js +100 -0
  29. package/dist/src/cli/internal/device-flow-service.js +83 -0
  30. package/dist/src/cli/mcp/ide-formats.js +243 -0
  31. package/dist/src/cli/mcp/mcp-server-builder.js +48 -0
  32. package/dist/src/cli/mcp/mcp-server-registry.js +160 -0
  33. package/dist/src/cli/mcp/types.js +3 -0
  34. package/dist/src/cli/providers/local-provider-registry.js +166 -0
  35. package/dist/src/cli/providers/provider-registry.js +230 -0
  36. package/dist/src/cli/setup/auto-mcp-setup.js +331 -0
  37. package/dist/src/cli/setup/codex-local-config.js +37 -0
  38. package/dist/src/cli/setup/first-run.js +242 -0
  39. package/dist/src/cli/setup/ide-detector.js +179 -0
  40. package/dist/src/cli/setup/mcp-config-generator.js +192 -0
  41. package/dist/src/cli/setup/provider-prompts.js +339 -0
  42. package/dist/src/cli/utils/agent-adapters.js +126 -0
  43. package/dist/src/cli/utils/digest-utils.js +47 -0
  44. package/dist/src/cli/utils/fraim-gitignore.js +40 -0
  45. package/dist/src/cli/utils/platform-detection.js +258 -0
  46. package/dist/src/cli/utils/project-bootstrap.js +93 -0
  47. package/dist/src/cli/utils/remote-sync.js +315 -0
  48. package/dist/src/cli/utils/script-sync-utils.js +221 -0
  49. package/dist/src/cli/utils/version-utils.js +32 -0
  50. package/dist/src/core/ai-mentor.js +230 -0
  51. package/dist/src/core/config-loader.js +114 -0
  52. package/dist/src/core/config-writer.js +75 -0
  53. package/dist/src/core/types.js +23 -0
  54. package/dist/src/core/utils/git-utils.js +95 -0
  55. package/dist/src/core/utils/include-resolver.js +92 -0
  56. package/dist/src/core/utils/inheritance-parser.js +288 -0
  57. package/dist/src/core/utils/job-parser.js +176 -0
  58. package/dist/src/core/utils/local-registry-resolver.js +616 -0
  59. package/dist/src/core/utils/object-utils.js +11 -0
  60. package/dist/src/core/utils/project-fraim-migration.js +103 -0
  61. package/dist/src/core/utils/project-fraim-paths.js +38 -0
  62. package/dist/src/core/utils/provider-utils.js +18 -0
  63. package/dist/src/core/utils/server-startup.js +34 -0
  64. package/dist/src/core/utils/stub-generator.js +147 -0
  65. package/dist/src/core/utils/workflow-parser.js +174 -0
  66. package/dist/src/local-mcp-server/learning-context-builder.js +229 -0
  67. package/dist/src/local-mcp-server/stdio-server.js +1698 -0
  68. package/dist/src/local-mcp-server/usage-collector.js +264 -0
  69. package/index.js +85 -0
  70. package/package.json +139 -0
@@ -0,0 +1,179 @@
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.expandPath = exports.findIDEByName = exports.getAllSupportedIDEs = exports.detectInstalledIDEs = exports.IDE_CONFIGS = void 0;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const os_1 = __importDefault(require("os"));
10
+ const expandPath = (filePath) => {
11
+ if (filePath.startsWith('~/')) {
12
+ return path_1.default.join(os_1.default.homedir(), filePath.slice(2));
13
+ }
14
+ return filePath;
15
+ };
16
+ exports.expandPath = expandPath;
17
+ const checkMultiplePaths = (paths) => {
18
+ return paths.some(p => fs_1.default.existsSync(expandPath(p)));
19
+ };
20
+ const detectClaude = () => {
21
+ const paths = [
22
+ '~/.claude.json',
23
+ '~/.claude',
24
+ '~/Library/Application Support/Cloud',
25
+ '~/Library/Application Support/Claude',
26
+ '~/AppData/Roaming/Claude'
27
+ ];
28
+ return checkMultiplePaths(paths);
29
+ };
30
+ const detectVSCode = () => {
31
+ const paths = [
32
+ '~/.vscode',
33
+ '~/Library/Application Support/Code',
34
+ '~/AppData/Roaming/Code',
35
+ '~/.config/Code'
36
+ ];
37
+ return checkMultiplePaths(paths);
38
+ };
39
+ const detectCursor = () => {
40
+ const paths = [
41
+ '~/.cursor',
42
+ '~/Library/Application Support/Cursor',
43
+ '~/AppData/Roaming/Cursor',
44
+ '~/.config/Cursor'
45
+ ];
46
+ return checkMultiplePaths(paths);
47
+ };
48
+ const detectWindsurf = () => {
49
+ const paths = [
50
+ '~/.codeium/windsurf',
51
+ '~/Library/Application Support/Windsurf',
52
+ '~/AppData/Roaming/Windsurf',
53
+ '~/.config/windsurf'
54
+ ];
55
+ return checkMultiplePaths(paths);
56
+ };
57
+ exports.IDE_CONFIGS = [
58
+ {
59
+ name: 'Claude Code',
60
+ configPath: '~/.claude.json',
61
+ configFormat: 'json',
62
+ configType: 'claude-code',
63
+ detectMethod: detectClaude,
64
+ alternativePaths: [
65
+ '~/.claude/settings.json'
66
+ ],
67
+ description: 'Anthropic Claude Code CLI tool'
68
+ },
69
+ {
70
+ name: 'Claude Desktop / Cowork',
71
+ configPath: '~/AppData/Roaming/Claude/claude_desktop_config.json',
72
+ configFormat: 'json',
73
+ configType: 'claude',
74
+ detectMethod: detectClaude,
75
+ alternativePaths: [
76
+ '~/Library/Application Support/Claude/claude_desktop_config.json'
77
+ ],
78
+ description: 'Anthropic Claude Desktop and Cowork application'
79
+ },
80
+ {
81
+ name: 'Antigravity',
82
+ configPath: '~/.gemini/antigravity/mcp_config.json',
83
+ configFormat: 'json',
84
+ configType: 'standard',
85
+ detectMethod: () => fs_1.default.existsSync(expandPath('~/.gemini/antigravity')),
86
+ description: 'Google Gemini Antigravity IDE'
87
+ },
88
+ {
89
+ name: 'Kiro',
90
+ configPath: '~/.kiro/settings/mcp.json',
91
+ configFormat: 'json',
92
+ configType: 'kiro',
93
+ detectMethod: () => fs_1.default.existsSync(expandPath('~/.kiro')),
94
+ description: 'Kiro AI-powered IDE'
95
+ },
96
+ {
97
+ name: 'Cursor',
98
+ configPath: '~/.cursor/mcp.json',
99
+ configFormat: 'json',
100
+ configType: 'kiro',
101
+ detectMethod: detectCursor,
102
+ alternativePaths: [
103
+ '~/Library/Application Support/Cursor/mcp.json',
104
+ '~/AppData/Roaming/Cursor/mcp.json',
105
+ '~/.config/Cursor/mcp.json'
106
+ ],
107
+ description: 'Cursor AI code editor'
108
+ },
109
+ {
110
+ name: 'VSCode',
111
+ configPath: process.platform === 'win32'
112
+ ? '~/AppData/Roaming/Code/User/mcp.json'
113
+ : process.platform === 'darwin'
114
+ ? '~/Library/Application Support/Code/User/mcp.json'
115
+ : '~/.config/Code/User/mcp.json',
116
+ configFormat: 'json',
117
+ configType: 'vscode',
118
+ detectMethod: detectVSCode,
119
+ alternativePaths: [
120
+ '~/Library/Application Support/Code/User/mcp.json',
121
+ '~/AppData/Roaming/Code/User/mcp.json',
122
+ '~/.config/Code/User/mcp.json'
123
+ ],
124
+ description: 'Visual Studio Code'
125
+ },
126
+ {
127
+ name: 'Codex',
128
+ configPath: '~/.codex/config.toml',
129
+ configFormat: 'toml',
130
+ configType: 'codex',
131
+ detectMethod: () => fs_1.default.existsSync(expandPath('~/.codex')),
132
+ description: 'Codex AI development environment'
133
+ },
134
+ {
135
+ name: 'Windsurf',
136
+ configPath: '~/.codeium/windsurf/mcp_config.json',
137
+ configFormat: 'json',
138
+ configType: 'windsurf',
139
+ detectMethod: detectWindsurf,
140
+ alternativePaths: [
141
+ '~/Library/Application Support/Windsurf/mcp_config.json',
142
+ '~/AppData/Roaming/Windsurf/mcp_config.json',
143
+ '~/.config/windsurf/mcp_config.json'
144
+ ],
145
+ description: 'Codeium Windsurf IDE'
146
+ }
147
+ ];
148
+ const findBestConfigPath = (ide) => {
149
+ // First try the default path
150
+ if (fs_1.default.existsSync(expandPath(ide.configPath))) {
151
+ return ide.configPath;
152
+ }
153
+ // Then try alternative paths
154
+ if (ide.alternativePaths) {
155
+ for (const altPath of ide.alternativePaths) {
156
+ if (fs_1.default.existsSync(expandPath(altPath))) {
157
+ return altPath;
158
+ }
159
+ }
160
+ }
161
+ // Return default path if nothing found (will be created)
162
+ return ide.configPath;
163
+ };
164
+ const detectInstalledIDEs = () => {
165
+ return exports.IDE_CONFIGS.filter(ide => ide.detectMethod()).map(ide => ({
166
+ ...ide,
167
+ configPath: findBestConfigPath(ide)
168
+ }));
169
+ };
170
+ exports.detectInstalledIDEs = detectInstalledIDEs;
171
+ const getAllSupportedIDEs = () => {
172
+ return exports.IDE_CONFIGS;
173
+ };
174
+ exports.getAllSupportedIDEs = getAllSupportedIDEs;
175
+ const findIDEByName = (name) => {
176
+ return exports.IDE_CONFIGS.find(ide => ide.name.toLowerCase().includes(name.toLowerCase()) ||
177
+ name.toLowerCase().includes(ide.name.toLowerCase()));
178
+ };
179
+ exports.findIDEByName = findIDEByName;
@@ -0,0 +1,192 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateMCPConfig = exports.generateWindsurfMCPServers = exports.generateVSCodeMCPServers = exports.generateCodexMCPServers = exports.generateKiroMCPServers = exports.generateClaudeCodeMCPServers = exports.generateClaudeMCPServers = exports.generateStandardMCPServers = exports.mergeTomlMCPServers = exports.extractTomlMcpServerBlock = void 0;
4
+ const mcp_server_builder_1 = require("../mcp/mcp-server-builder");
5
+ const ide_formats_1 = require("../mcp/ide-formats");
6
+ const normalizeTokens = (tokenInput) => {
7
+ if (!tokenInput)
8
+ return {};
9
+ if (typeof tokenInput === 'string') {
10
+ return tokenInput ? { github: tokenInput } : {};
11
+ }
12
+ return tokenInput;
13
+ };
14
+ const findTomlServerBlockRange = (content, server) => {
15
+ const lines = content.split(/\r?\n/);
16
+ const serverSection = `mcp_servers.${server}`;
17
+ const serverHeader = `[${serverSection}]`;
18
+ const start = lines.findIndex(line => line.trim() === serverHeader);
19
+ if (start === -1) {
20
+ return null;
21
+ }
22
+ let end = lines.length;
23
+ for (let i = start + 1; i < lines.length; i++) {
24
+ const sectionMatch = lines[i].trim().match(/^\[([^\]]+)\]$/);
25
+ if (!sectionMatch)
26
+ continue;
27
+ const sectionName = sectionMatch[1];
28
+ if (sectionName === serverSection || sectionName.startsWith(`${serverSection}.`)) {
29
+ continue;
30
+ }
31
+ end = i;
32
+ break;
33
+ }
34
+ return { start, end };
35
+ };
36
+ const extractTomlMcpServerBlock = (content, server) => {
37
+ const range = findTomlServerBlockRange(content, server);
38
+ if (!range)
39
+ return null;
40
+ const lines = content.split(/\r?\n/);
41
+ return lines.slice(range.start, range.end).join('\n').trim();
42
+ };
43
+ exports.extractTomlMcpServerBlock = extractTomlMcpServerBlock;
44
+ const removeTomlMcpServerBlock = (content, server) => {
45
+ const range = findTomlServerBlockRange(content, server);
46
+ if (!range)
47
+ return content;
48
+ const lines = content.split(/\r?\n/);
49
+ const updated = [...lines.slice(0, range.start), ...lines.slice(range.end)].join('\n');
50
+ return updated.replace(/\n{3,}/g, '\n\n').trimEnd();
51
+ };
52
+ const appendTomlBlock = (content, block) => {
53
+ const trimmedContent = content.trimEnd();
54
+ const trimmedBlock = block.trim();
55
+ if (!trimmedBlock)
56
+ return trimmedContent;
57
+ if (!trimmedContent)
58
+ return `${trimmedBlock}\n`;
59
+ return `${trimmedContent}\n\n${trimmedBlock}\n`;
60
+ };
61
+ const mergeTomlMCPServers = (existingContent, generatedContent, servers) => {
62
+ let merged = existingContent || '';
63
+ const addedServers = [];
64
+ const replacedServers = [];
65
+ const skippedServers = [];
66
+ for (const server of servers) {
67
+ const newBlock = (0, exports.extractTomlMcpServerBlock)(generatedContent, server);
68
+ if (!newBlock) {
69
+ skippedServers.push(server);
70
+ continue;
71
+ }
72
+ const existingBlock = (0, exports.extractTomlMcpServerBlock)(merged, server);
73
+ if (existingBlock && existingBlock.trim() === newBlock.trim()) {
74
+ skippedServers.push(server);
75
+ continue;
76
+ }
77
+ if (existingBlock) {
78
+ merged = removeTomlMcpServerBlock(merged, server);
79
+ merged = appendTomlBlock(merged, newBlock);
80
+ replacedServers.push(server);
81
+ continue;
82
+ }
83
+ merged = appendTomlBlock(merged, newBlock);
84
+ addedServers.push(server);
85
+ }
86
+ return {
87
+ content: merged.trimEnd() + '\n',
88
+ addedServers,
89
+ replacedServers,
90
+ skippedServers
91
+ };
92
+ };
93
+ exports.mergeTomlMCPServers = mergeTomlMCPServers;
94
+ // Helper function to add all provider servers with their configs
95
+ const addProviderServers = async (builder, tokens, providerConfigs) => {
96
+ for (const [providerId, token] of Object.entries(tokens)) {
97
+ if (token) {
98
+ // Get provider-specific config if it exists
99
+ const config = providerConfigs?.[providerId];
100
+ await builder.addProvider(providerId, token, config);
101
+ }
102
+ }
103
+ };
104
+ const generateStandardMCPServers = async (fraimKey, tokenInput, providerConfigs) => {
105
+ const tokens = normalizeTokens(tokenInput);
106
+ const builder = new mcp_server_builder_1.MCPServerBuilder();
107
+ builder.addBaseServers(fraimKey);
108
+ // Dynamically add provider servers based on available tokens
109
+ await addProviderServers(builder, tokens, providerConfigs);
110
+ const format = (0, ide_formats_1.getIDEFormat)('standard');
111
+ return format.transform(builder.getServers());
112
+ };
113
+ exports.generateStandardMCPServers = generateStandardMCPServers;
114
+ const generateClaudeMCPServers = async (fraimKey, tokenInput, providerConfigs) => {
115
+ const tokens = normalizeTokens(tokenInput);
116
+ const builder = new mcp_server_builder_1.MCPServerBuilder();
117
+ builder.addBaseServers(fraimKey);
118
+ // Claude Desktop does not support HTTPS MCP servers (GitHub, GitLab, Jira)
119
+ // These cause Claude Desktop to break on boot
120
+ // See: https://github.com/mathursrus/FRAIM/issues/132
121
+ // The ClaudeFormat adapter will filter out HTTP servers
122
+ await addProviderServers(builder, tokens, providerConfigs);
123
+ const format = (0, ide_formats_1.getIDEFormat)('claude');
124
+ return format.transform(builder.getServers());
125
+ };
126
+ exports.generateClaudeMCPServers = generateClaudeMCPServers;
127
+ const generateClaudeCodeMCPServers = async (fraimKey, tokenInput, providerConfigs) => {
128
+ const tokens = normalizeTokens(tokenInput);
129
+ const builder = new mcp_server_builder_1.MCPServerBuilder();
130
+ builder.addBaseServers(fraimKey);
131
+ await addProviderServers(builder, tokens, providerConfigs);
132
+ const format = (0, ide_formats_1.getIDEFormat)('claude-code');
133
+ return format.transform(builder.getServers());
134
+ };
135
+ exports.generateClaudeCodeMCPServers = generateClaudeCodeMCPServers;
136
+ const generateKiroMCPServers = async (fraimKey, tokenInput, providerConfigs) => {
137
+ const tokens = normalizeTokens(tokenInput);
138
+ const builder = new mcp_server_builder_1.MCPServerBuilder();
139
+ builder.addBaseServers(fraimKey);
140
+ await addProviderServers(builder, tokens, providerConfigs);
141
+ const format = (0, ide_formats_1.getIDEFormat)('kiro');
142
+ return format.transform(builder.getServers());
143
+ };
144
+ exports.generateKiroMCPServers = generateKiroMCPServers;
145
+ const generateCodexMCPServers = async (fraimKey, tokenInput, providerConfigs) => {
146
+ const tokens = normalizeTokens(tokenInput);
147
+ const builder = new mcp_server_builder_1.MCPServerBuilder();
148
+ builder.addBaseServers(fraimKey);
149
+ await addProviderServers(builder, tokens, providerConfigs);
150
+ const format = (0, ide_formats_1.getIDEFormat)('codex');
151
+ return format.transform(builder.getServers());
152
+ };
153
+ exports.generateCodexMCPServers = generateCodexMCPServers;
154
+ const generateVSCodeMCPServers = async (fraimKey, tokenInput, providerConfigs) => {
155
+ const tokens = normalizeTokens(tokenInput);
156
+ const builder = new mcp_server_builder_1.MCPServerBuilder();
157
+ builder.addBaseServers(fraimKey);
158
+ await addProviderServers(builder, tokens, providerConfigs);
159
+ const format = (0, ide_formats_1.getIDEFormat)('vscode');
160
+ return format.transform(builder.getServers());
161
+ };
162
+ exports.generateVSCodeMCPServers = generateVSCodeMCPServers;
163
+ const generateWindsurfMCPServers = async (fraimKey, tokenInput, providerConfigs) => {
164
+ const tokens = normalizeTokens(tokenInput);
165
+ const builder = new mcp_server_builder_1.MCPServerBuilder();
166
+ builder.addBaseServers(fraimKey);
167
+ await addProviderServers(builder, tokens, providerConfigs);
168
+ const format = (0, ide_formats_1.getIDEFormat)('windsurf');
169
+ return format.transform(builder.getServers());
170
+ };
171
+ exports.generateWindsurfMCPServers = generateWindsurfMCPServers;
172
+ const generateMCPConfig = async (configType, fraimKey, tokenInput, providerConfigs) => {
173
+ switch (configType) {
174
+ case 'standard':
175
+ return await (0, exports.generateStandardMCPServers)(fraimKey, tokenInput, providerConfigs);
176
+ case 'claude':
177
+ return await (0, exports.generateClaudeMCPServers)(fraimKey, tokenInput, providerConfigs);
178
+ case 'claude-code':
179
+ return await (0, exports.generateClaudeCodeMCPServers)(fraimKey, tokenInput, providerConfigs);
180
+ case 'kiro':
181
+ return await (0, exports.generateKiroMCPServers)(fraimKey, tokenInput, providerConfigs);
182
+ case 'vscode':
183
+ return await (0, exports.generateVSCodeMCPServers)(fraimKey, tokenInput, providerConfigs);
184
+ case 'codex':
185
+ return await (0, exports.generateCodexMCPServers)(fraimKey, tokenInput, providerConfigs);
186
+ case 'windsurf':
187
+ return await (0, exports.generateWindsurfMCPServers)(fraimKey, tokenInput, providerConfigs);
188
+ default:
189
+ throw new Error(`Unsupported config type: ${configType}`);
190
+ }
191
+ };
192
+ exports.generateMCPConfig = generateMCPConfig;