fraim-framework 2.0.63 → 2.0.65

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 (106) hide show
  1. package/bin/fraim-mcp.js +52 -19
  2. package/bin/fraim.js +23 -0
  3. package/dist/src/cli/commands/add-ide.js +53 -14
  4. package/dist/src/cli/commands/doctor.js +12 -24
  5. package/dist/src/cli/commands/init-project.js +0 -3
  6. package/dist/src/cli/commands/init.js +0 -2
  7. package/dist/src/cli/commands/mcp.js +65 -0
  8. package/dist/src/cli/commands/setup.js +17 -1
  9. package/dist/src/cli/commands/sync.js +173 -104
  10. package/dist/src/cli/setup/auto-mcp-setup.js +6 -4
  11. package/dist/src/cli/setup/mcp-config-generator.js +65 -41
  12. package/dist/src/fraim/issue-tracking/ado-provider.js +304 -0
  13. package/dist/src/fraim/issue-tracking/factory.js +63 -0
  14. package/dist/src/fraim/issue-tracking/github-provider.js +200 -0
  15. package/dist/src/fraim/issue-tracking/types.js +7 -0
  16. package/dist/src/fraim/issue-tracking-config.js +83 -0
  17. package/dist/src/local-mcp-server/stdio-server.js +91 -15
  18. package/dist/src/utils/remote-sync.js +130 -0
  19. package/package.json +3 -4
  20. package/dist/src/utils/enforcement-utils.js +0 -239
  21. package/dist/src/utils/validate-workflows.js +0 -101
  22. package/registry/scripts/cleanup-branch.ts +0 -341
  23. package/registry/scripts/code-quality-check.sh +0 -566
  24. package/registry/scripts/comprehensive-explorer.py +0 -297
  25. package/registry/scripts/create-git-labels.sh +0 -49
  26. package/registry/scripts/create-website-structure.js +0 -562
  27. package/registry/scripts/detect-tautological-tests.sh +0 -38
  28. package/registry/scripts/evaluate-code-quality.ts +0 -36
  29. package/registry/scripts/exec-with-timeout.ts +0 -122
  30. package/registry/scripts/generate-engagement-emails.ts +0 -830
  31. package/registry/scripts/interactive-explorer.py +0 -270
  32. package/registry/scripts/markdown-to-pdf.js +0 -395
  33. package/registry/scripts/newsletter-helpers.ts +0 -777
  34. package/registry/scripts/pdf-styles.css +0 -172
  35. package/registry/scripts/prep-issue.sh +0 -548
  36. package/registry/scripts/productivity/build-productivity-csv.mjs +0 -242
  37. package/registry/scripts/productivity/fetch-pr-details.mjs +0 -144
  38. package/registry/scripts/productivity/productivity-report.sh +0 -147
  39. package/registry/scripts/profile-server.ts +0 -426
  40. package/registry/scripts/run-thank-you-workflow.ts +0 -122
  41. package/registry/scripts/scrape-site.py +0 -302
  42. package/registry/scripts/send-newsletter-simple.ts +0 -102
  43. package/registry/scripts/send-thank-you-emails.ts +0 -57
  44. package/registry/scripts/validate-openapi-limits.ts +0 -366
  45. package/registry/scripts/validate-test-coverage.ts +0 -280
  46. package/registry/scripts/verify-pr-comments.sh +0 -74
  47. package/registry/scripts/verify-test-coverage.ts +0 -36
  48. package/registry/stubs/workflows/bootstrap/create-architecture.md +0 -11
  49. package/registry/stubs/workflows/bootstrap/detect-broken-windows.md +0 -11
  50. package/registry/stubs/workflows/bootstrap/evaluate-code-quality.md +0 -11
  51. package/registry/stubs/workflows/bootstrap/verify-test-coverage.md +0 -11
  52. package/registry/stubs/workflows/brainstorming/blue-sky-brainstorming.md +0 -11
  53. package/registry/stubs/workflows/brainstorming/codebase-brainstorming.md +0 -11
  54. package/registry/stubs/workflows/business-development/create-business-plan.md +0 -11
  55. package/registry/stubs/workflows/business-development/ideate-business-opportunity.md +0 -11
  56. package/registry/stubs/workflows/business-development/price-product.md +0 -18
  57. package/registry/stubs/workflows/compliance/detect-compliance-requirements.md +0 -11
  58. package/registry/stubs/workflows/compliance/generate-audit-evidence.md +0 -11
  59. package/registry/stubs/workflows/compliance/soc2-evidence-generator.md +0 -11
  60. package/registry/stubs/workflows/customer-development/insight-analysis.md +0 -11
  61. package/registry/stubs/workflows/customer-development/insight-triage.md +0 -11
  62. package/registry/stubs/workflows/customer-development/interview-preparation.md +0 -11
  63. package/registry/stubs/workflows/customer-development/linkedin-outreach.md +0 -11
  64. package/registry/stubs/workflows/customer-development/strategic-brainstorming.md +0 -11
  65. package/registry/stubs/workflows/customer-development/thank-customers.md +0 -11
  66. package/registry/stubs/workflows/customer-development/user-survey-dispatch.md +0 -11
  67. package/registry/stubs/workflows/customer-development/users-to-target.md +0 -11
  68. package/registry/stubs/workflows/customer-development/weekly-newsletter.md +0 -11
  69. package/registry/stubs/workflows/deploy/cloud-deployment.md +0 -11
  70. package/registry/stubs/workflows/improve-fraim/contribute.md +0 -11
  71. package/registry/stubs/workflows/improve-fraim/file-issue.md +0 -11
  72. package/registry/stubs/workflows/learning/build-skillset.md +0 -11
  73. package/registry/stubs/workflows/learning/synthesize-learnings.md +0 -11
  74. package/registry/stubs/workflows/legal/contract-review-analysis.md +0 -11
  75. package/registry/stubs/workflows/legal/nda.md +0 -11
  76. package/registry/stubs/workflows/legal/patent-filing.md +0 -11
  77. package/registry/stubs/workflows/legal/saas-contract-development.md +0 -11
  78. package/registry/stubs/workflows/legal/trademark-filing.md +0 -11
  79. package/registry/stubs/workflows/marketing/content-creation.md +0 -11
  80. package/registry/stubs/workflows/marketing/convert-to-pdf.md +0 -11
  81. package/registry/stubs/workflows/marketing/create-modern-website.md +0 -11
  82. package/registry/stubs/workflows/marketing/domain-registration.md +0 -11
  83. package/registry/stubs/workflows/marketing/hbr-article.md +0 -11
  84. package/registry/stubs/workflows/marketing/launch-checklist.md +0 -11
  85. package/registry/stubs/workflows/marketing/marketing-strategy.md +0 -11
  86. package/registry/stubs/workflows/marketing/storytelling.md +0 -11
  87. package/registry/stubs/workflows/performance/analyze-performance.md +0 -11
  88. package/registry/stubs/workflows/product-building/design.md +0 -11
  89. package/registry/stubs/workflows/product-building/implement.md +0 -11
  90. package/registry/stubs/workflows/product-building/iterate-on-pr-comments.md +0 -11
  91. package/registry/stubs/workflows/product-building/prep-issue.md +0 -11
  92. package/registry/stubs/workflows/product-building/prototype.md +0 -11
  93. package/registry/stubs/workflows/product-building/resolve.md +0 -11
  94. package/registry/stubs/workflows/product-building/retrospect.md +0 -11
  95. package/registry/stubs/workflows/product-building/spec.md +0 -11
  96. package/registry/stubs/workflows/product-building/test.md +0 -11
  97. package/registry/stubs/workflows/productivity-report/productivity-report.md +0 -11
  98. package/registry/stubs/workflows/quality-assurance/browser-validation.md +0 -11
  99. package/registry/stubs/workflows/quality-assurance/iterative-improvement-cycle.md +0 -11
  100. package/registry/stubs/workflows/replicate/replicate-discovery.md +0 -11
  101. package/registry/stubs/workflows/replicate/replicate-to-issues.md +0 -11
  102. package/registry/stubs/workflows/reviewer/review-implementation-vs-design-spec.md +0 -11
  103. package/registry/stubs/workflows/reviewer/review-implementation-vs-feature-spec.md +0 -11
  104. package/registry/stubs/workflows/startup-credits/aws-activate-application.md +0 -11
  105. package/registry/stubs/workflows/startup-credits/google-cloud-application.md +0 -11
  106. package/registry/stubs/workflows/startup-credits/microsoft-azure-application.md +0 -11
