faf-cli 4.3.0 โ 4.3.2
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.
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +40 -22
- package/dist/cli.js.map +1 -1
- package/dist/commands/readme.d.ts +11 -6
- package/dist/commands/readme.d.ts.map +1 -1
- package/dist/commands/readme.js +167 -120
- package/dist/commands/readme.js.map +1 -1
- package/dist/commands/show.d.ts.map +1 -1
- package/dist/commands/show.js +22 -7
- package/dist/commands/show.js.map +1 -1
- package/dist/commands/sixws.d.ts +6 -0
- package/dist/commands/sixws.d.ts.map +1 -0
- package/dist/commands/sixws.js +154 -0
- package/dist/commands/sixws.js.map +1 -0
- package/dist/utils/file-utils.d.ts.map +1 -1
- package/dist/utils/file-utils.js +1 -4
- package/dist/utils/file-utils.js.map +1 -1
- package/package.json +6 -2
- package/project.faf +4 -4
- package/scripts/ANTHROPIC-DEMO.sh +203 -0
- package/scripts/boris-ready.sh +169 -0
- package/scripts/bundle-yaml.js +87 -0
- package/scripts/check-version.js +88 -0
- package/scripts/clean-build.js +34 -0
- package/scripts/cleanup-unused.sh +54 -0
- package/scripts/debug-django.txt +9 -0
- package/scripts/debug-mongo.txt +9 -0
- package/scripts/debug-react.txt +9 -0
- package/scripts/debug-rust.txt +9 -0
- package/scripts/debug-whisper.cpp.txt +9 -0
- package/scripts/evaluate-family-member.ts +300 -0
- package/scripts/generate-docs.ts +358 -0
- package/scripts/generate-drift-reports.sh +111 -0
- package/scripts/industry-showcase.json +122 -0
- package/scripts/mcp-ecosystem-research.sh +58 -0
- package/scripts/migrate-yaml-imports.sh +55 -0
- package/scripts/migrate-yaml.ts +132 -0
- package/scripts/performance-validation.ts +460 -0
- package/scripts/postinstall.js +30 -0
- package/scripts/prepare-release.ts +421 -0
- package/scripts/run-industry-showcase.ts +237 -0
- package/scripts/run-test-showcase.ts +244 -0
- package/scripts/setup-github-watch.sh +43 -0
- package/scripts/sync-version.js +35 -0
- package/scripts/test-integration-detection.ts +93 -0
- package/scripts/test-integration-simple.js +93 -0
- package/scripts/test-medal-progression.sh +143 -0
- package/scripts/test-showcase-results.json +109 -0
- package/scripts/test-showcase.json +32 -0
- package/scripts/update-version.js +148 -0
- package/scripts/verify-build.js +343 -0
- package/scripts/version-check.js +78 -0
- package/scripts/watch-discussions.sh +86 -0
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Test Showcase Runner (5 repos)
|
|
4
|
+
* Tests the showcase runner on a small sample before running full 70 repos
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { execSync } from 'child_process';
|
|
8
|
+
import { readFileSync, writeFileSync } from 'fs';
|
|
9
|
+
import { join } from 'path';
|
|
10
|
+
import * as yaml from 'yaml';
|
|
11
|
+
|
|
12
|
+
interface ShowcaseData {
|
|
13
|
+
title: string;
|
|
14
|
+
description: string;
|
|
15
|
+
updated: string;
|
|
16
|
+
categories: Array<{
|
|
17
|
+
name: string;
|
|
18
|
+
repos: string[];
|
|
19
|
+
}>;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
interface RepoResult {
|
|
23
|
+
repo: string;
|
|
24
|
+
owner: string;
|
|
25
|
+
name: string;
|
|
26
|
+
category: string;
|
|
27
|
+
currentScore: number;
|
|
28
|
+
newScore: number;
|
|
29
|
+
improvement: number;
|
|
30
|
+
tier: string;
|
|
31
|
+
stack: {
|
|
32
|
+
frontend?: string;
|
|
33
|
+
backend?: string;
|
|
34
|
+
runtime?: string;
|
|
35
|
+
build?: string;
|
|
36
|
+
database?: string;
|
|
37
|
+
hosting?: string;
|
|
38
|
+
};
|
|
39
|
+
projectType: string;
|
|
40
|
+
mainLanguage: string;
|
|
41
|
+
description: string;
|
|
42
|
+
status: 'success' | 'failed' | 'rate-limited';
|
|
43
|
+
error?: string;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
interface ShowcaseResults {
|
|
47
|
+
generated: string;
|
|
48
|
+
totalRepos: number;
|
|
49
|
+
successCount: number;
|
|
50
|
+
failedCount: number;
|
|
51
|
+
avgImprovement: number;
|
|
52
|
+
categories: Array<{
|
|
53
|
+
name: string;
|
|
54
|
+
repos: RepoResult[];
|
|
55
|
+
}>;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function parseFafGitOutput(output: string): { currentScore: number; newScore: number; improvement: number; tier: string } | null {
|
|
59
|
+
// Strip ANSI color codes first
|
|
60
|
+
// eslint-disable-next-line no-control-regex
|
|
61
|
+
const cleanOutput = output.replace(/\x1b\[[0-9;]*m/g, '');
|
|
62
|
+
|
|
63
|
+
// v4.3.0 format (after stripping colors):
|
|
64
|
+
// Current: No .faf file โ ๏ธ
|
|
65
|
+
// With FAF: 100% ๐ Trophy
|
|
66
|
+
|
|
67
|
+
const currentMatch = cleanOutput.match(/Current:\s+No \.faf file/);
|
|
68
|
+
const withFafMatch = cleanOutput.match(/With FAF:\s+(\d+)%\s+([๐๐ฅ๐ฅ๐ฅ๐ข๐ก๐ด๐คโ ๏ธ]+)\s*(\w+)?/);
|
|
69
|
+
|
|
70
|
+
if (!withFafMatch) {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const currentScore = currentMatch ? 0 : 0; // Always 0 for "No .faf file"
|
|
75
|
+
const newScore = parseInt(withFafMatch[1]);
|
|
76
|
+
const tier = withFafMatch[3] || 'Unknown';
|
|
77
|
+
const improvement = newScore - currentScore;
|
|
78
|
+
|
|
79
|
+
return {
|
|
80
|
+
currentScore,
|
|
81
|
+
newScore,
|
|
82
|
+
improvement,
|
|
83
|
+
tier
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function extractStackFromFaf(fafPath: string): any {
|
|
88
|
+
try {
|
|
89
|
+
const content = readFileSync(fafPath, 'utf-8');
|
|
90
|
+
const parsed = yaml.parse(content);
|
|
91
|
+
|
|
92
|
+
return {
|
|
93
|
+
stack: {
|
|
94
|
+
frontend: parsed.stack?.frontend !== 'slotignored' ? parsed.stack?.frontend : undefined,
|
|
95
|
+
backend: parsed.stack?.backend !== 'slotignored' ? parsed.stack?.backend : undefined,
|
|
96
|
+
runtime: parsed.stack?.runtime !== 'slotignored' ? parsed.stack?.runtime : undefined,
|
|
97
|
+
build: parsed.stack?.build !== 'slotignored' ? parsed.stack?.build : undefined,
|
|
98
|
+
database: parsed.stack?.database !== 'slotignored' ? parsed.stack?.database : undefined,
|
|
99
|
+
hosting: parsed.stack?.hosting !== 'slotignored' ? parsed.stack?.hosting : undefined,
|
|
100
|
+
},
|
|
101
|
+
projectType: parsed.project?.type || 'unknown',
|
|
102
|
+
mainLanguage: parsed.project?.main_language || 'unknown',
|
|
103
|
+
description: parsed.project?.goal || parsed.metadata?.description || ''
|
|
104
|
+
};
|
|
105
|
+
} catch (e) {
|
|
106
|
+
return {
|
|
107
|
+
stack: {},
|
|
108
|
+
projectType: 'unknown',
|
|
109
|
+
mainLanguage: 'unknown',
|
|
110
|
+
description: ''
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
async function runTestShowcase() {
|
|
116
|
+
console.log('๐๏ธ FAF Test Showcase Runner (5 repos)\n');
|
|
117
|
+
|
|
118
|
+
// Read test showcase data
|
|
119
|
+
const showcaseData: ShowcaseData = JSON.parse(
|
|
120
|
+
readFileSync(join(__dirname, 'test-showcase.json'), 'utf-8')
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
const results: ShowcaseResults = {
|
|
124
|
+
generated: new Date().toISOString(),
|
|
125
|
+
totalRepos: 0,
|
|
126
|
+
successCount: 0,
|
|
127
|
+
failedCount: 0,
|
|
128
|
+
avgImprovement: 0,
|
|
129
|
+
categories: []
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
let totalImprovement = 0;
|
|
133
|
+
|
|
134
|
+
for (const category of showcaseData.categories) {
|
|
135
|
+
console.log(`\n๐ Category: ${category.name}`);
|
|
136
|
+
console.log(` Testing ${category.repos.length} repos...\n`);
|
|
137
|
+
|
|
138
|
+
const categoryResults: RepoResult[] = [];
|
|
139
|
+
|
|
140
|
+
for (const repo of category.repos) {
|
|
141
|
+
results.totalRepos++;
|
|
142
|
+
const [owner, name] = repo.split('/');
|
|
143
|
+
|
|
144
|
+
process.stdout.write(` โก ${repo}... `);
|
|
145
|
+
|
|
146
|
+
try {
|
|
147
|
+
// Run faf git (use local build to avoid bin name collision with bun-sticky)
|
|
148
|
+
const output = execSync(
|
|
149
|
+
`node ${join(__dirname, '../dist/cli.js')} git ${repo}`,
|
|
150
|
+
{
|
|
151
|
+
encoding: 'utf-8',
|
|
152
|
+
timeout: 30000,
|
|
153
|
+
stdio: 'pipe'
|
|
154
|
+
}
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
// Parse output
|
|
158
|
+
const scores = parseFafGitOutput(output);
|
|
159
|
+
|
|
160
|
+
if (!scores) {
|
|
161
|
+
// Debug: save output to file
|
|
162
|
+
const debugPath = join(__dirname, `debug-${name}.txt`);
|
|
163
|
+
writeFileSync(debugPath, output);
|
|
164
|
+
throw new Error(`Failed to parse output (saved to ${debugPath})`);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Extract stack from generated .faf file
|
|
168
|
+
const fafPath = join(process.cwd(), `${name}.faf`);
|
|
169
|
+
const fafData = extractStackFromFaf(fafPath);
|
|
170
|
+
|
|
171
|
+
const result: RepoResult = {
|
|
172
|
+
repo,
|
|
173
|
+
owner,
|
|
174
|
+
name,
|
|
175
|
+
category: category.name,
|
|
176
|
+
currentScore: scores.currentScore,
|
|
177
|
+
newScore: scores.newScore,
|
|
178
|
+
improvement: scores.improvement,
|
|
179
|
+
tier: scores.tier,
|
|
180
|
+
stack: fafData.stack,
|
|
181
|
+
projectType: fafData.projectType,
|
|
182
|
+
mainLanguage: fafData.mainLanguage,
|
|
183
|
+
description: fafData.description,
|
|
184
|
+
status: 'success'
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
categoryResults.push(result);
|
|
188
|
+
results.successCount++;
|
|
189
|
+
totalImprovement += scores.improvement;
|
|
190
|
+
|
|
191
|
+
console.log(`โ
${scores.currentScore}% โ ${scores.newScore}% (+${scores.improvement})`);
|
|
192
|
+
|
|
193
|
+
} catch (error: any) {
|
|
194
|
+
results.failedCount++;
|
|
195
|
+
|
|
196
|
+
const result: RepoResult = {
|
|
197
|
+
repo,
|
|
198
|
+
owner,
|
|
199
|
+
name,
|
|
200
|
+
category: category.name,
|
|
201
|
+
currentScore: 0,
|
|
202
|
+
newScore: 0,
|
|
203
|
+
improvement: 0,
|
|
204
|
+
tier: 'Failed',
|
|
205
|
+
stack: {},
|
|
206
|
+
projectType: 'unknown',
|
|
207
|
+
mainLanguage: 'unknown',
|
|
208
|
+
description: '',
|
|
209
|
+
status: error.message?.includes('rate limit') ? 'rate-limited' : 'failed',
|
|
210
|
+
error: error.message
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
categoryResults.push(result);
|
|
214
|
+
console.log(`โ ${error.message.split('\n')[0]}`);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// Rate limit protection (1 second between requests)
|
|
218
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
results.categories.push({
|
|
222
|
+
name: category.name,
|
|
223
|
+
repos: categoryResults
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// Calculate average improvement
|
|
228
|
+
results.avgImprovement = results.successCount > 0
|
|
229
|
+
? Math.round(totalImprovement / results.successCount)
|
|
230
|
+
: 0;
|
|
231
|
+
|
|
232
|
+
// Save results
|
|
233
|
+
const outputPath = join(__dirname, 'test-showcase-results.json');
|
|
234
|
+
writeFileSync(outputPath, JSON.stringify(results, null, 2));
|
|
235
|
+
|
|
236
|
+
console.log(`\n\n๐ Test Showcase Complete!\n`);
|
|
237
|
+
console.log(` Total Repos: ${results.totalRepos}`);
|
|
238
|
+
console.log(` โ
Success: ${results.successCount}`);
|
|
239
|
+
console.log(` โ Failed: ${results.failedCount}`);
|
|
240
|
+
console.log(` ๐ Avg Improvement: +${results.avgImprovement} points\n`);
|
|
241
|
+
console.log(`๐ Results saved to: ${outputPath}\n`);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
runTestShowcase().catch(console.error);
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# ๐ฉต Setup GitHub Discussions Watching for FAF
|
|
3
|
+
|
|
4
|
+
echo "๐ฉต Setting up GitHub Discussions alerts for FAF..."
|
|
5
|
+
echo ""
|
|
6
|
+
|
|
7
|
+
# Check if gh is installed
|
|
8
|
+
if ! command -v gh &> /dev/null; then
|
|
9
|
+
echo "โ GitHub CLI (gh) is not installed"
|
|
10
|
+
echo "Install with: brew install gh"
|
|
11
|
+
exit 1
|
|
12
|
+
fi
|
|
13
|
+
|
|
14
|
+
# Check authentication
|
|
15
|
+
if ! gh auth status &> /dev/null; then
|
|
16
|
+
echo "โ Not authenticated with GitHub"
|
|
17
|
+
echo "Run: gh auth login"
|
|
18
|
+
exit 1
|
|
19
|
+
fi
|
|
20
|
+
|
|
21
|
+
echo "โ
GitHub CLI authenticated"
|
|
22
|
+
|
|
23
|
+
# Watch the repository
|
|
24
|
+
echo "๐บ Watching FAF repository for activity..."
|
|
25
|
+
gh api -X PUT repos/Wolfe-Jam/faf/subscription \
|
|
26
|
+
--field subscribed=true \
|
|
27
|
+
--field ignored=false 2>/dev/null && echo "โ
Subscribed to repository notifications"
|
|
28
|
+
|
|
29
|
+
# Enable web notifications for discussions
|
|
30
|
+
echo "๐ Enabling discussion notifications..."
|
|
31
|
+
gh api -X PUT repos/Wolfe-Jam/faf/notifications \
|
|
32
|
+
--field discussions=true 2>/dev/null || echo "โน๏ธ Notifications API not available (normal)"
|
|
33
|
+
|
|
34
|
+
echo ""
|
|
35
|
+
echo "๐ฉต Setup complete! You can now:"
|
|
36
|
+
echo " 1. Run ./scripts/watch-discussions.sh to monitor in terminal"
|
|
37
|
+
echo " 2. Check https://github.com/Wolfe-Jam/faf/discussions for activity"
|
|
38
|
+
echo " 3. View notifications at https://github.com/notifications"
|
|
39
|
+
echo ""
|
|
40
|
+
echo "๐ก For best results, also enable notifications in GitHub web settings:"
|
|
41
|
+
echo " https://github.com/settings/notifications"
|
|
42
|
+
echo ""
|
|
43
|
+
echo "Thank you for engaging with the FAF community! ๐ฉตโก"
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Sync version from package.json to project.faf
|
|
4
|
+
* Run: npm run sync-version
|
|
5
|
+
* Auto-runs on: npm version (via "version" lifecycle hook)
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
|
|
11
|
+
const packageJsonPath = path.join(__dirname, '..', 'package.json');
|
|
12
|
+
const projectFafPath = path.join(__dirname, '..', 'project.faf');
|
|
13
|
+
|
|
14
|
+
try {
|
|
15
|
+
// Read version from package.json
|
|
16
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
|
|
17
|
+
const version = packageJson.version;
|
|
18
|
+
|
|
19
|
+
// Read project.faf
|
|
20
|
+
let projectFaf = fs.readFileSync(projectFafPath, 'utf-8');
|
|
21
|
+
|
|
22
|
+
// Update version field
|
|
23
|
+
projectFaf = projectFaf.replace(
|
|
24
|
+
/^(\s*version:\s*).+$/m,
|
|
25
|
+
`$1${version}`
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
// Write back
|
|
29
|
+
fs.writeFileSync(projectFafPath, projectFaf);
|
|
30
|
+
|
|
31
|
+
console.log(`Synced project.faf version to ${version}`);
|
|
32
|
+
} catch (error) {
|
|
33
|
+
console.error('Failed to sync version:', error.message);
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
#!/usr/bin/env ts-node
|
|
2
|
+
/**
|
|
3
|
+
* Test Integration Detection System
|
|
4
|
+
*
|
|
5
|
+
* Tests FAF Family detectors on real projects
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { integrationRegistry } from '../src/family/registry';
|
|
9
|
+
import { resolve } from 'path';
|
|
10
|
+
|
|
11
|
+
async function testProject(projectPath: string, projectName: string) {
|
|
12
|
+
console.log(`\n${'='.repeat(60)}`);
|
|
13
|
+
console.log(`๐ Testing: ${projectName}`);
|
|
14
|
+
console.log(`๐ Path: ${projectPath}`);
|
|
15
|
+
console.log(`${'='.repeat(60)}\n`);
|
|
16
|
+
|
|
17
|
+
try {
|
|
18
|
+
// Detect all integrations
|
|
19
|
+
const detected = await integrationRegistry.detectAll(projectPath);
|
|
20
|
+
|
|
21
|
+
if (detected.length === 0) {
|
|
22
|
+
console.log('โ No integrations detected\n');
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
console.log(`โ
Detected ${detected.length} integration(s):\n`);
|
|
27
|
+
|
|
28
|
+
// Show each detected integration
|
|
29
|
+
detected.forEach((integration, index) => {
|
|
30
|
+
const emoji = {
|
|
31
|
+
trophy: '๐',
|
|
32
|
+
gold: '๐ฅ',
|
|
33
|
+
silver: '๐ฅ',
|
|
34
|
+
bronze: '๐ฅ',
|
|
35
|
+
}[integration.tier] || 'โช';
|
|
36
|
+
|
|
37
|
+
console.log(`${index + 1}. ${emoji} ${integration.displayName}`);
|
|
38
|
+
console.log(` Tier: ${integration.tier} (${integration.qualityScore} quality score)`);
|
|
39
|
+
console.log(` Weekly adoption: ${integration.weeklyAdoption.toLocaleString()} developers`);
|
|
40
|
+
console.log(` MCP servers: ${integration.mcpServers.join(', ')}`);
|
|
41
|
+
console.log(` Context slots: ${integration.contextContribution.join(', ')}`);
|
|
42
|
+
console.log('');
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
// Generate combined context
|
|
46
|
+
console.log('๐ Generating combined .faf context...\n');
|
|
47
|
+
const context = await integrationRegistry.generateContext(projectPath);
|
|
48
|
+
|
|
49
|
+
console.log('Generated Context:');
|
|
50
|
+
console.log(JSON.stringify(context, null, 2));
|
|
51
|
+
console.log('');
|
|
52
|
+
|
|
53
|
+
} catch (error) {
|
|
54
|
+
console.error('โ Error testing project:', error);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async function main() {
|
|
59
|
+
console.log('๐ FAF Integration Detection System - Test Suite\n');
|
|
60
|
+
console.log('Championship Standard: Auto-detect stacks and generate optimized .faf context\n');
|
|
61
|
+
|
|
62
|
+
const testProjects = [
|
|
63
|
+
{
|
|
64
|
+
name: 'faf-cli (this project)',
|
|
65
|
+
path: resolve(__dirname, '..'),
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
name: 'claude-faf-mcp',
|
|
69
|
+
path: resolve(__dirname, '../../claude-faf-mcp'),
|
|
70
|
+
},
|
|
71
|
+
];
|
|
72
|
+
|
|
73
|
+
for (const project of testProjects) {
|
|
74
|
+
await testProject(project.path, project.name);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Show registry stats
|
|
78
|
+
console.log(`\n${'='.repeat(60)}`);
|
|
79
|
+
console.log('๐ Integration Registry Statistics');
|
|
80
|
+
console.log(`${'='.repeat(60)}\n`);
|
|
81
|
+
|
|
82
|
+
const stats = integrationRegistry.getStats();
|
|
83
|
+
console.log(`Total integrations: ${stats.total}`);
|
|
84
|
+
console.log(`Total weekly adoption: ${stats.totalWeeklyAdoption.toLocaleString()} developers`);
|
|
85
|
+
console.log('\nBy tier:');
|
|
86
|
+
Object.entries(stats.byTier).forEach(([tier, count]) => {
|
|
87
|
+
console.log(` ${tier}: ${count}`);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
console.log('\n๐ Test suite complete!');
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
main().catch(console.error);
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Test Integration Detection System (Simple JavaScript version)
|
|
4
|
+
*
|
|
5
|
+
* Tests FAF Family detectors on real projects
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const { integrationRegistry } = require('../dist/family/registry.js');
|
|
9
|
+
const { resolve } = require('path');
|
|
10
|
+
|
|
11
|
+
async function testProject(projectPath, projectName) {
|
|
12
|
+
console.log(`\n${'='.repeat(60)}`);
|
|
13
|
+
console.log(`๐ Testing: ${projectName}`);
|
|
14
|
+
console.log(`๐ Path: ${projectPath}`);
|
|
15
|
+
console.log(`${'='.repeat(60)}\n`);
|
|
16
|
+
|
|
17
|
+
try {
|
|
18
|
+
// Detect all integrations
|
|
19
|
+
const detected = await integrationRegistry.detectAll(projectPath);
|
|
20
|
+
|
|
21
|
+
if (detected.length === 0) {
|
|
22
|
+
console.log('โ No integrations detected\n');
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
console.log(`โ
Detected ${detected.length} integration(s):\n`);
|
|
27
|
+
|
|
28
|
+
// Show each detected integration
|
|
29
|
+
detected.forEach((integration, index) => {
|
|
30
|
+
const emoji = {
|
|
31
|
+
trophy: '๐',
|
|
32
|
+
gold: '๐ฅ',
|
|
33
|
+
silver: '๐ฅ',
|
|
34
|
+
bronze: '๐ฅ',
|
|
35
|
+
}[integration.tier] || 'โช';
|
|
36
|
+
|
|
37
|
+
console.log(`${index + 1}. ${emoji} ${integration.displayName}`);
|
|
38
|
+
console.log(` Tier: ${integration.tier} (${integration.qualityScore} quality score)`);
|
|
39
|
+
console.log(` Weekly adoption: ${integration.weeklyAdoption.toLocaleString()} developers`);
|
|
40
|
+
console.log(` MCP servers: ${integration.mcpServers.join(', ')}`);
|
|
41
|
+
console.log(` Context slots: ${integration.contextContribution.join(', ')}`);
|
|
42
|
+
console.log('');
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
// Generate combined context
|
|
46
|
+
console.log('๐ Generating combined .faf context...\n');
|
|
47
|
+
const context = await integrationRegistry.generateContext(projectPath);
|
|
48
|
+
|
|
49
|
+
console.log('Generated Context:');
|
|
50
|
+
console.log(JSON.stringify(context, null, 2));
|
|
51
|
+
console.log('');
|
|
52
|
+
|
|
53
|
+
} catch (error) {
|
|
54
|
+
console.error('โ Error testing project:', error.message);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async function main() {
|
|
59
|
+
console.log('๐ FAF Integration Detection System - Test Suite\n');
|
|
60
|
+
console.log('Championship Standard: Auto-detect stacks and generate optimized .faf context\n');
|
|
61
|
+
|
|
62
|
+
const testProjects = [
|
|
63
|
+
{
|
|
64
|
+
name: 'faf-cli (this project)',
|
|
65
|
+
path: resolve(__dirname, '..'),
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
name: 'claude-faf-mcp',
|
|
69
|
+
path: resolve(__dirname, '../../claude-faf-mcp'),
|
|
70
|
+
},
|
|
71
|
+
];
|
|
72
|
+
|
|
73
|
+
for (const project of testProjects) {
|
|
74
|
+
await testProject(project.path, project.name);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Show registry stats
|
|
78
|
+
console.log(`\n${'='.repeat(60)}`);
|
|
79
|
+
console.log('๐ Integration Registry Statistics');
|
|
80
|
+
console.log(`${'='.repeat(60)}\n`);
|
|
81
|
+
|
|
82
|
+
const stats = integrationRegistry.getStats();
|
|
83
|
+
console.log(`Total integrations: ${stats.total}`);
|
|
84
|
+
console.log(`Total weekly adoption: ${stats.totalWeeklyAdoption.toLocaleString()} developers`);
|
|
85
|
+
console.log('\nBy tier:');
|
|
86
|
+
Object.entries(stats.byTier).forEach(([tier, count]) => {
|
|
87
|
+
console.log(` ${tier}: ${count}`);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
console.log('\n๐ Test suite complete!');
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
main().catch(console.error);
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
##
|
|
4
|
+
# ๐ WJTC Medal Progression Visual Test
|
|
5
|
+
# Manual verification of championship medal display
|
|
6
|
+
#
|
|
7
|
+
# Philosophy: "We break things so others never even know they were ever broken"
|
|
8
|
+
##
|
|
9
|
+
|
|
10
|
+
set -e
|
|
11
|
+
|
|
12
|
+
echo "๐๏ธโก๏ธ WJTC MEDAL PROGRESSION TEST - Championship Visual Verification"
|
|
13
|
+
echo "โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ"
|
|
14
|
+
echo ""
|
|
15
|
+
|
|
16
|
+
# Test scores covering all medal tiers
|
|
17
|
+
TEST_SCORES=(
|
|
18
|
+
"0:๐ด Stop - Needs work"
|
|
19
|
+
"48:๐ด Stop - Needs work (near threshold)"
|
|
20
|
+
"55:๐ก Caution - Getting ready"
|
|
21
|
+
"62:๐ก Caution - Getting ready (mid-range)"
|
|
22
|
+
"70:๐ข GO! - Ready for Target 1"
|
|
23
|
+
"77:๐ข GO! - Ready for Target 1 (mid-range)"
|
|
24
|
+
"85:๐ฅ Target 1 - Bronze"
|
|
25
|
+
"88:๐ฅ Target 1 - Bronze (mid-range)"
|
|
26
|
+
"95:๐ฅ Target 2 - Silver"
|
|
27
|
+
"96:๐ฅ Target 2 - Silver (mid-range)"
|
|
28
|
+
"99:๐ฅ Gold"
|
|
29
|
+
"100:๐ Trophy - Championship"
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
# Create temp directory
|
|
33
|
+
TEST_DIR="/tmp/faf-medal-test-$$"
|
|
34
|
+
mkdir -p "$TEST_DIR"
|
|
35
|
+
|
|
36
|
+
echo "๐ Test directory: $TEST_DIR"
|
|
37
|
+
echo ""
|
|
38
|
+
|
|
39
|
+
# Function to create a test .faf file with specific score
|
|
40
|
+
create_test_faf() {
|
|
41
|
+
local score=$1
|
|
42
|
+
local label=$2
|
|
43
|
+
local dir="$TEST_DIR/project-$score"
|
|
44
|
+
|
|
45
|
+
mkdir -p "$dir"
|
|
46
|
+
|
|
47
|
+
# Calculate filled slots based on score
|
|
48
|
+
# 21 total slots, so score% = (filled/21) * 100
|
|
49
|
+
local filled_slots=$(echo "scale=0; ($score * 21) / 100" | bc)
|
|
50
|
+
|
|
51
|
+
# Create minimal .faf file
|
|
52
|
+
cat > "$dir/.faf" <<EOF
|
|
53
|
+
faf_version: "2.4.0"
|
|
54
|
+
ai_scoring_system: "2025-08-30"
|
|
55
|
+
ai_score: "${score}%"
|
|
56
|
+
ai_confidence: $([ $score -ge 70 ] && echo "HIGH" || echo "LOW")
|
|
57
|
+
project:
|
|
58
|
+
name: "Test Project $score%"
|
|
59
|
+
goal: "Testing medal display at $score%"
|
|
60
|
+
main_language: "TypeScript"
|
|
61
|
+
stack:
|
|
62
|
+
frontend: "React"
|
|
63
|
+
backend: "Node.js"
|
|
64
|
+
database: "PostgreSQL"
|
|
65
|
+
human_context:
|
|
66
|
+
who: "Developers"
|
|
67
|
+
what: "Test project for medal validation"
|
|
68
|
+
why: "WJTC championship testing"
|
|
69
|
+
where: "Testing environment"
|
|
70
|
+
when: "Now"
|
|
71
|
+
how: "Manual test script"
|
|
72
|
+
ai_instructions:
|
|
73
|
+
priority_order:
|
|
74
|
+
- "Test medal display"
|
|
75
|
+
working_style:
|
|
76
|
+
code_first: true
|
|
77
|
+
context_quality:
|
|
78
|
+
slots_filled: "$filled_slots/21 (${score}%)"
|
|
79
|
+
ai_confidence: $([ $score -ge 70 ] && echo "HIGH" || echo "LOW")
|
|
80
|
+
EOF
|
|
81
|
+
|
|
82
|
+
echo "$dir"
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
echo "๐จ Creating test projects..."
|
|
86
|
+
echo ""
|
|
87
|
+
|
|
88
|
+
# Create all test projects
|
|
89
|
+
TEST_PROJECTS=()
|
|
90
|
+
for entry in "${TEST_SCORES[@]}"; do
|
|
91
|
+
score="${entry%%:*}"
|
|
92
|
+
label="${entry#*:}"
|
|
93
|
+
|
|
94
|
+
project_dir=$(create_test_faf "$score" "$label")
|
|
95
|
+
TEST_PROJECTS+=("$score:$label:$project_dir")
|
|
96
|
+
|
|
97
|
+
echo " โ
Created: $score% - $label"
|
|
98
|
+
done
|
|
99
|
+
|
|
100
|
+
echo ""
|
|
101
|
+
echo "โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ"
|
|
102
|
+
echo "๐ RUNNING VISUAL VERIFICATION TESTS"
|
|
103
|
+
echo "โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ"
|
|
104
|
+
echo ""
|
|
105
|
+
|
|
106
|
+
# Run faf show on each project
|
|
107
|
+
for entry in "${TEST_PROJECTS[@]}"; do
|
|
108
|
+
score="${entry%%:*}"
|
|
109
|
+
rest="${entry#*:}"
|
|
110
|
+
label="${rest%%:*}"
|
|
111
|
+
project_dir="${rest#*:}"
|
|
112
|
+
|
|
113
|
+
echo "โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ"
|
|
114
|
+
echo "๐ Testing: $score% - $label"
|
|
115
|
+
echo "โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ"
|
|
116
|
+
echo ""
|
|
117
|
+
|
|
118
|
+
# Run faf show
|
|
119
|
+
npx ts-node src/cli.ts show "$project_dir"
|
|
120
|
+
|
|
121
|
+
echo ""
|
|
122
|
+
echo "โ
Verify: Medal matches expected '$label'"
|
|
123
|
+
echo ""
|
|
124
|
+
read -p "Press Enter to continue to next test..."
|
|
125
|
+
echo ""
|
|
126
|
+
done
|
|
127
|
+
|
|
128
|
+
echo "โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ"
|
|
129
|
+
echo "๐ WJTC MEDAL PROGRESSION TEST COMPLETE"
|
|
130
|
+
echo "โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ"
|
|
131
|
+
echo ""
|
|
132
|
+
echo "๐ Manual Verification Checklist:"
|
|
133
|
+
echo ""
|
|
134
|
+
echo " [ ] All medals display correctly"
|
|
135
|
+
echo " [ ] Traffic light progression is clear (๐ดโ๐กโ๐ข)"
|
|
136
|
+
echo " [ ] Medal progression is clear (๐ฅโ๐ฅโ๐ฅโ๐)"
|
|
137
|
+
echo " [ ] No medals shown at wrong scores"
|
|
138
|
+
echo " [ ] Colors match medal tier appropriately"
|
|
139
|
+
echo ""
|
|
140
|
+
echo "๐งน Cleanup: rm -rf $TEST_DIR"
|
|
141
|
+
echo ""
|
|
142
|
+
echo "Status: ${GREEN}READY FOR WJTC REPORT${NC}"
|
|
143
|
+
echo ""
|