fraim-framework 2.0.35 → 2.0.36

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 (51) hide show
  1. package/bin/fraim.js +52 -5
  2. package/dist/registry/scripts/cleanup-branch.js +62 -33
  3. package/dist/registry/scripts/generate-engagement-emails.js +119 -44
  4. package/dist/registry/scripts/newsletter-helpers.js +208 -268
  5. package/dist/registry/scripts/profile-server.js +387 -0
  6. package/dist/tests/test-chalk-regression.js +18 -2
  7. package/dist/tests/test-client-scripts-validation.js +133 -0
  8. package/dist/tests/test-prep-issue.js +1 -34
  9. package/dist/tests/test-script-location-independence.js +76 -28
  10. package/package.json +2 -2
  11. package/registry/agent-guardrails.md +62 -62
  12. package/registry/rules/communication.md +121 -121
  13. package/registry/rules/continuous-learning.md +54 -54
  14. package/registry/rules/hitl-ppe-record-analysis.md +302 -302
  15. package/registry/rules/software-development-lifecycle.md +104 -104
  16. package/registry/scripts/cleanup-branch.ts +341 -0
  17. package/registry/scripts/code-quality-check.sh +559 -559
  18. package/registry/scripts/detect-tautological-tests.sh +38 -38
  19. package/registry/scripts/generate-engagement-emails.ts +830 -0
  20. package/registry/scripts/markdown-to-pdf.js +7 -3
  21. package/registry/scripts/newsletter-helpers.ts +777 -0
  22. package/registry/scripts/prep-issue.sh +30 -61
  23. package/registry/scripts/profile-server.ts +424 -0
  24. package/registry/scripts/run-thank-you-workflow.ts +122 -0
  25. package/registry/scripts/send-newsletter-simple.ts +102 -0
  26. package/registry/scripts/send-thank-you-emails.ts +57 -0
  27. package/registry/scripts/validate-openapi-limits.ts +366 -366
  28. package/registry/scripts/validate-test-coverage.ts +280 -280
  29. package/registry/scripts/verify-pr-comments.sh +70 -70
  30. package/registry/templates/bootstrap/ARCHITECTURE-TEMPLATE.md +53 -53
  31. package/registry/templates/evidence/Implementation-BugEvidence.md +85 -85
  32. package/registry/templates/evidence/Implementation-FeatureEvidence.md +120 -120
  33. package/registry/workflows/customer-development/insight-analysis.md +156 -156
  34. package/registry/workflows/customer-development/interview-preparation.md +421 -421
  35. package/registry/workflows/customer-development/strategic-brainstorming.md +146 -146
  36. package/registry/workflows/quality-assurance/iterative-improvement-cycle.md +562 -562
  37. package/registry/workflows/reviewer/review-implementation-vs-feature-spec.md +669 -669
  38. package/dist/registry/scripts/build-scripts-generator.js +0 -205
  39. package/dist/registry/scripts/fraim-config.js +0 -61
  40. package/dist/registry/scripts/generic-issues-api.js +0 -100
  41. package/dist/registry/scripts/openapi-generator.js +0 -664
  42. package/dist/registry/scripts/performance/profile-server.js +0 -390
  43. package/dist/test-utils.js +0 -96
  44. package/dist/tests/esm-compat.js +0 -11
  45. package/dist/tests/test-chalk-esm-issue.js +0 -159
  46. package/dist/tests/test-chalk-real-world.js +0 -265
  47. package/dist/tests/test-chalk-resolution-issue.js +0 -304
  48. package/dist/tests/test-fraim-install-chalk-issue.js +0 -254
  49. package/dist/tests/test-npm-resolution-diagnostic.js +0 -140
  50. package/registry/templates/marketing/STORYTELLING-TEMPLATE.md +0 -130
  51. package/registry/workflows/marketing/storytelling.md +0 -65
