fraim-framework 2.0.44 → 2.0.45

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 (72) hide show
  1. package/bin/fraim.js +1 -1
  2. package/dist/registry/ai-manager-rules/design-phases/design-completeness-review.md +73 -0
  3. package/dist/registry/ai-manager-rules/design-phases/design-design.md +145 -0
  4. package/dist/registry/ai-manager-rules/design-phases/design.md +108 -0
  5. package/dist/registry/ai-manager-rules/design-phases/finalize.md +60 -0
  6. package/dist/registry/ai-manager-rules/design-phases/validate.md +125 -0
  7. package/dist/registry/ai-manager-rules/implement-phases/code.md +323 -0
  8. package/dist/registry/ai-manager-rules/implement-phases/completeness-review.md +94 -0
  9. package/dist/registry/ai-manager-rules/implement-phases/finalize.md +177 -0
  10. package/dist/registry/ai-manager-rules/implement-phases/implement-code.md +286 -0
  11. package/dist/registry/ai-manager-rules/implement-phases/implement-completeness-review.md +120 -0
  12. package/dist/registry/ai-manager-rules/implement-phases/implement-regression.md +173 -0
  13. package/dist/registry/ai-manager-rules/implement-phases/implement-repro.md +104 -0
  14. package/dist/registry/ai-manager-rules/implement-phases/implement-scoping.md +100 -0
  15. package/dist/registry/ai-manager-rules/implement-phases/implement-smoke.md +230 -0
  16. package/dist/registry/ai-manager-rules/implement-phases/implement-spike.md +121 -0
  17. package/dist/registry/ai-manager-rules/implement-phases/implement-validate.md +371 -0
  18. package/dist/registry/ai-manager-rules/implement-phases/quality-review.md +304 -0
  19. package/dist/registry/ai-manager-rules/implement-phases/regression.md +159 -0
  20. package/dist/registry/ai-manager-rules/implement-phases/repro.md +101 -0
  21. package/dist/registry/ai-manager-rules/implement-phases/scoping.md +93 -0
  22. package/dist/registry/ai-manager-rules/implement-phases/smoke.md +225 -0
  23. package/dist/registry/ai-manager-rules/implement-phases/spike.md +118 -0
  24. package/dist/registry/ai-manager-rules/implement-phases/validate.md +347 -0
  25. package/dist/registry/ai-manager-rules/shared-phases/finalize.md +169 -0
  26. package/dist/registry/ai-manager-rules/shared-phases/submit-pr.md +202 -0
  27. package/dist/registry/ai-manager-rules/shared-phases/wait-for-pr-review.md +170 -0
  28. package/dist/registry/ai-manager-rules/spec-phases/finalize.md +60 -0
  29. package/dist/registry/ai-manager-rules/spec-phases/spec-completeness-review.md +66 -0
  30. package/dist/registry/ai-manager-rules/spec-phases/spec-spec.md +139 -0
  31. package/dist/registry/ai-manager-rules/spec-phases/spec.md +102 -0
  32. package/dist/registry/ai-manager-rules/spec-phases/validate.md +118 -0
  33. package/dist/src/ai-manager/ai-manager.js +380 -119
  34. package/dist/src/ai-manager/evidence-validator.js +309 -0
  35. package/dist/src/ai-manager/phase-flow.js +244 -0
  36. package/dist/src/ai-manager/types.js +5 -0
  37. package/dist/src/fraim-mcp-server.js +45 -153
  38. package/dist/src/static-website-middleware.js +75 -0
  39. package/dist/tests/test-ai-coach-edge-cases.js +415 -0
  40. package/dist/tests/test-ai-coach-mcp-integration.js +432 -0
  41. package/dist/tests/test-ai-coach-performance.js +328 -0
  42. package/dist/tests/test-ai-coach-phase-content.js +264 -0
  43. package/dist/tests/test-ai-coach-workflows.js +487 -0
  44. package/dist/tests/test-ai-manager-phase-protocol.js +147 -0
  45. package/dist/tests/test-ai-manager.js +60 -71
  46. package/dist/tests/test-evidence-validation.js +221 -0
  47. package/dist/tests/test-mcp-lifecycle-methods.js +18 -23
  48. package/dist/tests/test-pr-review-integration.js +1 -0
  49. package/dist/tests/test-pr-review-workflow.js +299 -0
  50. package/dist/website/.nojekyll +0 -0
  51. package/dist/website/404.html +101 -0
  52. package/dist/website/CNAME +1 -0
  53. package/dist/website/README.md +22 -0
  54. package/dist/website/demo.html +604 -0
  55. package/dist/website/images/.gitkeep +1 -0
  56. package/dist/website/images/fraim-logo.png +0 -0
  57. package/dist/website/index.html +290 -0
  58. package/dist/website/pricing.html +414 -0
  59. package/dist/website/script.js +55 -0
  60. package/dist/website/styles.css +2647 -0
  61. package/package.json +2 -1
  62. package/registry/agent-guardrails.md +1 -1
  63. package/registry/stubs/workflows/brainstorming/blue-sky-brainstorming.md +11 -0
  64. package/registry/stubs/workflows/brainstorming/codebase-brainstorming.md +11 -0
  65. package/registry/stubs/workflows/compliance/detect-compliance-requirements.md +11 -0
  66. package/registry/stubs/workflows/compliance/generate-audit-evidence.md +11 -0
  67. package/registry/stubs/workflows/learning/synthesize-learnings.md +11 -0
  68. package/registry/stubs/workflows/legal/nda.md +11 -0
  69. package/registry/stubs/workflows/legal/patent-filing.md +11 -0
  70. package/registry/stubs/workflows/legal/trademark-filing.md +11 -0
  71. package/registry/stubs/workflows/product-building/design.md +1 -1
  72. package/registry/stubs/workflows/product-building/implement.md +1 -2