package/bin/fraim-mcp.js CHANGED
@@ -1,30 +1,63 @@
1
1
  #!/usr/bin/env node
2
+
2
3
  /**
3
- * FRAIM Local MCP Proxy
4
- *
5
- * This is a thin wrapper that launches the local STDIO MCP server.
6
- * The actual implementation is in dist/src/local-mcp-server/stdio-server.js
4
+ * FRAIM MCP Server - Smart Entry Point
5
+ * This file handles both production (dist/) and development (src/) environments.
7
6
  */
8
7
 
9
8
  const path = require('path');
9
+ const fs = require('fs');
10
10
  const { spawn } = require('child_process');
11
11
 
12
- // Path to the actual server implementation
13
- const serverPath = path.join(__dirname, '..', 'dist', 'src', 'local-mcp-server', 'stdio-server.js');
12
+ /**
13
+ * Runs the MCP server using either the compiled JS or the source TS via tsx
14
+ */
15
+ function runMCPServer() {
16
+ const distPath = path.join(__dirname, '..', 'dist', 'src', 'local-mcp-server', 'stdio-server.js');
17
+ const srcPath = path.join(__dirname, '..', 'src', 'local-mcp-server', 'stdio-server.ts');
14
18
 
15
- // Spawn the server with all arguments and environment variables
16
- const server = spawn('node', [serverPath, ...process.argv.slice(2)], {
17
- stdio: 'inherit',
18
- env: process.env
19
- });
19
+ // 1. Check if we have a compiled version (Production / CI)
20
+ if (fs.existsSync(distPath)) {
21
+ // Use spawn to run the compiled JS so it's treated as the main module
22
+ const result = spawn('node', [distPath, ...process.argv.slice(2)], {
23
+ stdio: 'inherit',
24
+ shell: false,
25
+ windowsHide: true
26
+ });
27
+
28
+ // Forward exit code
29
+ result.on('exit', (code) => {
30
+ process.exit(code || 0);
31
+ });
32
+
33
+ return;
34
+ }
20
35
 
21
- // Forward exit code
22
- server.on('exit', (code) => {
23
- process.exit(code || 0);
24
- });
36
+ // 2. Fallback to source version using tsx (Development)
37
+ if (fs.existsSync(srcPath)) {
38
+ // Use spawn to run tsx so it handles stdio correctly for MCP
39
+ const result = spawn('npx', ['tsx', srcPath, ...process.argv.slice(2)], {
40
+ stdio: 'inherit',
41
+ shell: true,
42
+ windowsHide: true
43
+ });
44
+
45
+ // Forward exit code
46
+ result.on('exit', (code) => {
47
+ process.exit(code || 0);
48
+ });
49
+
50
+ return;
51
+ }
25
52
 
26
- // Handle errors
27
- server.on('error', (err) => {
28
- console.error('Failed to start FRAIM MCP server:', err);
53
+ console.error('❌ FRAIM MCP Server Error: Could not find server entry point.');
54
+ console.error('Expected one of:');
55
+ console.error(` - ${distPath}`);
56
+ console.error(` - ${srcPath}`);
29
57
  process.exit(1);
30
- });
58
+ }
59
+
60
+ // If this file is run directly, run the MCP server
61
+ if (require.main === module) {
62
+ runMCPServer();
63
+ }
package/bin/fraim.js ADDED
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * FRAIM Framework CLI Entry Point
5
+ *
6
+ * This file delegates to the compiled TypeScript implementation.
7
+ */
8
+
9
+ try {
10
+ // In production/installed package, code is in dist/
11
+ require('../dist/src/cli/fraim.js');
12
+ } catch (error) {
13
+ if (error.code === 'MODULE_NOT_FOUND') {
14
+ // In development (local clone), we might use tsx if dist is missing
15
+ // But typically we should just tell user to build.
16
+ console.error('❌ Could not find FRAIM CLI implementation.');
17
+ console.error(' If you are running from source, please run "npm run build" first.');
18
+ console.error(` Error details: ${error.message}`);
19
+ process.exit(1);
20
+ } else {
21
+ throw error;
22
+ }
23
+ }
@@ -21,7 +21,8 @@ const loadGlobalConfig = () => {
21
21
  const config = JSON.parse(fs_1.default.readFileSync(globalConfigPath, 'utf8'));
22
22
  return {
23
23
  fraimKey: config.apiKey,
24
- githubToken: config.githubToken
24
+ githubToken: config.tokens?.github || config.githubToken, // Support both old and new format
25
+ mode: config.mode
25
26
  };
26
27
  }
