fraim-framework 2.0.2 โ 2.0.4
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/examples/simple-webapp/TESTING.md +62 -0
- package/examples/simple-webapp/example-test.ts +186 -0
- package/package.json +10 -1
- package/setup.js +203 -28
- package/.cursor/rules/cursor-rules.mdc +0 -8
- package/.cursor/rules/design.mdc +0 -4
- package/.cursor/rules/implement.mdc +0 -6
- package/.cursor/rules/resolve.mdc +0 -5
- package/.cursor/rules/retrospect.mdc +0 -4
- package/.cursor/rules/spec.mdc +0 -4
- package/.cursor/rules/test.mdc +0 -5
- package/.windsurf/rules/windsurf-rules.md +0 -7
- package/.windsurf/workflows/resolve-issue.md +0 -6
- package/.windsurf/workflows/retrospect.md +0 -6
- package/.windsurf/workflows/start-design.md +0 -6
- package/.windsurf/workflows/start-impl.md +0 -6
- package/.windsurf/workflows/start-spec.md +0 -6
- package/.windsurf/workflows/start-tests.md +0 -6
- package/CODEOWNERS +0 -24
- package/install.sh +0 -58
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Testing with FRAIM Framework
|
|
2
|
+
|
|
3
|
+
This directory contains example test cases that demonstrate how to use the FRAIM testing framework with proper tagging and structure.
|
|
4
|
+
|
|
5
|
+
## Test Structure
|
|
6
|
+
|
|
7
|
+
The example test file (`example-test.ts`) demonstrates:
|
|
8
|
+
|
|
9
|
+
- **BaseTestCase Interface**: All test cases extend the `BaseTestCase` interface
|
|
10
|
+
- **Tagging System**: Tests are tagged with categories like `smoke`, `integration`, `performance`, etc.
|
|
11
|
+
- **Test Organization**: Tests are organized by functionality and complexity
|
|
12
|
+
- **Mock Functions**: Example mock functions for common scenarios
|
|
13
|
+
|
|
14
|
+
## Recommended Test Tags (you can add others to your preference)
|
|
15
|
+
|
|
16
|
+
- **`smoke`**: Critical tests that must pass for basic functionality
|
|
17
|
+
- **`flaky`**: Tests that may be unreliable or environment-dependent
|
|
18
|
+
- **`failing`**: Tests that are currently failing and need debugging
|
|
19
|
+
|
|
20
|
+
## Running Tests
|
|
21
|
+
|
|
22
|
+
### Run All Tests
|
|
23
|
+
```bash
|
|
24
|
+
npx run test example-test.ts
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Run Only Smoke Tests
|
|
28
|
+
```bash
|
|
29
|
+
npx run test-smoke example-test.ts
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Run Only Flaky Tests
|
|
33
|
+
```bash
|
|
34
|
+
npx run test-flkay *test*.ts
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Best Practices
|
|
38
|
+
|
|
39
|
+
1. **Always use tags**: Tag your tests appropriately for easy filtering
|
|
40
|
+
2. **Include descriptions**: Provide clear descriptions of what each test does
|
|
41
|
+
3. **Use meaningful names**: Test names should clearly indicate what's being tested
|
|
42
|
+
4. **Handle errors gracefully**: Catch and report errors appropriately
|
|
43
|
+
5. **Use mocks for external dependencies**: Don't rely on external services in tests
|
|
44
|
+
6. **Test both success and failure cases**: Ensure your tests cover edge cases
|
|
45
|
+
|
|
46
|
+
## Integration with FRAIM
|
|
47
|
+
|
|
48
|
+
This testing framework integrates with FRAIM's agent coordination system:
|
|
49
|
+
|
|
50
|
+
- **AI Agents**: Use these tests during implementation phase
|
|
51
|
+
- **CI/CD**: Automated test execution with proper tagging
|
|
52
|
+
- **Evidence Collection**: Test results are collected as evidence for reviews
|
|
53
|
+
|
|
54
|
+
## Customization
|
|
55
|
+
|
|
56
|
+
To adapt this testing framework for your project:
|
|
57
|
+
|
|
58
|
+
1. **Update mock functions**: Replace example mocks with your actual functions
|
|
59
|
+
2. **Add project-specific tags**: Define tags relevant to your domain
|
|
60
|
+
3. **Customize test structure**: Modify the test case interface as needed
|
|
61
|
+
4. **Add setup/teardown**: Include any necessary test setup or cleanup
|
|
62
|
+
5. **Configure CI integration**: Set up automated test execution in your CI pipeline
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Example Test Case for FRAIM Framework
|
|
5
|
+
*
|
|
6
|
+
* This demonstrates how to write test cases using the FRAIM testing framework
|
|
7
|
+
* with proper tagging and structure.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { BaseTestCase, runTests } from '../../test-utils';
|
|
11
|
+
|
|
12
|
+
// Example test case interface extending BaseTestCase
|
|
13
|
+
interface ExampleTestCase extends BaseTestCase {
|
|
14
|
+
description: string;
|
|
15
|
+
testFunction: () => Promise<boolean>;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Example test cases with different tags
|
|
19
|
+
const EXAMPLE_TEST_CASES: ExampleTestCase[] = [
|
|
20
|
+
{
|
|
21
|
+
name: 'test_basic_functionality',
|
|
22
|
+
tags: ['smoke', 'basic'],
|
|
23
|
+
description: 'Should verify basic application functionality works',
|
|
24
|
+
testFunction: async () => {
|
|
25
|
+
console.log('๐งช Testing basic functionality...');
|
|
26
|
+
|
|
27
|
+
// Example: Test that a basic function works
|
|
28
|
+
const result = await basicFunction();
|
|
29
|
+
|
|
30
|
+
if (result !== 'success') {
|
|
31
|
+
console.log(`โ Expected 'success', got '${result}'`);
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
console.log('โ
Basic functionality test passed');
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
name: 'test_user_authentication',
|
|
41
|
+
tags: ['smoke', 'auth'],
|
|
42
|
+
description: 'Should verify user authentication works correctly',
|
|
43
|
+
testFunction: async () => {
|
|
44
|
+
console.log('๐งช Testing user authentication...');
|
|
45
|
+
|
|
46
|
+
// Example: Test authentication flow
|
|
47
|
+
const authResult = await authenticateUser('test@example.com', 'password123');
|
|
48
|
+
|
|
49
|
+
if (!authResult.success) {
|
|
50
|
+
console.log(`โ Authentication failed: ${authResult.error}`);
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
console.log('โ
User authentication test passed');
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
name: 'test_api_integration',
|
|
60
|
+
tags: ['integration', 'api'],
|
|
61
|
+
description: 'Should verify API integration works correctly',
|
|
62
|
+
testFunction: async () => {
|
|
63
|
+
console.log('๐งช Testing API integration...');
|
|
64
|
+
|
|
65
|
+
// Example: Test API call
|
|
66
|
+
const apiResult = await callExternalAPI('https://api.example.com/data');
|
|
67
|
+
|
|
68
|
+
if (!apiResult || !apiResult.data) {
|
|
69
|
+
console.log('โ API integration failed - no data returned');
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
console.log('โ
API integration test passed');
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
name: 'test_database_operations',
|
|
79
|
+
tags: ['database', 'integration'],
|
|
80
|
+
description: 'Should verify database operations work correctly',
|
|
81
|
+
testFunction: async () => {
|
|
82
|
+
console.log('๐งช Testing database operations...');
|
|
83
|
+
|
|
84
|
+
// Example: Test database operations
|
|
85
|
+
const dbResult = await performDatabaseOperation();
|
|
86
|
+
|
|
87
|
+
if (!dbResult.success) {
|
|
88
|
+
console.log(`โ Database operation failed: ${dbResult.error}`);
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
console.log('โ
Database operations test passed');
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
name: 'test_performance_benchmark',
|
|
98
|
+
tags: ['performance', 'flaky'],
|
|
99
|
+
description: 'Should verify performance meets requirements (may be flaky)',
|
|
100
|
+
testFunction: async () => {
|
|
101
|
+
console.log('๐งช Testing performance benchmark...');
|
|
102
|
+
|
|
103
|
+
const startTime = Date.now();
|
|
104
|
+
await performExpensiveOperation();
|
|
105
|
+
const endTime = Date.now();
|
|
106
|
+
|
|
107
|
+
const duration = endTime - startTime;
|
|
108
|
+
const maxDuration = 1000; // 1 second
|
|
109
|
+
|
|
110
|
+
if (duration > maxDuration) {
|
|
111
|
+
console.log(`โ Performance test failed: ${duration}ms > ${maxDuration}ms`);
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
console.log(`โ
Performance test passed: ${duration}ms`);
|
|
116
|
+
return true;
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
name: 'test_failing_scenario',
|
|
121
|
+
tags: ['failing', 'debug'],
|
|
122
|
+
description: 'This test is currently failing and needs debugging',
|
|
123
|
+
testFunction: async () => {
|
|
124
|
+
console.log('๐งช Testing failing scenario...');
|
|
125
|
+
|
|
126
|
+
// This test is intentionally failing to demonstrate the failing tag
|
|
127
|
+
console.log('โ This test is currently failing for demonstration');
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
];
|
|
132
|
+
|
|
133
|
+
// Mock functions for demonstration
|
|
134
|
+
async function basicFunction(): Promise<string> {
|
|
135
|
+
// Simulate some work
|
|
136
|
+
await new Promise(resolve => setTimeout(resolve, 10));
|
|
137
|
+
return 'success';
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
async function authenticateUser(email: string, password: string): Promise<{success: boolean, error?: string}> {
|
|
141
|
+
// Simulate authentication
|
|
142
|
+
await new Promise(resolve => setTimeout(resolve, 50));
|
|
143
|
+
|
|
144
|
+
if (email === 'test@example.com' && password === 'password123') {
|
|
145
|
+
return { success: true };
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
return { success: false, error: 'Invalid credentials' };
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
async function callExternalAPI(url: string): Promise<{data?: any}> {
|
|
152
|
+
// Simulate API call
|
|
153
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
154
|
+
|
|
155
|
+
return {
|
|
156
|
+
data: {
|
|
157
|
+
id: 1,
|
|
158
|
+
name: 'Test Data',
|
|
159
|
+
timestamp: new Date().toISOString()
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
async function performDatabaseOperation(): Promise<{success: boolean, error?: string}> {
|
|
165
|
+
// Simulate database operation
|
|
166
|
+
await new Promise(resolve => setTimeout(resolve, 75));
|
|
167
|
+
|
|
168
|
+
return { success: true };
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
async function performExpensiveOperation(): Promise<void> {
|
|
172
|
+
// Simulate expensive operation
|
|
173
|
+
await new Promise(resolve => setTimeout(resolve, 500));
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Test runner function
|
|
177
|
+
const runExampleTest = async (testCase: ExampleTestCase): Promise<boolean> => {
|
|
178
|
+
try {
|
|
179
|
+
return await testCase.testFunction();
|
|
180
|
+
} catch (error) {
|
|
181
|
+
console.log(`โ Test ${testCase.name} threw an error: ${error}`);
|
|
182
|
+
return false;
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
await runTests(EXAMPLE_TEST_CASES, runExampleTest, 'Example Test Suite');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fraim-framework",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.4",
|
|
4
4
|
"description": "FRAIM v2: Framework for Rigor-based AI Management - Transform from solo developer to AI manager orchestrating production-ready code with enterprise-grade discipline",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -49,6 +49,15 @@
|
|
|
49
49
|
"tsx": "^4.0.0",
|
|
50
50
|
"dotenv": "^16.0.0"
|
|
51
51
|
},
|
|
52
|
+
"files": [
|
|
53
|
+
".ai-agents/",
|
|
54
|
+
"examples/",
|
|
55
|
+
"bin/",
|
|
56
|
+
"*.js",
|
|
57
|
+
"*.ts",
|
|
58
|
+
"*.md",
|
|
59
|
+
"*.json"
|
|
60
|
+
],
|
|
52
61
|
"publishConfig": {
|
|
53
62
|
"access": "public"
|
|
54
63
|
}
|
package/setup.js
CHANGED
|
@@ -208,7 +208,7 @@ THIS IS THE MOST CRITICAL RULE. Be ethical, truthful, honest above all.
|
|
|
208
208
|
- **Accessibility**: Consider accessibility implications in all designs
|
|
209
209
|
- **Documentation**: Document known limitations and issues
|
|
210
210
|
- **Attribution**: Properly attribute external code sources and inspirations`;
|
|
211
|
-
writeFile('rules/integrity-and-test-ethics.md', integrityContent);
|
|
211
|
+
writeFile('.ai-agents/rules/integrity-and-test-ethics.md', integrityContent);
|
|
212
212
|
logSuccess('Created integrity-and-test-ethics.md');
|
|
213
213
|
|
|
214
214
|
// Create simplicity.md
|
|
@@ -238,7 +238,7 @@ Keep solutions simple and focused, avoid over-engineering.
|
|
|
238
238
|
- Avoid making unrelated changes
|
|
239
239
|
- File separate issues for other problems you discover
|
|
240
240
|
- Keep the scope narrow and well-defined`;
|
|
241
|
-
writeFile('rules/simplicity.md', simplicityContent);
|
|
241
|
+
writeFile('.ai-agents/rules/simplicity.md', simplicityContent);
|
|
242
242
|
logSuccess('Created simplicity.md');
|
|
243
243
|
|
|
244
244
|
// Create architecture.md
|
|
@@ -268,7 +268,7 @@ Maintain clean architectural boundaries by using appropriate technologies for ea
|
|
|
268
268
|
- Use deterministic code for business logic and data processing
|
|
269
269
|
- Select appropriate data storage technologies based on access patterns
|
|
270
270
|
- Choose UI frameworks based on application requirements and team expertise`;
|
|
271
|
-
writeFile('rules/architecture.md', architectureContent);
|
|
271
|
+
writeFile('.ai-agents/rules/architecture.md', architectureContent);
|
|
272
272
|
logSuccess('Created architecture.md');
|
|
273
273
|
|
|
274
274
|
// Create continuous-learning.md
|
|
@@ -299,7 +299,7 @@ Prevent repeating past mistakes by systematically learning from retrospectives,
|
|
|
299
299
|
- Check knowledge base for relevant patterns and anti-patterns
|
|
300
300
|
- Document new learnings after completing work
|
|
301
301
|
- Share insights with the team through appropriate channels`;
|
|
302
|
-
writeFile('rules/continuous-learning.md', continuousLearningContent);
|
|
302
|
+
writeFile('.ai-agents/rules/continuous-learning.md', continuousLearningContent);
|
|
303
303
|
logSuccess('Created continuous-learning.md');
|
|
304
304
|
|
|
305
305
|
// Create successful-debugging-patterns.md
|
|
@@ -332,7 +332,7 @@ Debug issues systematically and convert learnings into test cases.
|
|
|
332
332
|
- Break complex issues into smaller, testable components
|
|
333
333
|
- Document the debugging process and findings
|
|
334
334
|
- Create regression tests that would have caught the issue`;
|
|
335
|
-
writeFile('rules/successful-debugging-patterns.md', debuggingContent);
|
|
335
|
+
writeFile('.ai-agents/rules/successful-debugging-patterns.md', debuggingContent);
|
|
336
336
|
logSuccess('Created successful-debugging-patterns.md');
|
|
337
337
|
}
|
|
338
338
|
|
|
@@ -382,7 +382,7 @@ This workflow guides the design phase for new features or significant changes.
|
|
|
382
382
|
- Comprehensive RFC document
|
|
383
383
|
- Updated issue with implementation tasks
|
|
384
384
|
- Design approval from stakeholders`;
|
|
385
|
-
writeFile('workflows/design.md', designContent);
|
|
385
|
+
writeFile('.ai-agents/workflows/design.md', designContent);
|
|
386
386
|
logSuccess('Created design.md workflow');
|
|
387
387
|
|
|
388
388
|
// Create implement.md
|
|
@@ -432,7 +432,7 @@ This workflow guides the implementation phase after design approval.
|
|
|
432
432
|
- Comprehensive test coverage
|
|
433
433
|
- Updated documentation
|
|
434
434
|
- Pull request ready for review`;
|
|
435
|
-
writeFile('workflows/implement.md', implementContent);
|
|
435
|
+
writeFile('.ai-agents/workflows/implement.md', implementContent);
|
|
436
436
|
logSuccess('Created implement.md workflow');
|
|
437
437
|
|
|
438
438
|
// Create test.md
|
|
@@ -484,7 +484,7 @@ This workflow guides the testing phase to ensure quality and reliability.
|
|
|
484
484
|
- Test evidence documentation
|
|
485
485
|
- Test coverage report
|
|
486
486
|
- Stakeholder approval of test results`;
|
|
487
|
-
writeFile('workflows/test.md', testContent);
|
|
487
|
+
writeFile('.ai-agents/workflows/test.md', testContent);
|
|
488
488
|
logSuccess('Created test.md workflow');
|
|
489
489
|
|
|
490
490
|
// Create resolve.md
|
|
@@ -541,7 +541,7 @@ This workflow guides the process of resolving issues and bugs.
|
|
|
541
541
|
- Fixed implementation
|
|
542
542
|
- Tests that prevent regression
|
|
543
543
|
- Documentation of the resolution`;
|
|
544
|
-
writeFile('workflows/resolve.md', resolveContent);
|
|
544
|
+
writeFile('.ai-agents/workflows/resolve.md', resolveContent);
|
|
545
545
|
logSuccess('Created resolve.md workflow');
|
|
546
546
|
|
|
547
547
|
// Create retrospect.md
|
|
@@ -593,26 +593,23 @@ This workflow guides the process of conducting retrospectives after completing s
|
|
|
593
593
|
- Action items with owners and deadlines
|
|
594
594
|
- Updated processes and guidelines
|
|
595
595
|
- Knowledge sharing with the team`;
|
|
596
|
-
writeFile('workflows/retrospect.md', retrospectContent);
|
|
596
|
+
writeFile('.ai-agents/workflows/retrospect.md', retrospectContent);
|
|
597
597
|
logSuccess('Created retrospect.md workflow');
|
|
598
598
|
}
|
|
599
599
|
|
|
600
600
|
// Create project structure
|
|
601
601
|
function createProjectStructure() {
|
|
602
602
|
// Create directories
|
|
603
|
-
ensureDirectory('
|
|
604
|
-
ensureDirectory('
|
|
605
|
-
ensureDirectory('
|
|
606
|
-
ensureDirectory('templates/
|
|
607
|
-
ensureDirectory('templates/
|
|
608
|
-
ensureDirectory('templates/
|
|
609
|
-
ensureDirectory('
|
|
610
|
-
ensureDirectory('
|
|
603
|
+
ensureDirectory('.ai-agents/rules');
|
|
604
|
+
ensureDirectory('.ai-agents/workflows');
|
|
605
|
+
ensureDirectory('.ai-agents/templates/evidence');
|
|
606
|
+
ensureDirectory('.ai-agents/templates/retrospective');
|
|
607
|
+
ensureDirectory('.ai-agents/templates/specs');
|
|
608
|
+
ensureDirectory('.ai-agents/templates/help');
|
|
609
|
+
ensureDirectory('.ai-agents/scripts');
|
|
610
|
+
ensureDirectory('examples/simple-webapp');
|
|
611
611
|
ensureDirectory('.github/workflows');
|
|
612
|
-
ensureDirectory('
|
|
613
|
-
ensureDirectory('agents/claude');
|
|
614
|
-
ensureDirectory('agents/windsurf');
|
|
615
|
-
ensureDirectory('scripts');
|
|
612
|
+
ensureDirectory('docs');
|
|
616
613
|
|
|
617
614
|
logSuccess('Created directory structure');
|
|
618
615
|
|
|
@@ -624,8 +621,8 @@ function createProjectStructure() {
|
|
|
624
621
|
- Could be new tests that need to be added into an existing test suite
|
|
625
622
|
- Could be a new test suite
|
|
626
623
|
`;
|
|
627
|
-
writeFile('
|
|
628
|
-
logSuccess('Created
|
|
624
|
+
writeFile('.ai-agents/templates/specs/BUGSPEC-TEMPLATE.md', bugfixTemplate);
|
|
625
|
+
logSuccess('Created BUGSPEC-TEMPLATE.md');
|
|
629
626
|
|
|
630
627
|
// Create RFC template
|
|
631
628
|
const rfcTemplate = `# RFC: <Title>
|
|
@@ -644,16 +641,20 @@ Owner: <agent>
|
|
|
644
641
|
- Unit: modules & edge cases
|
|
645
642
|
- Integration: API <-> DB <-> external
|
|
646
643
|
- E2E: user flows (happy/sad)`;
|
|
647
|
-
writeFile('
|
|
648
|
-
logSuccess('Created
|
|
644
|
+
writeFile('.ai-agents/templates/specs/FEATURESPEC-TEMPLATE.md', rfcTemplate);
|
|
645
|
+
logSuccess('Created FEATURESPEC-TEMPLATE.md');
|
|
649
646
|
|
|
650
|
-
//
|
|
651
|
-
|
|
647
|
+
// Copy all rule files from the package
|
|
648
|
+
copyRuleFiles();
|
|
652
649
|
logSuccess('Created rule files');
|
|
653
650
|
|
|
654
651
|
// Create workflow templates
|
|
655
652
|
createWorkflowTemplates();
|
|
656
653
|
logSuccess('Created workflow templates');
|
|
654
|
+
|
|
655
|
+
// Copy additional files
|
|
656
|
+
copyAdditionalFiles();
|
|
657
|
+
logSuccess('Copied additional files');
|
|
657
658
|
|
|
658
659
|
// Create basic CODEOWNERS file
|
|
659
660
|
const codeownersContent = `# This file defines the code owners for the repository
|
|
@@ -804,6 +805,180 @@ Owner: <agent>
|
|
|
804
805
|
logSuccess('Created labels.json');
|
|
805
806
|
}
|
|
806
807
|
|
|
808
|
+
// Copy rule files from the package
|
|
809
|
+
function copyRuleFiles() {
|
|
810
|
+
const fs = require('fs');
|
|
811
|
+
const path = require('path');
|
|
812
|
+
|
|
813
|
+
// List of rule files to copy
|
|
814
|
+
const ruleFiles = [
|
|
815
|
+
'agent-testing-guidelines.md',
|
|
816
|
+
'architecture.md',
|
|
817
|
+
'communication.md',
|
|
818
|
+
'continuous-learning.md',
|
|
819
|
+
'git-safe-commands.md',
|
|
820
|
+
'integrity-and-test-ethics.md',
|
|
821
|
+
'local-development.md',
|
|
822
|
+
'merge-requirements.md',
|
|
823
|
+
'pr-workflow-completeness.md',
|
|
824
|
+
'simplicity.md',
|
|
825
|
+
'software-development-lifecycle.md',
|
|
826
|
+
'spike-first-development.md',
|
|
827
|
+
'successful-debugging-patterns.md'
|
|
828
|
+
];
|
|
829
|
+
|
|
830
|
+
// Copy each rule file
|
|
831
|
+
ruleFiles.forEach(file => {
|
|
832
|
+
try {
|
|
833
|
+
const sourcePath = path.join(__dirname, '.ai-agents', 'rules', file);
|
|
834
|
+
const destPath = path.join('.ai-agents', 'rules', file);
|
|
835
|
+
|
|
836
|
+
if (fs.existsSync(sourcePath)) {
|
|
837
|
+
fs.copyFileSync(sourcePath, destPath);
|
|
838
|
+
logSuccess(`Copied ${file}`);
|
|
839
|
+
} else {
|
|
840
|
+
console.log(`โ ๏ธ Warning: ${file} not found in package`);
|
|
841
|
+
}
|
|
842
|
+
} catch (error) {
|
|
843
|
+
console.log(`โ ๏ธ Warning: Could not copy ${file}: ${error.message}`);
|
|
844
|
+
}
|
|
845
|
+
});
|
|
846
|
+
|
|
847
|
+
// Copy workflow files
|
|
848
|
+
const workflowFiles = [
|
|
849
|
+
'design.md',
|
|
850
|
+
'implement.md',
|
|
851
|
+
'resolve.md',
|
|
852
|
+
'retrospect.md',
|
|
853
|
+
'spec.md',
|
|
854
|
+
'test.md'
|
|
855
|
+
];
|
|
856
|
+
|
|
857
|
+
workflowFiles.forEach(file => {
|
|
858
|
+
try {
|
|
859
|
+
const sourcePath = path.join(__dirname, '.ai-agents', 'workflows', file);
|
|
860
|
+
const destPath = path.join('.ai-agents', 'workflows', file);
|
|
861
|
+
|
|
862
|
+
if (fs.existsSync(sourcePath)) {
|
|
863
|
+
fs.copyFileSync(sourcePath, destPath);
|
|
864
|
+
logSuccess(`Copied ${file}`);
|
|
865
|
+
} else {
|
|
866
|
+
console.log(`โ ๏ธ Warning: ${file} not found in package`);
|
|
867
|
+
}
|
|
868
|
+
} catch (error) {
|
|
869
|
+
console.log(`โ ๏ธ Warning: Could not copy ${file}: ${error.message}`);
|
|
870
|
+
}
|
|
871
|
+
});
|
|
872
|
+
|
|
873
|
+
// Copy template files
|
|
874
|
+
const templateFiles = [
|
|
875
|
+
'templates/evidence/Design-Evidence.md',
|
|
876
|
+
'templates/evidence/Implementation-BugEvidence.md',
|
|
877
|
+
'templates/evidence/Implementation-FeatureEvidence.md',
|
|
878
|
+
'templates/evidence/Spec-Evidence.md',
|
|
879
|
+
'templates/help/HelpNeeded.md',
|
|
880
|
+
'templates/retrospective/RETROSPECTIVE-TEMPLATE.md',
|
|
881
|
+
'templates/specs/BUGSPEC-TEMPLATE.md',
|
|
882
|
+
'templates/specs/FEATURESPEC-TEMPLATE.md',
|
|
883
|
+
'templates/specs/TECHSPEC-TEMPLATE.md'
|
|
884
|
+
];
|
|
885
|
+
|
|
886
|
+
templateFiles.forEach(file => {
|
|
887
|
+
try {
|
|
888
|
+
const sourcePath = path.join(__dirname, '.ai-agents', file);
|
|
889
|
+
const destPath = path.join('.ai-agents', file);
|
|
890
|
+
|
|
891
|
+
if (fs.existsSync(sourcePath)) {
|
|
892
|
+
fs.copyFileSync(sourcePath, destPath);
|
|
893
|
+
logSuccess(`Copied ${file}`);
|
|
894
|
+
} else {
|
|
895
|
+
console.log(`โ ๏ธ Warning: ${file} not found in package`);
|
|
896
|
+
}
|
|
897
|
+
} catch (error) {
|
|
898
|
+
console.log(`โ ๏ธ Warning: Could not copy ${file}: ${error.message}`);
|
|
899
|
+
}
|
|
900
|
+
});
|
|
901
|
+
|
|
902
|
+
// Copy script files
|
|
903
|
+
const scriptFiles = [
|
|
904
|
+
'scripts/cleanup-branch.ts',
|
|
905
|
+
'scripts/exec-with-timeout.ts',
|
|
906
|
+
'scripts/prep-issue.sh'
|
|
907
|
+
];
|
|
908
|
+
|
|
909
|
+
scriptFiles.forEach(file => {
|
|
910
|
+
try {
|
|
911
|
+
const sourcePath = path.join(__dirname, '.ai-agents', file);
|
|
912
|
+
const destPath = path.join('.ai-agents', file);
|
|
913
|
+
|
|
914
|
+
if (fs.existsSync(sourcePath)) {
|
|
915
|
+
fs.copyFileSync(sourcePath, destPath);
|
|
916
|
+
logSuccess(`Copied ${file}`);
|
|
917
|
+
} else {
|
|
918
|
+
console.log(`โ ๏ธ Warning: ${file} not found in package`);
|
|
919
|
+
}
|
|
920
|
+
} catch (error) {
|
|
921
|
+
console.log(`โ ๏ธ Warning: Could not copy ${file}: ${error.message}`);
|
|
922
|
+
}
|
|
923
|
+
});
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
// Copy additional files
|
|
927
|
+
function copyAdditionalFiles() {
|
|
928
|
+
const fs = require('fs');
|
|
929
|
+
const path = require('path');
|
|
930
|
+
|
|
931
|
+
// Copy sample files
|
|
932
|
+
const additionalFiles = [
|
|
933
|
+
'sample_package.json',
|
|
934
|
+
'test-utils.ts',
|
|
935
|
+
'tsconfig.json'
|
|
936
|
+
];
|
|
937
|
+
|
|
938
|
+
additionalFiles.forEach(file => {
|
|
939
|
+
try {
|
|
940
|
+
const sourcePath = path.join(__dirname, file);
|
|
941
|
+
const destPath = file;
|
|
942
|
+
|
|
943
|
+
if (fs.existsSync(sourcePath)) {
|
|
944
|
+
fs.copyFileSync(sourcePath, destPath);
|
|
945
|
+
logSuccess(`Copied ${file}`);
|
|
946
|
+
} else {
|
|
947
|
+
console.log(`โ ๏ธ Warning: ${file} not found in package`);
|
|
948
|
+
}
|
|
949
|
+
} catch (error) {
|
|
950
|
+
console.log(`โ ๏ธ Warning: Could not copy ${file}: ${error.message}`);
|
|
951
|
+
}
|
|
952
|
+
});
|
|
953
|
+
|
|
954
|
+
// Copy examples
|
|
955
|
+
try {
|
|
956
|
+
const examplesSource = path.join(__dirname, 'examples', 'simple-webapp');
|
|
957
|
+
const examplesDest = 'examples/simple-webapp';
|
|
958
|
+
|
|
959
|
+
if (fs.existsSync(examplesSource)) {
|
|
960
|
+
ensureDirectory(examplesDest);
|
|
961
|
+
|
|
962
|
+
const exampleFiles = [
|
|
963
|
+
'example-test.ts',
|
|
964
|
+
'TESTING.md'
|
|
965
|
+
];
|
|
966
|
+
|
|
967
|
+
exampleFiles.forEach(file => {
|
|
968
|
+
const sourcePath = path.join(examplesSource, file);
|
|
969
|
+
const destPath = path.join(examplesDest, file);
|
|
970
|
+
|
|
971
|
+
if (fs.existsSync(sourcePath)) {
|
|
972
|
+
fs.copyFileSync(sourcePath, destPath);
|
|
973
|
+
logSuccess(`Copied examples/simple-webapp/${file}`);
|
|
974
|
+
}
|
|
975
|
+
});
|
|
976
|
+
}
|
|
977
|
+
} catch (error) {
|
|
978
|
+
console.log(`โ ๏ธ Warning: Could not copy examples: ${error.message}`);
|
|
979
|
+
}
|
|
980
|
+
}
|
|
981
|
+
|
|
807
982
|
// Export the main setup function
|
|
808
983
|
function runSetup() {
|
|
809
984
|
console.log('๐ Setting up FRAIM in current repository...\n');
|
package/.cursor/rules/design.mdc
DELETED
package/.cursor/rules/spec.mdc
DELETED
package/.cursor/rules/test.mdc
DELETED
package/CODEOWNERS
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
# This file defines the code owners for the FRAIM repository
|
|
2
|
-
# Code owners are automatically requested for review when someone opens a PR that modifies code they own
|
|
3
|
-
# See: https://docs.github.com/en/repositories/managing-your-codebase-in-github/about-code-owners
|
|
4
|
-
|
|
5
|
-
# Default owners for everything in the repo
|
|
6
|
-
* @mathursrus
|
|
7
|
-
|
|
8
|
-
# Specific ownership for different parts of the codebase
|
|
9
|
-
/agents/ @mathursrus
|
|
10
|
-
/rules/ @mathursrus
|
|
11
|
-
/workflows/ @mathursrus
|
|
12
|
-
/templates/ @mathursrus
|
|
13
|
-
/scripts/ @mathursrus
|
|
14
|
-
/.github/ @mathursrus
|
|
15
|
-
|
|
16
|
-
# Documentation
|
|
17
|
-
/docs/ @mathursrus
|
|
18
|
-
*.md @mathursrus
|
|
19
|
-
|
|
20
|
-
# Configuration files
|
|
21
|
-
*.json @mathursrus
|
|
22
|
-
*.jsonc @mathursrus
|
|
23
|
-
*.yml @mathursrus
|
|
24
|
-
*.yaml @mathursrus
|
package/install.sh
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
|
|
3
|
-
# FRAIM One-Line Installer
|
|
4
|
-
# Framework for Rigor-based AI Management
|
|
5
|
-
# Where humans become AI managers through rigorous methodology
|
|
6
|
-
|
|
7
|
-
set -e
|
|
8
|
-
|
|
9
|
-
# Colors for output
|
|
10
|
-
RED='\033[0;31m'
|
|
11
|
-
GREEN='\033[0;32m'
|
|
12
|
-
YELLOW='\033[1;33m'
|
|
13
|
-
BLUE='\033[0;34m'
|
|
14
|
-
NC='\033[0m' # No Color
|
|
15
|
-
|
|
16
|
-
# Banner
|
|
17
|
-
echo -e "${BLUE}"
|
|
18
|
-
cat << 'EOF'
|
|
19
|
-
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
20
|
-
โ ๐ FRAIM โ
|
|
21
|
-
โ Framework for Rigor-based AI Management โ
|
|
22
|
-
โ Where humans become AI managers โ
|
|
23
|
-
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
24
|
-
EOF
|
|
25
|
-
echo -e "${NC}"
|
|
26
|
-
|
|
27
|
-
echo -e "${GREEN}๐ค Welcome to FRAIM!${NC}"
|
|
28
|
-
echo -e "${GREEN}Where humans become AI managers through rigorous methodology${NC}\n"
|
|
29
|
-
|
|
30
|
-
# Check if we're in a git repository
|
|
31
|
-
if [ ! -d ".git" ]; then
|
|
32
|
-
echo -e "${RED}โ Error: Not in a git repository${NC}"
|
|
33
|
-
echo "Please run this script from within a git repository."
|
|
34
|
-
exit 1
|
|
35
|
-
fi
|
|
36
|
-
|
|
37
|
-
# Check if FRAIM is already installed
|
|
38
|
-
if [ -d "FRAIM" ]; then
|
|
39
|
-
echo -e "${YELLOW}โ ๏ธ FRAIM appears to already be installed in this repository${NC}"
|
|
40
|
-
echo "If you want to reinstall, please remove the existing FRAIM folder first."
|
|
41
|
-
exit 1
|
|
42
|
-
fi
|
|
43
|
-
|
|
44
|
-
echo -e "${BLUE}๐ฅ Installing FRAIM framework...${NC}"
|
|
45
|
-
|
|
46
|
-
# Download FRAIM from GitHub
|
|
47
|
-
echo "Downloading FRAIM framework..."
|
|
48
|
-
curl -sSL https://raw.githubusercontent.com/mathursrus/FRAIM/master/install.sh | bash -s -- --repo $(git remote get-url origin | sed 's/.*github.com[:/]\([^/]*\/[^/]*\).*/\1/' | sed 's/\.git$//')
|
|
49
|
-
|
|
50
|
-
echo -e "\n${GREEN}โ
FRAIM installation complete!${NC}"
|
|
51
|
-
echo -e "\n${BLUE}๐ Next steps:${NC}"
|
|
52
|
-
echo "1. Review the FRAIM folder that was created"
|
|
53
|
-
echo "2. Run: npx @fraim/framework init"
|
|
54
|
-
echo "3. Start managing your AI agents with RIGOR methodology!"
|
|
55
|
-
echo -e "\n${BLUE}๐ Learn more:${NC}"
|
|
56
|
-
echo "Documentation: https://github.com/mathursrus/FRAIM"
|
|
57
|
-
echo -e "\n${GREEN}๐ฏ Ready to become an AI manager?${NC}"
|
|
58
|
-
echo "The FRAIM framework is now installed and ready to use!"
|