fraim-framework 2.0.30 → 2.0.33

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 (67) hide show
  1. package/dist/src/cli/commands/init.js +29 -2
  2. package/dist/src/cli/commands/sync.js +18 -1
  3. package/dist/src/utils/script-sync-utils.js +218 -0
  4. package/dist/tests/debug-tools.js +6 -5
  5. package/dist/tests/test-chalk-regression.js +58 -8
  6. package/dist/tests/test-cli.js +70 -5
  7. package/dist/tests/test-end-to-end-hybrid-validation.js +349 -0
  8. package/dist/tests/test-first-run-journey.js +43 -3
  9. package/dist/tests/test-hybrid-script-execution.js +369 -0
  10. package/dist/tests/test-mcp-connection.js +2 -2
  11. package/dist/tests/test-mcp-issue-integration.js +12 -4
  12. package/dist/tests/test-mcp-lifecycle-methods.js +4 -4
  13. package/dist/tests/test-node-compatibility.js +24 -2
  14. package/dist/tests/test-prep-issue.js +4 -1
  15. package/dist/tests/test-script-location-independence.js +173 -0
  16. package/dist/tests/test-script-sync.js +557 -0
  17. package/dist/tests/test-session-rehydration.js +2 -2
  18. package/dist/tests/test-standalone.js +3 -3
  19. package/dist/tests/test-sync-version-update.js +1 -1
  20. package/dist/tests/test-telemetry.js +2 -2
  21. package/dist/tests/test-user-journey.js +8 -4
  22. package/dist/tests/test-utils.js +13 -0
  23. package/dist/tests/test-wizard.js +2 -2
  24. package/package.json +3 -3
  25. package/registry/rules/agent-testing-guidelines.md +502 -502
  26. package/registry/rules/ephemeral-execution.md +37 -27
  27. package/registry/rules/local-development.md +253 -251
  28. package/registry/rules/successful-debugging-patterns.md +491 -482
  29. package/registry/scripts/prep-issue.sh +468 -468
  30. package/registry/workflows/bootstrap/evaluate-code-quality.md +8 -2
  31. package/registry/workflows/bootstrap/verify-test-coverage.md +8 -2
  32. package/registry/workflows/customer-development/thank-customers.md +203 -193
  33. package/registry/workflows/customer-development/weekly-newsletter.md +366 -362
  34. package/registry/workflows/performance/analyze-performance.md +65 -63
  35. package/registry/workflows/product-building/implement.md +6 -2
  36. package/registry/workflows/product-building/prep-issue.md +11 -24
  37. package/registry/workflows/product-building/resolve.md +5 -1
  38. package/registry/workflows/replicate/replicate-discovery.md +336 -0
  39. package/registry/workflows/replicate/replicate-to-issues.md +319 -0
  40. package/registry/workflows/reviewer/review-implementation-vs-design-spec.md +632 -632
  41. package/.windsurf/rules/windsurf-rules.md +0 -7
  42. package/.windsurf/workflows/resolve-issue.md +0 -6
  43. package/.windsurf/workflows/retrospect.md +0 -6
  44. package/.windsurf/workflows/start-design.md +0 -6
  45. package/.windsurf/workflows/start-impl.md +0 -6
  46. package/.windsurf/workflows/start-spec.md +0 -6
  47. package/.windsurf/workflows/start-tests.md +0 -6
  48. package/bin/fraim.js +0 -23
  49. package/registry/scripts/build-scripts-generator.ts +0 -216
  50. package/registry/scripts/cleanup-branch.ts +0 -303
  51. package/registry/scripts/fraim-config.ts +0 -63
  52. package/registry/scripts/generate-engagement-emails.ts +0 -744
  53. package/registry/scripts/generic-issues-api.ts +0 -110
  54. package/registry/scripts/newsletter-helpers.ts +0 -874
  55. package/registry/scripts/openapi-generator.ts +0 -695
  56. package/registry/scripts/performance/profile-server.ts +0 -370
  57. package/registry/scripts/run-thank-you-workflow.ts +0 -122
  58. package/registry/scripts/send-newsletter-simple.ts +0 -104
  59. package/registry/scripts/send-thank-you-emails.ts +0 -57
  60. package/registry/workflows/replicate/re-implementation-strategy.md +0 -226
  61. package/registry/workflows/replicate/use-case-extraction.md +0 -135
  62. package/registry/workflows/replicate/visual-analysis.md +0 -154
  63. package/registry/workflows/replicate/website-discovery-analysis.md +0 -231
  64. package/sample_package.json +0 -18
  65. /package/registry/scripts/{replicate/comprehensive-explorer.py → comprehensive-explorer.py} +0 -0
  66. /package/registry/scripts/{replicate/interactive-explorer.py → interactive-explorer.py} +0 -0
  67. /package/registry/scripts/{replicate/scrape-site.py → scrape-site.py} +0 -0