@@ -1,205 +0,0 @@
1
- #!/usr/bin/env node
2
- "use strict";
3
- /**
4
- * FRAIM Build Scripts Generator
5
- *
6
- * Generates generic build scripts and validation patterns.
7
- * These are generic enough to apply to any project.
8
- *
9
- * Usage:
10
- * npx tsx scripts/build-scripts-generator.ts
11
- */
12
- Object.defineProperty(exports, "__esModule", { value: true });
13
- exports.generatePackageScripts = generatePackageScripts;
14
- exports.generateCodeQualityScript = generateCodeQualityScript;
15
- exports.generateCopyScripts = generateCopyScripts;
16
- exports.generateBuildScripts = generateBuildScripts;
17
- const fs_1 = require("fs");
18
- const path_1 = require("path");
19
- const config_loader_js_1 = require("../../src/fraim/config-loader.js");
20
- /**
21
- * Generate package.json scripts section
22
- */
23
- function generatePackageScripts(config) {
24
- return {
25
- "build": "tsc && npm run validate:openapi",
26
- "validate:openapi": "npx tsx " + "reg" + "istry/scripts/validate-openapi-limits.ts",
27
- "start": "node dist/src/server.js",
28
- "start:mcp": "node dist/src/mcp-server.js",
29
- "dev": "npx tsx --watch src/server.ts",
30
- "dev:mcp": "tsx src/mcp-server.ts",
31
- "generate:openapi": "npx tsx " + "reg" + "istry/scripts/openapi-generator.ts",
32
- "test": "npx tsx --test test*.ts",
33
- "lint": "eslint *.ts",
34
- "lint:fix": "eslint *.ts --fix"
35
- };
36
- }
37
- /**
38
- * Generate code quality check script (generic version)
39
- */
40
- function generateCodeQualityScript(outputDir) {
41
- if (!(0, fs_1.existsSync)(outputDir)) {
42
- (0, fs_1.mkdirSync)(outputDir, { recursive: true });
43
- }
44
- const scriptContent = `#!/bin/bash
45
-
46
- # FRAIM Generic Code Quality Check
47
- # Validates code quality, build, and ChatGPT limits
48
-
49
- set -e
50
-
51
- MODE=\${1:-full}
52
- FAILED=0
53
- WARNINGS=0
54
-
55
- echo "================================================"
56
- echo "🔍 CODE QUALITY CHECK ($MODE mode)"
57
- echo "================================================"
58
- echo ""
59
-
60
- # Build check
61
- if [ "$MODE" = "full" ] || [ "$MODE" = "build" ]; then
62
- echo "📦 Building project..."
63
- if npm run build; then
64
- echo "✅ Build passed"
65
- else
66
- echo "❌ Build failed"
67
- FAILED=1
68
- fi
69
- echo ""
70
- fi
71
-
72
- # Lint check
73
- if [ "$MODE" = "full" ] || [ "$MODE" = "lint" ]; then
74
- echo "🔍 Linting code..."
75
- if npm run lint; then
76
- echo "✅ Lint passed"
77
- else
78
- echo "⚠️ Lint warnings (non-blocking)"
79
- WARNINGS=1
80
- fi
81
- echo ""
82
- fi
83
-
84
- # OpenAPI validation (ChatGPT limits)
85
- if [ "$MODE" = "full" ] || [ "$MODE" = "openapi" ]; then
86
- echo "📋 Validating OpenAPI and ChatGPT limits..."
87
- if npm run validate:openapi; then
88
- echo "✅ OpenAPI validation passed"
89
- else
90
- echo "❌ OpenAPI validation failed"
91
- FAILED=1
92
- fi
93
- echo ""
94
- fi
95
-
96
- # Summary
97
- echo "================================================"
98
- echo "📊 QUALITY CHECK SUMMARY ($MODE mode)"
99
- echo "================================================"
100
- echo ""
101
-
102
- if [ $FAILED -eq 1 ]; then
103
- echo "❌ CHECKS FAILED"
104
- echo ""
105
- echo "Fix the errors above before proceeding."
106
- exit 1
107
- elif [ $WARNINGS -eq 1 ]; then
108
- echo "⚠️ CHECKS PASSED WITH WARNINGS"
109
- echo ""
110
- echo "Review warnings above."
111
- exit 0
112
- else
113
- echo "✅ ALL CHECKS PASSED"
114
- echo ""
115
- exit 0
116
- fi
117
- `;
118
- const scriptPath = (0, path_1.join)(outputDir, 'code-quality-check.sh');
119
- (0, fs_1.writeFileSync)(scriptPath, scriptContent);
120
- // Make executable (Unix)
121
- if (process.platform !== 'win32') {
122
- const { execSync } = require('child_process');
123
- execSync(`chmod +x ${scriptPath}`);
124
- }
125
- console.log(`✅ Generated code quality check script at ${scriptPath}`);
126
- }
127
- /**
128
- * Generate build copy scripts (generic)
129
- */
130
- function generateCopyScripts(outputDir) {
131
- if (!(0, fs_1.existsSync)(outputDir)) {
132
- (0, fs_1.mkdirSync)(outputDir, { recursive: true });
133
- }
134
- // Copy AI agents script (if .fraim exists)
135
- const copyAiAgents = `#!/usr/bin/env node
136
-
137
- /**
138
- * Copy registry directory to dist
139
- * Generic build script for FRAIM projects
140
- */
141
-
142
- const fs = require('fs');
143
- const path = require('path');
144
-
145
- const sourceDir = path.join(__dirname, '..', '..', 'registry');
146
- const destDir = path.join(__dirname, '..', '..', 'dist', 'registry');
147
-
148
- if (fs.existsSync(sourceDir)) {
149
- // Recursive copy
150
- function copyRecursive(src, dest) {
151
- if (!fs.existsSync(dest)) {
152
- fs.mkdirSync(dest, { recursive: true });
153
- }
154
-
155
- const entries = fs.readdirSync(src, { withFileTypes: true });
156
-
157
- for (const entry of entries) {
158
- const srcPath = path.join(src, entry.name);
159
- const destPath = path.join(dest, entry.name);
160
-
161
- if (entry.isDirectory()) {
162
- copyRecursive(srcPath, destPath);
163
- } else {
164
- fs.copyFileSync(srcPath, destPath);
165
- }
166
- }
167
- }
168
-
169
- copyRecursive(sourceDir, destDir);
170
- console.log('✅ Copied registry to dist/registry');
171
- } else {
172
- console.log('ℹ️ registry directory not found, skipping');
173
- }
174
- `;
175
- (0, fs_1.writeFileSync)((0, path_1.join)(outputDir, 'copy-ai-agents.js'), copyAiAgents);
176
- console.log(`✅ Generated copy-ai-agents.js`);
177
- }
178
- /**
179
- * Main generator function
180
- */
181
- function generateBuildScripts(config, outputDir = "scr" + "ipts/build") {
182
- console.log('🚀 FRAIM Build Scripts Generator\n');
183
- console.log(`📁 Output directory: ${outputDir}\n`);
184
- // Ensure output directory exists
185
- if (!(0, fs_1.existsSync)(outputDir)) {
186
- (0, fs_1.mkdirSync)(outputDir, { recursive: true });
187
- }
188
- // Generate code quality check
189
- console.log('📝 Generating code quality check script...');
190
- generateCodeQualityScript(outputDir);
191
- // Generate build scripts
192
- console.log('\n📝 Generating build scripts...');
193
- generateCopyScripts(outputDir);
194
- console.log('\n✅ Build scripts generation complete!');
195
- console.log('\n📋 Next steps:');
196
- console.log('1. Add scripts to package.json');
197
- console.log('2. Run: npm run validate:openapi');
198
- console.log('3. Run: ./scripts/build/code-quality-check.sh');
199
- }
200
- // Run if executed directly
201
- // @ts-ignore
202
- if (import.meta.url === `file://${process.argv[1]}`) {
203
- const config = (0, config_loader_js_1.loadFraimConfig)();
204
- generateBuildScripts(config);
205
- }
@@ -1,61 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.fraimConfig = void 0;
4
- exports.formatExecutiveDisplayName = formatExecutiveDisplayName;
5
- exports.formatPersonaSignature = formatPersonaSignature;
6
- const config_loader_1 = require("../../src/fraim/config-loader");
7
- const config = (0, config_loader_1.loadFraimConfig)();
8
- const envOr = (keys, fallback) => {
9
- for (const key of keys) {
10
- const value = process.env[key];
11
- if (value && value.length) {
12
- return value;
13
- }
14
- }
15
- return fallback;
16
- };
17
- const personaName = config.persona.name;
18
- const personaDisplayNameDefault = config.persona.displayNamePattern.replace('{executiveName}', 'Your');
19
- exports.fraimConfig = {
20
- repoOwner: config.git.repoOwner || 'mathursrus',
21
- repoName: config.git.repoName || 'fraim-repo',
22
- projectName: config.project.name,
23
- personaName,
24
- personaPronouns: envOr(['FRAIM_PERSONA_PRONOUNS'], 'they/them'), // Could add to config if needed
25
- personaDisplayName: envOr(['FRAIM_PERSONA_DISPLAY_NAME'], personaDisplayNameDefault),
26
- personaDisplayNamePattern: config.persona.displayNamePattern,
27
- personaThankYouSignature: config.persona.emailSignature,
28
- defaultEmail: envOr(['FRAIM_DEFAULT_EMAIL'], 'agent@example.com'),
29
- prodDefaultEmail: envOr(['PROD_FRAIM_DEFAULT_EMAIL'], 'agent@example.com'),
30
- defaultAccessToken: envOr(['FRAIM_DEFAULT_ACCESS_TOKEN'], ''),
31
- defaultRefreshToken: envOr(['FRAIM_DEFAULT_REFRESH_TOKEN'], ''),
32
- prodAccessToken: envOr(['PROD_FRAIM_DEFAULT_ACCESS_TOKEN'], ''),
33
- prodRefreshToken: envOr(['PROD_FRAIM_DEFAULT_REFRESH_TOKEN'], ''),
34
- defaultOAuthClientId: envOr(['FRAIM_DEFAULT_OAUTH_CLIENT_ID'], ''),
35
- defaultOAuthClientSecret: envOr(['FRAIM_DEFAULT_OAUTH_CLIENT_SECRET'], ''),
36
- prodOAuthClientId: envOr(['PROD_FRAIM_DEFAULT_OAUTH_CLIENT_ID'], ''),
37
- prodOAuthClientSecret: envOr(['PROD_FRAIM_DEFAULT_OAUTH_CLIENT_SECRET'], ''),
38
- identityCollection: config.database?.identityCollection || 'Identity',
39
- executiveCollection: config.database?.executiveCollection || 'Executive',
40
- newsletterTitle: config.marketing?.newsletterTitle || 'Weekly Update',
41
- newsletterCtaText: config.marketing?.newsletterCtaText || 'Learn More',
42
- newsletterUrl: config.marketing?.newsletterUrl || envOr(['FRAIM_NEWSLETTER_URL'], ''),
43
- issueRepoUrl: config.git.url || `https://github.com/${config.git.repoOwner}/${config.git.repoName}.git`,
44
- identityTokensCollection: config.database?.tokensCollection || 'Tokens',
45
- webAppUrl: config.marketing?.websiteUrl || envOr(['FRAIM_WEB_APP_URL'], 'http://localhost:3000'),
46
- chatUrl: config.marketing?.chatUrl || envOr(['FRAIM_CHAT_URL'], ''),
47
- azure: {
48
- prodAppName: envOr(['FRAIM_AZURE_PROD_APP_NAME'], 'fraim-app-prod'),
49
- prodResourceGroup: envOr(['FRAIM_AZURE_PROD_RESOURCE_GROUP'], 'fraim-prod-rg'),
50
- preprodAppName: envOr(['FRAIM_AZURE_PREPROD_APP_NAME'], 'fraim-app-pre-prod'),
51
- preprodResourceGroup: envOr(['FRAIM_AZURE_PREPROD_RESOURCE_GROUP'], 'fraim-pre-prod-rg'),
52
- localAppName: envOr(['FRAIM_AZURE_LOCAL_APP_NAME'], 'local'),
53
- localResourceGroup: envOr(['FRAIM_AZURE_LOCAL_RESOURCE_GROUP'], 'local')
54
- }
55
- };
56
- function formatExecutiveDisplayName(executiveName) {
57
- return config.persona.displayNamePattern.replace('{executiveName}', executiveName);
58
- }
59
- function formatPersonaSignature() {
60
- return `With gratitude,\n${exports.fraimConfig.personaThankYouSignature}\n${personaName} - Your AI Executive Assistant\n\n`;
61
- }
@@ -1,100 +0,0 @@
1
- "use strict";
2
- /**
3
- * FRAIM Generic Issues API
4
- *
5
- * Generic issue filing endpoint that works for any project.
6
- * Can be invoked through ChatGPT OpenAPI or MCP.
7
- *
8
- * Usage:
9
- * 1. Import this file
10
- * 2. Mount the router in your Express app
11
- * 3. Configure GitHub repository in .fraim/config.json
12
- */
13
- Object.defineProperty(exports, "__esModule", { value: true });
14
- exports.issuesRouter = void 0;
15
- const express_1 = require("express");
16
- const issues_js_1 = require("../../src/fraim/issues.js");
17
- const config_loader_js_1 = require("../../src/fraim/config-loader.js");
18
- const issuesRouter = (0, express_1.Router)();
19
- exports.issuesRouter = issuesRouter;
20
- /**
21
- * POST /issues/create - Create a GitHub issue
22
- *
23
- * Generic endpoint that works for any FRAIM project.
24
- * Repository owner and name are read from .fraim/config.json
25
- */
26
- issuesRouter.post('/create', async (req, res) => {
27
- try {
28
- // Load project configuration
29
- const config = (0, config_loader_js_1.loadFraimConfig)();
30
- const repoOwner = config.git?.repoOwner || process.env.GITHUB_OWNER || 'your-org';
31
- const repoName = config.git?.repoName || process.env.GITHUB_REPO || 'your-repo';
32
- // Get user context (if available - project-specific)
33
- // Projects can customize this based on their auth system
34
- const userId = req.userContext?.userId ||
35
- req.executiveContext?.executiveId ||
36
- req.headers['x-user-id'];
37
- const userEmail = req.userContext?.email ||
38
- req.executiveContext?.executiveEmail ||
39
- req.headers['x-user-email'];
40
- const userName = req.userContext?.name ||
41
- req.executiveContext?.executiveName ||
42
- req.headers['x-user-name'];
43
- const { title, body, labels } = req.body;
44
- if (!title || !body) {
45
- return res.status(400).json({
46
- success: false,
47
- error: 'Missing required fields: title, body'
48
- });
49
- }
50
- // Check if GitHub token is configured
51
- if (!process.env.GITHUB_TOKEN && !process.env.GIT_TOKEN && !process.env.GITHUB_PAT) {
52
- return res.status(500).json({
53
- success: false,
54
- error: 'GitHub integration not configured. Please set GITHUB_TOKEN environment variable.'
55
- });
56
- }
57
- // Build issue body with user context (if available)
58
- let issueBody = body;
59
- if (userName || userEmail || userId) {
60
- issueBody = `**Reported by:** ${userName || 'Unknown'}${userEmail ? ` (${userEmail})` : ''}${userId ? `\n**User ID:** ${userId}` : ''}\n\n**Issue Details:**\n${body}\n\n---\n*This issue was automatically created through the API.*`;
61
- }
62
- // Create the issue using shared function
63
- const result = await (0, issues_js_1.fileFraimIssue)({
64
- title: title,
65
- body: issueBody,
66
- labels: labels || ['user-reported']
67
- });
68
- if (!result.success) {
69
- return res.status(500).json({
70
- success: false,
71
- error: result.message
72
- });
73
- }
74
- return res.json({
75
- success: true,
76
- message: 'Issue created successfully',
77
- issueNumber: result.issueNumber,
78
- issueUrl: result.htmlUrl,
79
- title: title
80
- });
81
- }
82
- catch (error) {
83
- console.error('❌ Unexpected error creating Git issue:', error);
84
- return res.status(500).json({
85
- success: false,
86
- error: error.message || 'Failed to create Git issue'
87
- });
88
- }
89
- });
90
- /**
91
- * GET /issues/list - List issues
92
- *
93
- * Not implemented in this generic version.
94
- */
95
- issuesRouter.get('/list', async (req, res) => {
96
- return res.status(501).json({
97
- success: false,
98
- error: 'Listing issues is not supported in this generic API version yet.'
99
- });
100
- });