27
28
  catch (e) {
@@ -29,22 +30,44 @@ const loadGlobalConfig = () => {
29
30
  }
30
31
  };
31
32
  exports.loadGlobalConfig = loadGlobalConfig;
32
- const promptForGitHubToken = async () => {
33
- console.log(chalk_1.default.yellow('\n🔑 GitHub token needed for MCP configuration'));
34
- console.log(chalk_1.default.gray('This is required for git and GitHub MCP servers to function properly.\n'));
33
+ const promptForGitHubToken = async (isConversationalMode = false) => {
34
+ if (isConversationalMode) {
35
+ console.log(chalk_1.default.yellow('\n🔑 GitHub token (optional for conversational mode)'));
36
+ console.log(chalk_1.default.gray('GitHub token enables GitHub-specific MCP features.\n'));
37
+ const wantsToken = await (0, prompts_1.default)({
38
+ type: 'confirm',
39
+ name: 'addToken',
40
+ message: 'Do you want to add a GitHub token?',
41
+ initial: false
42
+ });
43
+ if (!wantsToken.addToken) {
44
+ console.log(chalk_1.default.blue('ℹ️ Skipping GitHub token - GitHub MCP server will not be configured'));
45
+ return '';
46
+ }
47
+ }
48
+ else {
49
+ console.log(chalk_1.default.yellow('\n🔑 GitHub token needed for MCP configuration'));
50
+ console.log(chalk_1.default.gray('This is required for git and GitHub MCP servers to function properly.\n'));
51
+ }
35
52
  const tokenResponse = await (0, prompts_1.default)({
36
53
  type: 'password',
37
54
  name: 'token',
38
55
  message: 'Enter your GitHub token',
39
56
  validate: (value) => {
40
- if (!value)
57
+ if (!value && !isConversationalMode)
41
58
  return 'GitHub token is required';
59
+ if (!value && isConversationalMode)
60
+ return true; // Allow empty in conversational mode
42
61
  if (value.startsWith('ghp_') || value.startsWith('github_pat_'))
43
62
  return true;
44
63
  return 'Please enter a valid GitHub token (starts with ghp_ or github_pat_)';
45
64
  }
46
65
  });
47
66
  if (!tokenResponse.token) {
67
+ if (isConversationalMode) {
68
+ console.log(chalk_1.default.blue('ℹ️ No GitHub token provided - GitHub MCP server will not be configured'));
69
+ return '';
70
+ }
48
71
  console.log(chalk_1.default.red('GitHub token is required. Exiting.'));
49
72
  process.exit(1);
50
73
  }
@@ -55,7 +78,13 @@ const saveGitHubTokenToConfig = (githubToken) => {
55
78
  if (fs_1.default.existsSync(globalConfigPath)) {
56
79
  try {
57
80
  const config = JSON.parse(fs_1.default.readFileSync(globalConfigPath, 'utf8'));
58
- config.githubToken = githubToken;
81
+ // Use new tokens structure if it exists, otherwise fall back to old format
82
+ if (config.tokens) {
83
+ config.tokens.github = githubToken;
84
+ }
85
+ else {
86
+ config.githubToken = githubToken;
87
+ }
59
88
  fs_1.default.writeFileSync(globalConfigPath, JSON.stringify(config, null, 2));
60
89
  console.log(chalk_1.default.green('✅ GitHub token saved to global config'));
61
90
  }
@@ -170,7 +199,7 @@ const listSupportedIDEs = () => {
170
199
  console.log(chalk_1.default.yellow('💡 Use "fraim add-ide --ide <name>" to configure a specific IDE'));
171
200
  console.log(chalk_1.default.yellow(' Example: fraim add-ide --ide claude'));
172
201
  };
173
- const promptForIDESelection = async (availableIDEs) => {
202
+ const promptForIDESelection = async (availableIDEs, githubToken) => {
174
203
  console.log(chalk_1.default.green(`✅ Found ${availableIDEs.length} IDEs that can be configured:\n`));
175
204
  availableIDEs.forEach((ide, index) => {
176
205
  const configExists = fs_1.default.existsSync((0, ide_detector_1.expandPath)(ide.configPath));
@@ -181,7 +210,9 @@ const promptForIDESelection = async (availableIDEs) => {
181
210
  console.log(chalk_1.default.blue('\nFRAIM will add these MCP servers:'));
182
211
  console.log(chalk_1.default.gray(' • fraim (workflows and AI management)'));
183
212
  console.log(chalk_1.default.gray(' • git (version control integration)'));
184
- console.log(chalk_1.default.gray(' • github (GitHub API access)'));
213
+ if (githubToken) {
214
+ console.log(chalk_1.default.gray(' • github (GitHub API access)'));
215
+ }
185
216
  console.log(chalk_1.default.gray(' • playwright (browser automation)'));
186
217
  const response = await (0, prompts_1.default)({
187
218
  type: 'text',
@@ -221,12 +252,20 @@ const runAddIDE = async (options) => {
221
252
  process.exit(1);
222
253
  }
223
254
  let githubToken = globalConfig.githubToken;
224
- if (!githubToken) {
255
+ const isConversationalMode = globalConfig.mode === 'conversational';
256
+ if (!githubToken && !isConversationalMode) {
225
257
  console.log(chalk_1.default.yellow('⚠️ No GitHub token found in configuration.'));
226
- githubToken = await promptForGitHubToken();
227
- saveGitHubTokenToConfig(githubToken);
258
+ githubToken = await promptForGitHubToken(false);
259
+ if (githubToken) {
260
+ saveGitHubTokenToConfig(githubToken);
261
+ }
262
+ }
263
+ if (isConversationalMode && !githubToken) {
264
+ console.log(chalk_1.default.blue('ℹ️ Conversational mode: Configuring MCP without GitHub integration\n'));
265
+ }
266
+ else {
267
+ console.log(chalk_1.default.green('✅ Using existing FRAIM configuration\n'));
228
268
  }
229
- console.log(chalk_1.default.green('✅ Using existing FRAIM configuration\n'));
230
269
  // Detect available IDEs
231
270
  const detectedIDEs = (0, ide_detector_1.detectInstalledIDEs)();
232
271
  if (detectedIDEs.length === 0) {
@@ -258,7 +297,7 @@ const runAddIDE = async (options) => {
258
297
  }
259
298
  else {
260
299
  // Interactive selection
261
- idesToConfigure = await promptForIDESelection(detectedIDEs);
300
+ idesToConfigure = await promptForIDESelection(detectedIDEs, githubToken);
262
301
  }
263
302
  if (idesToConfigure.length === 0) {
264
303
  console.log(chalk_1.default.yellow('⚠️ No IDEs selected for configuration.'));
@@ -271,7 +310,7 @@ const runAddIDE = async (options) => {
271
310
  };
272
311
  for (const ide of idesToConfigure) {
273
312
  try {
274
- await configureIDEMCP(ide, globalConfig.fraimKey, githubToken);
313
+ await configureIDEMCP(ide, globalConfig.fraimKey, githubToken || '');
275
314
  results.successful.push(ide.name);
276
315
  }
277
316
  catch (error) {
@@ -8,7 +8,6 @@ const commander_1 = require("commander");
8
8
  const fs_1 = __importDefault(require("fs"));
9
9
  const path_1 = __importDefault(require("path"));
10
10
  const chalk_1 = __importDefault(require("chalk"));
11
- const digest_utils_1 = require("../../utils/digest-utils");
12
11
  exports.doctorCommand = new commander_1.Command('doctor')
13
12
  .description('Validate FRAIM installation and configuration')
14
13
  .action(async () => {
@@ -50,33 +49,22 @@ exports.doctorCommand = new commander_1.Command('doctor')
50
49
  issuesFound++;
51
50
  }
52
51
  }
53
- // 4. Check registry & sync status
54
- const digestPath = path_1.default.join(fraimDir, '.digest');
55
- // Try 4 levels up (dist/src/cli/commands -> root)
56
- let registryPath = path_1.default.join(__dirname, '../../../../registry/stubs');
57
- if (!fs_1.default.existsSync(registryPath)) {
58
- // Try 3 levels up (src/cli/commands -> root)
59
- registryPath = path_1.default.join(__dirname, '../../../registry/stubs');
60
- }
61
- // Fallback for local development if running from within the framework repo itself (and CWD is root)
62
- if (!fs_1.default.existsSync(registryPath)) {
63
- registryPath = path_1.default.join(projectRoot, 'registry/stubs');
64
- }
65
- if (!fs_1.default.existsSync(registryPath)) {
66
- console.log(chalk_1.default.yellow('⚠️ Could not locate framework stub registry. (Expected in node_modules/@fraim/framework/registry/stubs)'));
67
- }
68
- else {
69
- console.log(chalk_1.default.green('✅ Framework stub registry found.'));
70
- const currentDigest = await (0, digest_utils_1.generateDigest)(registryPath);
71
- const existingDigest = fs_1.default.existsSync(digestPath) ? fs_1.default.readFileSync(digestPath, 'utf8') : '';
72
- if (currentDigest !== existingDigest) {
73
- console.log(chalk_1.default.yellow('⚠️ Local stubs are out of sync with registry. Run "fraim sync".'));
74
- issuesFound++;
52
+ // 4. Check sync status (remote or local)
53
+ // With Issue #83, stubs are no longer in the package - they're fetched from remote server
54
+ // Check if config has remoteUrl configured
55
+ try {
56
+ const config = JSON.parse(fs_1.default.readFileSync(configPath, 'utf8'));
57
+ if (config.remoteUrl && config.apiKey) {
58
+ console.log(chalk_1.default.green('✅ Remote sync configured (remoteUrl and apiKey present).'));
75
59
  }
76
60
  else {
77
- console.log(chalk_1.default.green(' Local stubs are in sync.'));
61
+ console.log(chalk_1.default.yellow('⚠️ Remote sync not configured. Run "fraim sync" to fetch workflows from server.'));
62
+ console.log(chalk_1.default.gray(' Add remoteUrl and apiKey to .fraim/config.json for remote sync.'));
78
63
  }
79
64
  }
65
+ catch (e) {
66
+ // Config check already failed above, skip this check
67
+ }
80
68
  if (issuesFound === 0) {
81
69
  console.log(chalk_1.default.green('\n✨ Everything looks great! Your project is FRAIM-ready.'));
82
70
  }
@@ -62,7 +62,6 @@ const runInitProject = async () => {
62
62
  project: {
63
63
  name: projectName
64
64
  },
65
- mode: 'conversational',
66
65
  customizations: {
67
66
  workflowsPath: '.fraim/workflows'
68
67
  }
@@ -88,7 +87,6 @@ const runInitProject = async () => {
88
87
  name: detection.repository.name
89
88
  },
90
89
  repository: detection.repository,
91
- mode: 'integrated',
92
90
  customizations: {
93
91
  workflowsPath: '.fraim/workflows'
94
92
  }
@@ -123,7 +121,6 @@ const runInitProject = async () => {
123
121
  url: `https://github.com/your-username/${repoName}.git`,
124
122
  defaultBranch: 'main'
125
123
  },
126
- mode: 'integrated',
127
124
  customizations: {
128
125
  workflowsPath: '.fraim/workflows'
129
126
  }
@@ -61,7 +61,6 @@ const runInit = async (options = {}) => {
61
61
  project: {
62
62
  name: projectName
63
63
  },
64
- mode: 'conversational',
65
64
  customizations: {
66
65
  workflowsPath: '.fraim/workflows'
67
66
  }
@@ -99,7 +98,6 @@ const runInit = async (options = {}) => {
99
98
  name: detection.repository.name
100
99
  },
101
100
  repository: detection.repository,
102
- mode: 'integrated',
103
101
  customizations: {
104
102
  workflowsPath: '.fraim/workflows'
105
103
  }
@@ -0,0 +1,65 @@
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.mcpCommand = void 0;
7
+ const commander_1 = require("commander");
8
+ const server_1 = require("../../local-mcp-server/server");
9
+ const chalk_1 = __importDefault(require("chalk"));
10
+ exports.mcpCommand = new commander_1.Command('mcp')
11
+ .description('Start the local FRAIM MCP server')
12
+ .option('-p, --port <port>', 'Port to run the server on', '3003')
13
+ .option('--remote-only', 'Use remote server only (skip local proxy)', false)
14
+ .action(async (options) => {
15
+ try {
16
+ if (options.remoteOnly) {
17
+ console.log(chalk_1.default.yellow('⚠️ Remote-only mode not yet implemented'));
18
+ console.log(chalk_1.default.blue('ℹ️ Starting local MCP server instead...'));
19
+ }
20
+ const port = parseInt(options.port);
21
+ if (isNaN(port) || port < 1 || port > 65535) {
22
+ console.error(chalk_1.default.red('❌ Invalid port number. Must be between 1 and 65535.'));
23
+ process.exit(1);
24
+ }
25
+ console.log(chalk_1.default.blue('🚀 Starting FRAIM Local MCP Server...'));
26
+ console.log(chalk_1.default.gray(`📡 Port: ${port}`));
27
+ console.log(chalk_1.default.gray(`🔄 Auto-updates: Every 5 minutes`));
28
+ console.log(chalk_1.default.gray(`📁 Cache: ~/.fraim/cache`));
29
+ console.log('');
30
+ // Set the port in environment
31
+ process.env.FRAIM_LOCAL_MCP_PORT = port.toString();
32
+ // Start the server
33
+ await (0, server_1.startLocalMCPServer)();
34
+ // Server is now running, show configuration instructions
35
+ console.log('');
36
+ console.log(chalk_1.default.green('✅ FRAIM Local MCP Server is running!'));
37
+ console.log('');
38
+ console.log(chalk_1.default.bold('📋 Agent Configuration:'));
39
+ console.log('');
40
+ console.log(chalk_1.default.gray('Add this to your agent\'s MCP configuration:'));
41
+ console.log('');
42
+ console.log(chalk_1.default.cyan(JSON.stringify({
43
+ "mcpServers": {
44
+ "fraim": {
45
+ "command": "fraim",
46
+ "args": ["mcp"],
47
+ "env": {}
48
+ }
49
+ }
50
+ }, null, 2)));
51
+ console.log('');
52
+ console.log(chalk_1.default.bold('🔗 Endpoints:'));
53
+ console.log(chalk_1.default.gray(` MCP: http://localhost:${port}/mcp`));
54
+ console.log(chalk_1.default.gray(` Health: http://localhost:${port}/health`));
55
+ console.log('');
56
+ console.log(chalk_1.default.bold('🛑 To stop the server:'));
57
+ console.log(chalk_1.default.gray(' Press Ctrl+C'));
58
+ console.log('');
59
+ }
60
+ catch (error) {
61
+ console.error(chalk_1.default.red('❌ Failed to start Local MCP Server:'));
62
+ console.error(chalk_1.default.red(error instanceof Error ? error.message : String(error)));
63
+ process.exit(1);
64
+ }
65
+ });
@@ -370,8 +370,24 @@ const runSetup = async (options) => {
370
370
  // Save global configuration
371
371
  console.log(chalk_1.default.blue('💾 Saving global configuration...'));
372
372
  saveGlobalConfig(fraimKey, mode, tokens);
373
- // Sync global scripts (only on initial setup)
373
+ // Configure MCP servers (only on initial setup)
374
374
  if (!isUpdate) {
375
+ console.log(chalk_1.default.blue('\n🔌 Configuring MCP servers...'));
376
+ // For conversational mode, we still configure MCP but without GitHub token requirement
377
+ // The FRAIM MCP server works without GitHub token, other servers can be optional
378
+ const mcpGitHubToken = tokens.github || '';
379
+ if (mode === 'conversational' && !mcpGitHubToken) {
380
+ console.log(chalk_1.default.yellow('ℹ️ Conversational mode: Configuring MCP servers without GitHub integration'));
381
+ console.log(chalk_1.default.gray(' FRAIM workflows will work, but GitHub-specific features will be unavailable\n'));
382
+ }
383
+ try {
384
+ await (0, auto_mcp_setup_1.autoConfigureMCP)(fraimKey, mcpGitHubToken, options.ide ? [options.ide] : undefined);
385
+ }
386
+ catch (e) {
387
+ console.log(chalk_1.default.yellow('⚠️ MCP configuration encountered issues'));
388
+ console.log(chalk_1.default.gray(' You can configure MCP manually or run setup again later\n'));
389
+ }
390
+ // Sync global scripts
375
391
  syncGlobalScripts();
376
392
  }
377
393
  // Show summary