@@ -1,695 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * FRAIM OpenAPI Generator
5
- *
6
- * Auto-generates OpenAPI specification, instructions.txt, KB files, and MCP server structure
7
- * for any project using FRAIM.
8
- *
9
- * Usage:
10
- * npx tsx scripts/openapi-generator.ts
11
- *
12
- * This will:
13
- * 1. Generate openapi.json based on project routes
14
- * 2. Generate instructions.txt for ChatGPT
15
- * 3. Create KB-*.txt files for detailed documentation
16
- * 4. Generate MCP server structure
17
- * 5. Set up build-time validation
18
- */
19
-
20
- import { readFileSync, writeFileSync, existsSync, mkdirSync, readdirSync } from 'fs';
21
- import { join, dirname } from 'path';
22
- import { loadFraimConfig } from '../../src/fraim/config-loader.js';
23
- import type { FraimConfig } from '../../src/fraim/types.js';
24
-
25
- const INSTRUCTIONS_LIMIT = 8000;
26
- const OPENAPI_ENDPOINT_LIMIT = 35;
27
- const OPENAPI_DESC_LIMIT = 300;
28
-
29
- interface EndpointInfo {
30
- path: string;
31
- method: string;
32
- description: string;
33
- operationId: string;
34
- requiresAuth: boolean;
35
- isConsequential: boolean;
36
- }
37
-
38
- /**
39
- * Generate OpenAPI specification from project routes
40
- */
41
- export function generateOpenAPI(config: any): any {
42
- const projectName = config.project.name || 'My Project';
43
- const projectDescription = config.project.description || 'API for ' + projectName;
44
- const baseUrl = config.api?.baseUrl || 'https://api.example.com';
45
-
46
- // Start with base OpenAPI structure
47
- const openapi: any = {
48
- openapi: '3.1.1',
49
- info: {
50
- title: `${projectName} API`,
51
- description: projectDescription,
52
- version: config.project.version || '1.0.0',
53
- contact: {
54
- name: projectName,
55
- email: config.project.contactEmail || 'support@example.com'
56
- }
57
- },
58
- servers: [
59
- {
60
- url: baseUrl,
61
- description: projectName
62
- }
63
- ],
64
- security: [
65
- {
66
- BearerAuth: []
67
- }
68
- ],
69
- components: {
70
- securitySchemes: {
71
- BearerAuth: {
72
- type: 'http',
73
- scheme: 'bearer',
74
- bearerFormat: 'JWT',
75
- description: 'JWT token obtained from OAuth authentication'
76
- }
77
- },
78
- schemas: {
79
- Error: {
80
- type: 'object',
81
- properties: {
82
- success: {
83
- type: 'boolean',
84
- example: false
85
- },
86
- error: {
87
- type: 'string',
88
- description: 'Error message'
89
- },
90
- message: {
91
- type: 'string',
92
- description: 'Human-readable error message'
93
- }
94
- },
95
- required: ['success', 'error']
96
- },
97
- Success: {
98
- type: 'object',
99
- properties: {
100
- success: {
101
- type: 'boolean',
102
- example: true
103
- },
104
- message: {
105
- type: 'string',
106
- description: 'Success message'
107
- },
108
- data: {
109
- type: 'object',
110
- description: 'Response data'
111
- }
112
- },
113
- required: ['success']
114
- }
115
- }
116
- },
117
- paths: {}
118
- };
119
-
120
- // Add issue filing endpoint (generic, always included)
121
- openapi.paths['/issues/create'] = {
122
- post: {
123
- operationId: 'createIssue',
124
- summary: 'Create a GitHub issue',
125
- description: 'Create a new issue in the project repository. Can be invoked through ChatGPT OpenAPI or MCP.',
126
- 'x-openai-isConsequential': false,
127
- tags: ['Issues'],
128
- security: [{ BearerAuth: [] }],
129
- requestBody: {
130
- required: true,
131
- content: {
132
- 'application/json': {
133
- schema: {
134
- type: 'object',
135
- properties: {
136
- title: {
137
- type: 'string',
138
- description: 'Issue title',
139
- example: 'Bug: Feature not working'
140
- },
141
- body: {
142
- type: 'string',
143
- description: 'Issue description',
144
- example: 'Detailed description of the issue'
145
- },
146
- labels: {
147
- type: 'array',
148
- items: { type: 'string' },
149
- description: 'Optional labels for the issue',
150
- example: ['bug', 'high-priority']
151
- }
152
- },
153
- required: ['title', 'body']
154
- }
155
- }
156
- }
157
- },
158
- responses: {
159
- '200': {
160
- description: 'Issue created successfully',
161
- content: {
162
- 'application/json': {
163
- schema: {
164
- allOf: [
165
- { $ref: '#/components/schemas/Success' },
166
- {
167
- type: 'object',
168
- properties: {
169
- issueNumber: {
170
- type: 'integer',
171
- description: 'GitHub issue number'
172
- },
173
- issueUrl: {
174
- type: 'string',
175
- format: 'uri',
176
- description: 'URL to the created issue'
177
- }
178
- }
179
- }
180
- ]
181
- }
182
- }
183
- }
184
- },
185
- '400': {
186
- description: 'Bad request',
187
- content: {
188
- 'application/json': {
189
- schema: { $ref: '#/components/schemas/Error' }
190
- }
191
- }
192
- },
193
- '401': {
194
- description: 'Unauthorized',
195
- content: {
196
- 'application/json': {
197
- schema: { $ref: '#/components/schemas/Error' }
198
- }
199
- }
200
- },
201
- '500': {
202
- description: 'Internal server error',
203
- content: {
204
- 'application/json': {
205
- schema: { $ref: '#/components/schemas/Error' }
206
- }
207
- }
208
- }
209
- }
210
- }
211
- };
212
-
213
- return openapi;
214
- }
215
-
216
- /**
217
- * Generate instructions.txt for ChatGPT
218
- */
219
- export function generateInstructions(config: any): string {
220
- const projectName = config.project.name || 'My Project';
221
- const projectDescription = config.project.description || 'API for ' + projectName;
222
-
223
- let instructions = `# Intent
224
- You are an AI assistant for ${projectName} - ${projectDescription}
225
-
226
- # Personality
227
- Helpful, friendly, professional. Put the user first and manage their time efficiently.
228
-
229
- # Communication
230
- Use plain ASCII only. No en dashes, em dashes, curly quotes, or ellipses. Use hyphens, straight quotes, and three dots instead.
231
-
232
- # Key Rules
233
- - Never claim to complete actions without verified tool/API use
234
- - Always get confirmation before performing destructive actions
235
- - See KB files for details on various aspects of operation
236
-
237
- ## Authentication
238
- Most endpoints require Bearer token authentication. Exception: Public endpoints (if any).
239
-
240
- **When User Asks to Log In/Sign In/Authenticate:**
241
- - Call authentication endpoint. If it returns 401 Unauthorized, ChatGPT's OAuth system will automatically present the login button/redirect.
242
- - NO explanations about OAuth, NO lists of steps, NO instructions. Just call the endpoint - ChatGPT's OAuth handles the rest automatically.
243
-
244
- ## Core Commands
245
-
246
- ### 1. POST /issues/create - Create GitHub Issue
247
- **MUST be available for all FRAIM projects.** Create a new issue in the project repository. Can be invoked through ChatGPT OpenAPI or MCP.
248
-
249
- **Request Body:**
250
- - \`title\` (string, required): Issue title
251
- - \`body\` (string, required): Issue description
252
- - \`labels\` (array of strings, optional): Labels for the issue
253
-
254
- **Response:**
255
- - \`success\` (boolean): Whether the issue was created
256
- - \`issueNumber\` (integer): GitHub issue number
257
- - \`issueUrl\` (string): URL to the created issue
258
-
259
- **Usage:** When user reports a bug, requests a feature, or needs to file an issue, use this endpoint.
260
-
261
- ## Response Format
262
- All responses: \`{"success": true/false, "message": "Description", "data": {}}\`
263
-
264
- ## KB Files
265
- See KB-*.txt files for detailed information on:
266
- - KB-issues.txt: Issue filing and management
267
- - KB-authentication.txt: Authentication and authorization
268
- - KB-api-overview.txt: API overview and common patterns
269
-
270
- ## Next Steps
271
- 1. Read KB files for detailed workflows
272
- 2. Use endpoints as described
273
- 3. Always confirm with user before destructive actions
274
- `;
275
-
276
- // Ensure instructions are within limit
277
- if (instructions.length > INSTRUCTIONS_LIMIT) {
278
- console.warn(`⚠️ Instructions exceed ${INSTRUCTIONS_LIMIT} character limit (${instructions.length} chars)`);
279
- console.warn(' Consider moving detailed content to KB files');
280
- }
281
-
282
- return instructions;
283
- }
284
-
285
- /**
286
- * Generate KB files
287
- */
288
- export function generateKBFiles(config: any, outputDir: string): void {
289
- if (!existsSync(outputDir)) {
290
- mkdirSync(outputDir, { recursive: true });
291
- }
292
-
293
- // KB-issues.txt - Issue filing
294
- const kbIssues = `# Issue Filing and Management
295
-
296
- ## Overview
297
- This project includes a generic issue filing endpoint that can be invoked through ChatGPT OpenAPI or MCP.
298
-
299
- ## Endpoint: POST /issues/create
300
-
301
- ### Purpose
302
- Create a new GitHub issue in the project repository.
303
-
304
- ### Authentication
305
- Requires Bearer token authentication.
306
-
307
- ### Request Format
308
- \`\`\`json
309
- {
310
- "title": "Issue title",
311
- "body": "Detailed description",
312
- "labels": ["bug", "high-priority"]
313
- }
314
- \`\`\`
315
-
316
- ### Response Format
317
- \`\`\`json
318
- {
319
- "success": true,
320
- "message": "Issue created successfully",
321
- "issueNumber": 123,
322
- "issueUrl": "https://github.com/owner/repo/issues/123"
323
- }
324
- \`\`\`
325
-
326
- ### Usage Examples
327
-
328
- **From ChatGPT:**
329
- - User: "I found a bug where the login doesn't work"
330
- - Assistant: Calls POST /issues/create with title and description
331
-
332
- **From MCP:**
333
- - Tool: create_issue
334
- - Parameters: title, body, labels
335
-
336
- ### Configuration
337
- The endpoint uses GitHub token from environment variables:
338
- - GITHUB_TOKEN (preferred)
339
- - GIT_TOKEN
340
- - GITHUB_PAT
341
-
342
- Repository owner and name are configured in project settings.
343
-
344
- ### Labels
345
- Common labels:
346
- - bug: Something isn't working
347
- - feature: New feature request
348
- - enhancement: Improvement to existing feature
349
- - question: Further information is requested
350
- - help wanted: Extra attention is needed
351
- `;
352
-
353
- // KB-authentication.txt
354
- const kbAuth = `# Authentication and Authorization
355
-
356
- ## Overview
357
- Most endpoints require Bearer token authentication.
358
-
359
- ## Getting a Token
360
- 1. User logs in through OAuth
361
- 2. ChatGPT automatically handles OAuth flow
362
- 3. Token is included in Authorization header
363
-
364
- ## Token Format
365
- \`Authorization: Bearer <token>\`
366
-
367
- ## Public Endpoints
368
- Some endpoints may be public (no authentication required). Check endpoint documentation.
369
-
370
- ## Error Responses
371
- - 401 Unauthorized: Token missing or invalid
372
- - 403 Forbidden: Token valid but insufficient permissions
373
- `;
374
-
375
- // KB-api-overview.txt
376
- const kbApi = `# API Overview
377
-
378
- ## Base URL
379
- ${config.api?.baseUrl || 'https://api.example.com'}
380
-
381
- ## Common Patterns
382
-
383
- ### Success Response
384
- \`\`\`json
385
- {
386
- "success": true,
387
- "message": "Operation completed",
388
- "data": {}
389
- }
390
- \`\`\`
391
-
392
- ### Error Response
393
- \`\`\`json
394
- {
395
- "success": false,
396
- "error": "Error code",
397
- "message": "Human-readable error message"
398
- }
399
- \`\`\`
400
-
401
- ## Rate Limiting
402
- Check response headers for rate limit information.
403
-
404
- ## Pagination
405
- List endpoints may support pagination:
406
- - \`limit\`: Number of items per page
407
- - \`offset\`: Number of items to skip
408
- `;
409
-
410
- writeFileSync(join(outputDir, 'KB-issues.txt'), kbIssues);
411
- writeFileSync(join(outputDir, 'KB-authentication.txt'), kbAuth);
412
- writeFileSync(join(outputDir, 'KB-api-overview.txt'), kbApi);
413
-
414
- console.log(`✅ Generated KB files in ${outputDir}`);
415
- }
416
-
417
- /**
418
- * Generate MCP server structure
419
- */
420
- export function generateMCPServer(config: any, outputDir: string): void {
421
- const mcpServerDir = join(outputDir, '..', 'src', 'mcp-server.ts');
422
- const mcpServerContent = `#!/usr/bin/env node
423
-
424
- import express from 'express';
425
- import cors from 'cors';
426
-
427
- /**
428
- * ${config.project.name} MCP Server
429
- *
430
- * MCP server that exposes project API endpoints as MCP tools.
431
- * Auto-generated by FRAIM.
432
- */
433
-
434
- class ProjectMCPServer {
435
- private app: express.Application;
436
- private apiBaseUrl: string;
437
-
438
- constructor(apiBaseUrl?: string) {
439
- this.app = express();
440
- this.app.use(cors());
441
- this.app.use(express.json());
442
-
443
- this.apiBaseUrl = apiBaseUrl || '${config.api?.baseUrl || 'http://localhost:3000'}';
444
- this.setupRoutes();
445
- }
446
-
447
- private setupRoutes() {
448
- // Health check
449
- this.app.get('/health', (req, res) => {
450
- res.json({
451
- status: 'healthy',
452
- server: 'project-mcp-server',
453
- api_url: this.apiBaseUrl
454
- });
455
- });
456
-
457
- // MCP endpoint
458
- this.app.post('/mcp', async (req, res): Promise<void> => {
459
- return this.handleMCPRequest(req, res);
460
- });
461
- }
462
-
463
- private async handleMCPRequest(req: any, res: any): Promise<void> {
464
- try {
465
- const { jsonrpc, method, params, id } = req.body;
466
-
467
- if (jsonrpc !== '2.0') {
468
- res.status(400).json({
469
- jsonrpc: '2.0',
470
- id: id || null,
471
- error: {
472
- code: -32600,
473
- message: 'Invalid Request - jsonrpc must be "2.0"'
474
- }
475
- });
476
- return;
477
- }
478
-
479
- let result;
480
-
481
- switch (method) {
482
- case 'initialize':
483
- result = this.handleInitialize(params);
484
- break;
485
-
486
- case 'tools/list':
487
- result = this.getToolsList();
488
- break;
489
-
490
- case 'tools/call':
491
- result = await this.handleToolCall(params);
492
- break;
493
-
494
- default:
495
- throw new Error(\`Unknown method: \${method}\`);
496
- }
497
-
498
- if (id !== undefined) {
499
- res.json({
500
- jsonrpc: '2.0',
501
- id,
502
- result
503
- });
504
- return;
505
- } else {
506
- res.status(202).send();
507
- return;
508
- }
509
-
510
- } catch (error) {
511
- res.json({
512
- jsonrpc: '2.0',
513
- id: req.body?.id || null,
514
- error: {
515
- code: -32603,
516
- message: error instanceof Error ? error.message : 'Internal error'
517
- }
518
- });
519
- return;
520
- }
521
- }
522
-
523
- public handleInitialize(params: any) {
524
- return {
525
- protocolVersion: '2024-11-05',
526
- capabilities: {
527
- tools: {
528
- listChanged: false
529
- },
530
- logging: {}
531
- },
532
- serverInfo: {
533
- name: 'project-mcp-server',
534
- version: '1.0.0'
535
- }
536
- };
537
- }
538
-
539
- public getToolsList() {
540
- return {
541
- tools: [
542
- {
543
- name: 'create_issue',
544
- description: 'Create a new GitHub issue in the project repository',
545
- inputSchema: {
546
- type: 'object',
547
- properties: {
548
- title: {
549
- type: 'string',
550
- description: 'Issue title'
551
- },
552
- body: {
553
- type: 'string',
554
- description: 'Issue description'
555
- },
556
- labels: {
557
- type: 'array',
558
- items: { type: 'string' },
559
- description: 'Optional labels for the issue'
560
- }
561
- },
562
- required: ['title', 'body']
563
- }
564
- }
565
- ]
566
- };
567
- }
568
-
569
- public async handleToolCall(params: any): Promise<any> {
570
- const { name: toolName, arguments: toolArgs } = params;
571
-
572
- switch (toolName) {
573
- case 'create_issue':
574
- return await this.createIssue(toolArgs);
575
-
576
- default:
577
- throw new Error(\`Unknown tool: \${toolName}\`);
578
- }
579
- }
580
-
581
- private async createIssue(args: any): Promise<any> {
582
- try {
583
- const response = await fetch(\`\${this.apiBaseUrl}/issues/create\`, {
584
- method: 'POST',
585
- headers: {
586
- 'Content-Type': 'application/json',
587
- 'Authorization': \`Bearer \${args.token || ''}\`
588
- },
589
- body: JSON.stringify({
590
- title: args.title,
591
- body: args.body,
592
- labels: args.labels || []
593
- })
594
- });
595
-
596
- const data = await response.json();
597
-
598
- if (!response.ok) {
599
- throw new Error(data.error || 'Failed to create issue');
600
- }
601
-
602
- return {
603
- content: [
604
- {
605
- type: 'text',
606
- text: \`Issue created successfully: #\${data.issueNumber}\\nURL: \${data.issueUrl}\`
607
- }
608
- ]
609
- };
610
- } catch (error) {
611
- throw new Error(\`Failed to create issue: \${error instanceof Error ? error.message : 'Unknown error'}\`);
612
- }
613
- }
614
-
615
- async start(port: number = 3001) {
616
- // Basic express app setup usually goes here or is passed in
617
- // For this generator script, we'll just log
618
- console.log(\`🚀 MCP Server running on port \${port}\`);
619
- console.log(\`📡 MCP endpoint: http://localhost:\${port}/mcp\`);
620
- }
621
- }
622
-
623
- // Start server if run directly
624
- if (import.meta.url === \`file://\${process.argv[1]}\`) {
625
- const server = new ProjectMCPServer();
626
- server.start().catch((error) => {
627
- console.error('Failed to start MCP Server:', error);
628
- process.exit(1);
629
- });
630
- }
631
-
632
- export { ProjectMCPServer };
633
- `;
634
-
635
- // Ensure directory exists
636
- const mcpDir = dirname(mcpServerDir);
637
- if (!existsSync(mcpDir)) {
638
- mkdirSync(mcpDir, { recursive: true });
639
- }
640
-
641
- writeFileSync(mcpServerDir, mcpServerContent);
642
- console.log(`✅ Generated MCP server at ${mcpServerDir} `);
643
- }
644
-
645
- /**
646
- * Main generator function
647
- */
648
- export function generateAll(config: any, outputDir: string = 'src/openapi'): void {
649
- console.log('🚀 FRAIM OpenAPI Generator\n');
650
- console.log(`📁 Output directory: ${outputDir} \n`);
651
-
652
- // Ensure output directory exists
653
- if (!existsSync(outputDir)) {
654
- mkdirSync(outputDir, { recursive: true });
655
- }
656
-
657
- // Generate OpenAPI spec
658
- console.log('📝 Generating OpenAPI specification...');
659
- const openapi = generateOpenAPI(config);
660
- const openapiPath = join(outputDir, 'openapi.json');
661
- writeFileSync(openapiPath, JSON.stringify(openapi, null, 2));
662
- console.log(`✅ Generated OpenAPI spec at ${openapiPath} `);
663
-
664
- // Generate instructions.txt
665
- console.log('\n📝 Generating instructions.txt...');
666
- const instructions = generateInstructions(config);
667
- const instructionsPath = join(outputDir, 'instructions.txt');
668
- writeFileSync(instructionsPath, instructions);
669
- console.log(`✅ Generated instructions.txt at ${instructionsPath} `);
670
- console.log(` Length: ${instructions.length} characters(limit: ${INSTRUCTIONS_LIMIT})`);
671
-
672
- // Generate KB files
673
- console.log('\n📝 Generating KB files...');
674
- generateKBFiles(config, outputDir);
675
-
676
- // Generate MCP server
677
- console.log('\n📝 Generating MCP server...');
678
- generateMCPServer(config, outputDir);
679
-
680
- console.log('\n✅ FRAIM generation complete!');
681
- console.log('\n📋 Next steps:');
682
- console.log('1. Review and customize generated files');
683
- console.log('2. Add project-specific endpoints to openapi.json');
684
- console.log('3. Update instructions.txt with project-specific details');
685
- console.log('4. Add more KB files as needed');
686
- console.log('5. Run build-time validation: npm run validate:openapi');
687
- }
688
-
689
- // Run if executed directly
690
- // Run if executed directly
691
- // @ts-ignore
692
- if (import.meta.url === `file://${process.argv[1]}`) {
693
- const config = loadFraimConfig();
694
- generateAll(config);
695
- }