@@ -170,7 +170,6 @@ class FraimMCPServer {
170
170
  // Initialize database service
171
171
  this.dbService = new db_service_1.FraimDbService();
172
172
  this.sessionManager = new SessionManager(this.dbService);
173
- this.aiManager = new ai_manager_1.AIManager();
174
173
  // Load FRAIM configuration
175
174
  this.config = (0, config_loader_1.loadFraimConfig)();
176
175
  // Find registry directory (check dist first for production, then source)
@@ -178,6 +177,8 @@ class FraimMCPServer {
178
177
  // Build file index from filesystem (includes registry and .fraim)
179
178
  this.buildFileIndex();
180
179
  this.buildWorkflowKeywords();
180
+ // Initialize AI Coach with file index
181
+ this.aiCoach = new ai_manager_1.AICoach(this.fileIndex);
181
182
  // Apply core middleware first (logging and auth)
182
183
  this.app.use(this.requestLogger.bind(this));
183
184
  this.app.use(this.versionCheck.bind(this));
@@ -282,6 +283,10 @@ class FraimMCPServer {
282
283
  if (req.path === '/health' || req.path.startsWith('/admin')) {
283
284
  return next();
284
285
  }
286
+ // Skip auth in test mode
287
+ if (process.env.NODE_ENV === 'test') {
288
+ return next();
289
+ }
285
290
  const apiKey = req.headers['x-api-key'] || req.query['api-key'];
286
291
  if (!apiKey) {
287
292
  console.error(`[FRAIM AUTH] Missing API key for ${req.method} ${req.path}`);
@@ -983,95 +988,55 @@ Supports dry-run mode to preview the operation.`,
983
988
  }
984
989
  },
985
990
  {
986
- name: 'ai_manager_request_review',
987
- description: `Request self-review instructions from AI Manager after completing workflow phase.
991
+ name: 'seekCoachingOnNextStep',
992
+ description: `Get coaching on what to do next in your implementation workflow.
988
993
 
989
- The AI Manager provides detailed review instructions including:
990
- - Step-by-step validation criteria
991
- - Pass/fail criteria for each step
992
- - Commands to run for verification
993
- - Grading guidelines and reporting format
994
+ The AI Coach provides phase-specific instructions based on your current progress:
995
+ - If starting: Get initial phase instructions (usually scoping)
996
+ - If completed phase: Provide evidence for validation, get next phase instructions
997
+ - If stuck/incomplete: Get guidance to continue current phase
994
998
 
995
- Use this when you believe your work is complete and ready for review.
996
- Currently supports: spec, implement phases (more phases coming soon).`,
999
+ This is your single point of contact for workflow guidance with evidence validation.`,
997
1000
  inputSchema: {
998
1001
  type: 'object',
999
1002
  properties: {
1000
1003
  workflowType: {
1001
1004
  type: 'string',
1002
- description: 'Type of workflow phase completed',
1003
- enum: ['spec', 'design', 'implement', 'test']
1005
+ description: 'Type of workflow you are following',
1006
+ enum: ['implement', 'spec', 'design', 'test']
1004
1007
  },
1005
1008
  issueNumber: {
1006
1009
  type: 'string',
1007
- description: 'Issue number being worked on'
1008
- },
1009
- phase: {
1010
- type: 'string',
1011
- description: 'Specific phase name (e.g., "specification", "implementation")'
1012
- }
1013
- },
1014
- required: ['workflowType', 'issueNumber', 'phase']
1015
- }
1016
- },
1017
- {
1018
- name: 'ai_manager_report_grade',
1019
- description: `Report your self-assessment to AI Manager after completing self-review.
1020
-
1021
- Provide results from review in JSON format:
1022
- - pass: true/false based on review assessment
1023
- - reasons: array of failure reasons (only if pass=false)
1024
- - iterationCount: REQUIRED - your current iteration number for this phase
1025
-
1026
- AI Manager will evaluate your report and provide next steps:
1027
- - PROCEED: Ready to submit PR for human review
1028
- - ITERATE: Fix issues and retry (max 3 iterations)
1029
- - ESCALATE: Max iterations reached, escalate to human review
1030
-
1031
- IMPORTANT: Track your iteration count per workflow phase. Each phase (spec, implement, test) has its own counter.
1032
- Maximum 3 iterations per phase before automatic escalation to human review.`,
1033
- inputSchema: {
1034
- type: 'object',
1035
- properties: {
1036
- workflowType: {
1037
- type: 'string',
1038
- description: 'Type of workflow phase',
1039
- enum: ['spec', 'design', 'implement', 'test']
1010
+ description: 'Issue number you are working on'
1040
1011
  },
1041
- issueNumber: {
1012
+ currentPhase: {
1042
1013
  type: 'string',
1043
- description: 'Issue number being worked on'
1014
+ description: 'Phase you just completed or are working on (e.g., "scoping", "repro", "code")'
1044
1015
  },
1045
- phase: {
1016
+ status: {
1046
1017
  type: 'string',
1047
- description: 'Specific phase name'
1018
+ description: 'Status of your current phase',
1019
+ enum: ['starting', 'complete', 'incomplete', 'failure']
1048
1020
  },
1049
- report: {
1021
+ findings: {
1050
1022
  type: 'object',
1051
- description: 'Your self-assessment report in JSON format',
1023
+ description: 'Your findings/results from the current phase (varies by phase)',
1052
1024
  properties: {
1053
- pass: {
1054
- type: 'boolean',
1055
- description: 'Whether your work passes all validation criteria'
1056
- },
1057
- reasons: {
1025
+ uncertainties: {
1058
1026
  type: 'array',
1059
- description: 'Array of specific reasons for failure (only required if pass=false)',
1060
- items: {
1061
- type: 'string'
1062
- }
1063
- },
1064
- iterationCount: {
1065
- type: 'number',
1066
- description: 'REQUIRED: Your current iteration number for this workflow phase (1, 2, or 3)',
1067
- minimum: 1,
1068
- maximum: 3
1027
+ items: { type: 'string' },
1028
+ description: 'Any unclear aspects that need clarification (used for help messages)'
1069
1029
  }
1070
1030
  },
1071
- required: ['pass', 'iterationCount']
1031
+ additionalProperties: true
1032
+ },
1033
+ evidence: {
1034
+ type: 'object',
1035
+ description: 'Evidence submission for validation (varies by phase - can contain any relevant evidence)',
1036
+ additionalProperties: true
1072
1037
  }
1073
1038
  },
1074
- required: ['workflowType', 'issueNumber', 'phase', 'report']
1039
+ required: ['workflowType', 'issueNumber', 'currentPhase', 'status']
1075
1040
  }
1076
1041
  }
1077
1042
  ]
@@ -1110,10 +1075,8 @@ Maximum 3 iterations per phase before automatic escalation to human review.`,
1110
1075
  };
1111
1076
  case 'fraim_connect':
1112
1077
  return await this.handleFraimConnect(toolArgs, context.apiKey, context.userId);
1113
- case 'ai_manager_request_review':
1114
- return await this.handleAIManagerRequestReview(toolArgs);
1115
- case 'ai_manager_report_grade':
1116
- return await this.handleAIManagerReportGrade(toolArgs);
1078
+ case 'seekCoachingOnNextStep':
1079
+ return await this.handleSeekCoachingOnNextStep(toolArgs);
1117
1080
  default:
1118
1081
  throw new Error(`Unknown tool: ${toolName} `);
1119
1082
  }
@@ -1548,102 +1511,31 @@ If \`.fraim/config.json\` doesn't exist:
1548
1511
  sessionId: sessionId
1549
1512
  };
1550
1513
  }
1551
- async handleAIManagerRequestReview(args) {
1552
- try {
1553
- console.log(`🤖 AI Manager: Generating review instructions for ${args.workflowType} phase`);
1554
- const instructions = this.aiManager.generateReviewInstructions({
1555
- workflowType: args.workflowType,
1556
- issueNumber: args.issueNumber,
1557
- phase: args.phase
1558
- });
1559
- return {
1560
- content: [{
1561
- type: 'text',
1562
- text: instructions
1563
- }]
1564
- };
1565
- }
1566
- catch (error) {
1567
- console.error('❌ AI Manager request review failed:', error);
1568
- return {
1569
- content: [{
1570
- type: 'text',
1571
- text: `# ❌ AI Manager Request Failed\n\n**Error**: ${error instanceof Error ? error.message : 'Unknown error'}\n\nPlease check your request parameters and try again.`
1572
- }],
1573
- error: error instanceof Error ? error.message : 'Unknown error'
1574
- };
1575
- }
1576
- }
1577
- async handleAIManagerReportGrade(args) {
1514
+ async handleSeekCoachingOnNextStep(args) {
1578
1515
  try {
1579
- console.log(`🤖 AI Manager: Evaluating review report for ${args.workflowType} phase`);
1580
- const decision = this.aiManager.evaluateReport(args.report, {
1516
+ const response = await this.aiCoach.handleCoachingRequest({
1581
1517
  workflowType: args.workflowType,
1582
1518
  issueNumber: args.issueNumber,
1583
- phase: args.phase
1584
- });
1585
- // Format response for agent
1586
- let response = `# 🤖 AI Manager Evaluation Result\n\n`;
1587
- const actionEmoji = decision.action === 'PROCEED' ? '✅' :
1588
- decision.action === 'ESCALATE' ? '⚠️' : '🔄';
1589
- response += `## Decision: ${actionEmoji} ${decision.action}\n\n`;
1590
- response += `**Message**: ${decision.message}\n\n`;
1591
- if (decision.iterationCount) {
1592
- response += `**Iteration Count**: ${decision.iterationCount}/3\n\n`;
1593
- }
1594
- response += `## Next Steps\n\n`;
1595
- decision.nextSteps.forEach((step, index) => {
1596
- response += `${index + 1}. ${step}\n`;
1519
+ currentPhase: args.currentPhase,
1520
+ status: args.status,
1521
+ evidence: args.evidence,
1522
+ findings: args.findings
1597
1523
  });
1598
- response += `\n`;
1599
- if (decision.action === 'PROCEED') {
1600
- response += `## 🎉 Ready for Human Review!\n\n`;
1601
- response += `Your work has passed AI Manager validation. You should now:\n\n`;
1602
- response += `1. **Submit PR** with complete evidence document\n`;
1603
- response += `2. **Update issue labels** to status:needs-review\n`;
1604
- response += `3. **Include this AI Manager validation** in your evidence\n\n`;
1605
- }
1606
- else if (decision.action === 'ESCALATE') {
1607
- response += `## ⚠️ Escalated to Human Review\n\n`;
1608
- response += `Maximum iterations reached. Your work will be reviewed by a human despite validation failures:\n\n`;
1609
- response += `1. **Submit PR** with detailed iteration history\n`;
1610
- response += `2. **Add escalation label** (ai-manager:max-iterations)\n`;
1611
- response += `3. **Document all attempts** and failure reasons in evidence\n`;
1612
- response += `4. **Human reviewer** will focus on recurring validation issues\n\n`;
1613
- }
1614
- else {
1615
- response += `## 🔧 Work Required\n\n`;
1616
- response += `Your work needs improvement. You should:\n\n`;
1617
- response += `1. **Address all failure reasons** listed below\n`;
1618
- response += `2. **Re-run validation steps** to verify fixes\n`;
1619
- response += `3. **Request new review** using ai_manager_request_review\n`;
1620
- response += `4. **Include iterationCount: ${(decision.iterationCount || 1) + 1}** in next report\n`;
1621
- response += `5. **Do NOT submit PR** until review passes or escalates\n\n`;
1622
- }
1623
- response += `## Your Report Summary\n\n`;
1624
- response += `**Pass**: ${args.report.pass}\n`;
1625
- response += `**Iteration**: ${args.report.iterationCount || 1}/3\n`;
1626
- if (args.report.reasons && args.report.reasons.length > 0) {
1627
- response += `**Failure Reasons**:\n`;
1628
- args.report.reasons.forEach((reason) => {
1629
- response += `- ${reason}\n`;
1630
- });
1631
- }
1632
1524
  return {
1633
1525
  content: [{
1634
1526
  type: 'text',
1635
1527
  text: response
1636
- }],
1637
- decision: decision
1528
+ }]
1638
1529
  };
1639
1530
  }
1640
1531
  catch (error) {
1641
- console.error('❌ AI Manager report evaluation failed:', error);
1532
+ console.error('❌ AI Coach guidance failed:', error);
1642
1533
  return {
1643
1534
  content: [{
1644
1535
  type: 'text',
1645
- text: `# ❌ AI Manager Evaluation Failed\n\n**Error**: ${error instanceof Error ? error.message : 'Unknown error'}\n\nPlease check your report format and try again.`
1536
+ text: `# ❌ AI Coach Guidance Failed\n\n**Error**: ${error instanceof Error ? error.message : 'Unknown error'}\n\nPlease check your request parameters and try again.`
1646
1537
  }],
1538
+ isError: true,
1647
1539
  error: error instanceof Error ? error.message : 'Unknown error'
1648
1540
  };
1649
1541
  }
@@ -0,0 +1,75 @@
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.createStaticWebsiteMiddleware = createStaticWebsiteMiddleware;
7
+ const express_1 = __importDefault(require("express"));
8
+ const path_1 = require("path");
9
+ const fs_1 = require("fs");
10
+ /**
11
+ * Middleware to serve the FRAIM website at /fraim endpoint
12
+ * This serves the static website files from the website directory
13
+ */
14
+ function createStaticWebsiteMiddleware() {
15
+ const router = express_1.default.Router();
16
+ // Find the website directory
17
+ const websitePath = findWebsitePath();
18
+ if (!websitePath) {
19
+ console.warn('⚠️ Website directory not found. FRAIM website will not be available at /fraim');
20
+ return router;
21
+ }
22
+ console.log(`🌐 Serving FRAIM website from: ${websitePath}`);
23
+ // Serve static files from website directory at /fraim endpoint only
24
+ router.use('/fraim', express_1.default.static(websitePath, {
25
+ index: 'index.html',
26
+ setHeaders: (res, path) => {
27
+ // Set proper MIME types
28
+ if (path.endsWith('.css')) {
29
+ res.setHeader('Content-Type', 'text/css');
30
+ }
31
+ else if (path.endsWith('.js')) {
32
+ res.setHeader('Content-Type', 'application/javascript');
33
+ }
34
+ else if (path.endsWith('.png')) {
35
+ res.setHeader('Content-Type', 'image/png');
36
+ }
37
+ else if (path.endsWith('.jpg') || path.endsWith('.jpeg')) {
38
+ res.setHeader('Content-Type', 'image/jpeg');
39
+ }
40
+ else if (path.endsWith('.svg')) {
41
+ res.setHeader('Content-Type', 'image/svg+xml');
42
+ }
43
+ // Cache static assets for 1 hour
44
+ if (path.match(/\.(css|js|png|jpg|jpeg|svg|ico)$/)) {
45
+ res.setHeader('Cache-Control', 'public, max-age=3600');
46
+ }
47
+ }
48
+ }));
49
+ return router;
50
+ }
51
+ /**
52
+ * Find the website directory
53
+ * Checks multiple possible locations
54
+ */
55
+ function findWebsitePath() {
56
+ const possiblePaths = [
57
+ // Production: dist/website
58
+ (0, path_1.join)(process.cwd(), 'dist', 'website'),
59
+ // Development: website
60
+ (0, path_1.join)(process.cwd(), 'website'),
61
+ // Relative to server file: ../website
62
+ (0, path_1.join)(__dirname, '..', 'website'),
63
+ // Relative to server file: ../../website
64
+ (0, path_1.join)(__dirname, '..', '..', 'website')
65
+ ];
66
+ for (const path of possiblePaths) {
67
+ if ((0, fs_1.existsSync)(path)) {
68
+ const indexPath = (0, path_1.join)(path, 'index.html');
69
+ if ((0, fs_1.existsSync)(indexPath)) {
70
+ return path;
71
+ }
72
+ }
73
+ }
74
+ return null;
75
+ }