fraim-framework 1.0.0 → 1.0.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/bin/fraim.js +16 -8
- package/package.json +1 -1
- package/setup.js +337 -74
package/bin/fraim.js
CHANGED
|
@@ -70,6 +70,19 @@ function showRigor() {
|
|
|
70
70
|
console.log('✨ Every rule has been tested and proven in real project environments.');
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
+
async function runSetup() {
|
|
74
|
+
try {
|
|
75
|
+
// Import and run the setup script
|
|
76
|
+
const { runSetup: setupFunction } = require('../setup.js');
|
|
77
|
+
setupFunction();
|
|
78
|
+
} catch (error) {
|
|
79
|
+
console.error('❌ Failed to run setup:', error.message);
|
|
80
|
+
console.log('\n💡 Try running the setup script directly:');
|
|
81
|
+
console.log(' node setup.js');
|
|
82
|
+
process.exit(1);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
73
86
|
function main() {
|
|
74
87
|
const args = process.argv.slice(2);
|
|
75
88
|
|
|
@@ -86,13 +99,7 @@ function main() {
|
|
|
86
99
|
if (args.includes('init') || args.includes('setup')) {
|
|
87
100
|
console.log(banner);
|
|
88
101
|
console.log('🚀 Setting up FRAIM in current repository...\n');
|
|
89
|
-
|
|
90
|
-
console.log(' • Create GitHub labels for AI management');
|
|
91
|
-
console.log(' • Set up automated workflows');
|
|
92
|
-
console.log(' • Configure AI agent rules (all tested & proven)');
|
|
93
|
-
console.log(' • Initialize documentation\n');
|
|
94
|
-
console.log('💡 Run: npx fraim-framework init # For full setup');
|
|
95
|
-
console.log('🔧 Or run: npx fraim-framework wizard # For interactive setup');
|
|
102
|
+
runSetup();
|
|
96
103
|
return;
|
|
97
104
|
}
|
|
98
105
|
|
|
@@ -104,7 +111,8 @@ function main() {
|
|
|
104
111
|
console.log(' 2. AI agent setup (with tested rules)');
|
|
105
112
|
console.log(' 3. Workflow customization');
|
|
106
113
|
console.log(' 4. Team member onboarding\n');
|
|
107
|
-
console.log('💡
|
|
114
|
+
console.log('💡 Starting setup wizard...\n');
|
|
115
|
+
runSetup();
|
|
108
116
|
return;
|
|
109
117
|
}
|
|
110
118
|
|
package/package.json
CHANGED
package/setup.js
CHANGED
|
@@ -1,86 +1,349 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
/**
|
|
4
|
-
* FRAIM Setup Script
|
|
5
|
-
* Framework for Rigor-based AI Management
|
|
6
|
-
*
|
|
7
|
-
* This script sets up the FRAIM framework in a GitHub repository,
|
|
8
|
-
* implementing the RIGOR methodology for coordinated AI agent development.
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
const { program } = require('commander');
|
|
12
3
|
const fs = require('fs');
|
|
13
4
|
const path = require('path');
|
|
14
5
|
|
|
15
|
-
//
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
6
|
+
// Colors for console output
|
|
7
|
+
const colors = {
|
|
8
|
+
reset: '\x1b[0m',
|
|
9
|
+
bright: '\x1b[1m',
|
|
10
|
+
red: '\x1b[31m',
|
|
11
|
+
green: '\x1b[32m',
|
|
12
|
+
yellow: '\x1b[33m',
|
|
13
|
+
blue: '\x1b[34m',
|
|
14
|
+
magenta: '\x1b[35m',
|
|
15
|
+
cyan: '\x1b[36m'
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
function log(message, color = 'reset') {
|
|
19
|
+
console.log(`${colors[color]}${message}${colors.reset}`);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function logSuccess(message) {
|
|
23
|
+
log(`✅ ${message}`, 'green');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function logInfo(message) {
|
|
27
|
+
log(`ℹ️ ${message}`, 'blue');
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function logWarning(message) {
|
|
31
|
+
log(`⚠️ ${message}`, 'yellow');
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function logError(message) {
|
|
35
|
+
log(`❌ ${message}`, 'red');
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function logHeader(message) {
|
|
39
|
+
log(`\n${colors.bright}${colors.cyan}${message}${colors.reset}`);
|
|
40
|
+
log('─'.repeat(message.length));
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function ensureDirectory(dirPath) {
|
|
44
|
+
if (!fs.existsSync(dirPath)) {
|
|
45
|
+
fs.mkdirSync(dirPath, { recursive: true });
|
|
46
|
+
logSuccess(`Created directory: ${dirPath}`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function writeFile(filePath, content) {
|
|
51
|
+
ensureDirectory(path.dirname(filePath));
|
|
52
|
+
fs.writeFileSync(filePath, content);
|
|
53
|
+
logSuccess(`Created file: ${filePath}`);
|
|
54
|
+
}
|
|
23
55
|
|
|
24
|
-
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
{ name: 'ai-agent:windsurf', color: '2CA02C', description: 'Assigned to Windsurf agent (Code understanding)' },
|
|
40
|
-
|
|
41
|
-
// Priority Labels (optional)
|
|
42
|
-
{ name: 'priority:critical', color: 'D93F0B', description: 'Critical priority' },
|
|
43
|
-
{ name: 'priority:high', color: 'FBCA04', description: 'High priority' },
|
|
44
|
-
{ name: 'priority:medium', color: '0E8A16', description: 'Medium priority' },
|
|
45
|
-
{ name: 'priority:low', color: '0366D6', description: 'Low priority' }
|
|
46
|
-
];
|
|
47
|
-
|
|
48
|
-
// Main setup function
|
|
49
|
-
async function setupFRAIM(options) {
|
|
50
|
-
console.log(FRAIM_BANNER);
|
|
51
|
-
console.log('🚀 Setting up FRAIM in your repository...\n');
|
|
56
|
+
function createGitHubLabels() {
|
|
57
|
+
const labels = [
|
|
58
|
+
{ name: 'phase:design', color: '0e8a16', description: 'Design phase - RFC creation and review' },
|
|
59
|
+
{ name: 'phase:impl', color: '1d76db', description: 'Implementation phase - coding and testing' },
|
|
60
|
+
{ name: 'phase:tests', color: 'fef2c0', description: 'Testing phase - validation and QA' },
|
|
61
|
+
{ name: 'status:wip', color: 'fbca04', description: 'Work in progress' },
|
|
62
|
+
{ name: 'status:needs-review', color: 'd93f0b', description: 'Ready for review' },
|
|
63
|
+
{ name: 'status:complete', color: '0e8a16', description: 'Completed and approved' },
|
|
64
|
+
{ name: 'ai-agent:cursor', color: '5319e7', description: 'Assigned to Cursor AI agent' },
|
|
65
|
+
{ name: 'ai-agent:claude', color: 'c2e0c6', description: 'Assigned to Claude AI agent' },
|
|
66
|
+
{ name: 'ai-agent:windsurf', color: 'bfdadc', description: 'Assigned to Windsurf AI agent' }
|
|
67
|
+
];
|
|
68
|
+
|
|
69
|
+
const labelsContent = JSON.stringify(labels, null, 2);
|
|
70
|
+
writeFile('.github/labels.json', labelsContent);
|
|
52
71
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
72
|
+
logInfo('GitHub labels configuration created');
|
|
73
|
+
logInfo('You can import these labels using GitHub CLI or the web interface');
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function createGitHubWorkflows() {
|
|
77
|
+
// Phase change workflow
|
|
78
|
+
const phaseChangeWorkflow = `name: Phase Change Automation
|
|
79
|
+
|
|
80
|
+
on:
|
|
81
|
+
issues:
|
|
82
|
+
types: [labeled, unlabeled]
|
|
83
|
+
|
|
84
|
+
jobs:
|
|
85
|
+
phase-change:
|
|
86
|
+
runs-on: ubuntu-latest
|
|
87
|
+
if: contains(github.event.issue.labels.*.name, 'phase:') || contains(github.event.label.name, 'phase:')
|
|
88
|
+
steps:
|
|
89
|
+
- name: Checkout
|
|
90
|
+
uses: actions/checkout@v4
|
|
91
|
+
|
|
92
|
+
- name: Phase Change Handler
|
|
93
|
+
run: |
|
|
94
|
+
echo "Phase change detected for issue #\${{ github.event.issue.number }}"
|
|
95
|
+
echo "New phase: \${{ github.event.label.name || 'phase removed' }}"
|
|
96
|
+
|
|
97
|
+
- name: Update Issue Status
|
|
98
|
+
if: contains(github.event.label.name, 'phase:')
|
|
99
|
+
run: |
|
|
100
|
+
gh issue edit \${{ github.event.issue.number }} --add-label "status:wip"
|
|
101
|
+
echo "Status updated to WIP for new phase"
|
|
102
|
+
`;
|
|
103
|
+
|
|
104
|
+
// Status change workflow
|
|
105
|
+
const statusChangeWorkflow = `name: Status Change Automation
|
|
106
|
+
|
|
107
|
+
on:
|
|
108
|
+
issues:
|
|
109
|
+
types: [labeled, unlabeled]
|
|
110
|
+
|
|
111
|
+
jobs:
|
|
112
|
+
status-change:
|
|
113
|
+
runs-on: ubuntu-latest
|
|
114
|
+
if: contains(github.event.issue.labels.*.name, 'status:') || contains(github.event.label.name, 'status:')
|
|
115
|
+
steps:
|
|
116
|
+
- name: Checkout
|
|
117
|
+
uses: actions/checkout@v4
|
|
118
|
+
|
|
119
|
+
- name: Status Change Handler
|
|
120
|
+
run: |
|
|
121
|
+
echo "Status change detected for issue #\${{ github.event.issue.number }}"
|
|
122
|
+
echo "New status: \${{ github.event.label.name || 'status removed' }}"
|
|
123
|
+
|
|
124
|
+
- name: Notify Team
|
|
125
|
+
if: contains(github.event.label.name, 'status:needs-review')
|
|
126
|
+
run: |
|
|
127
|
+
echo "Issue ready for review - notifying team"
|
|
128
|
+
`;
|
|
129
|
+
|
|
130
|
+
writeFile('.github/workflows/phase-change.yml', phaseChangeWorkflow);
|
|
131
|
+
writeFile('.github/workflows/status-change.yml', statusChangeWorkflow);
|
|
58
132
|
|
|
59
|
-
|
|
60
|
-
|
|
133
|
+
logSuccess('GitHub workflows created');
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function createAgentConfigs() {
|
|
137
|
+
// Cursor rules - only create if it doesn't exist
|
|
138
|
+
if (!fs.existsSync('.cursorrules')) {
|
|
139
|
+
const cursorRules = `# FRAIM Cursor Rules
|
|
140
|
+
|
|
141
|
+
## Core Rules (Always Apply)
|
|
142
|
+
- **ashley-architecture.mdc** - Follow the established architecture patterns
|
|
143
|
+
- **continuous-learning.mdc** - Always review retrospectives and RFCs before starting work
|
|
144
|
+
- **local-development.mdc** - Work locally, coordinate remotely
|
|
145
|
+
- **simplicity.mdc** - Keep it simple, don't over-engineer
|
|
146
|
+
- **software-development-lifecycle.mdc** - Follow the established SDLC
|
|
147
|
+
|
|
148
|
+
## Phase-Specific Rules (Manual Trigger Only)
|
|
149
|
+
- **prep.mdc** - Preparation phase rules
|
|
150
|
+
- **design.mdc** - Design phase rules
|
|
151
|
+
- **implement.mdc** - Implementation phase rules
|
|
152
|
+
- **test.mdc** - Testing phase rules
|
|
153
|
+
- **resolve.mdc** - Resolution phase rules
|
|
154
|
+
- **cursor-workflow.mdc** - Cursor-specific workflow rules
|
|
155
|
+
|
|
156
|
+
## Key Behavioral Requirements
|
|
157
|
+
- Always verify actions taken
|
|
158
|
+
- Never expect user verification
|
|
159
|
+
- Run tests to verify expected behavior
|
|
160
|
+
- Link work to issues with "Closes #<n>"
|
|
161
|
+
- Open Draft PRs early for review
|
|
162
|
+
|
|
163
|
+
## Project Structure Awareness
|
|
164
|
+
- Work in feature branches only
|
|
165
|
+
- Never push to master
|
|
166
|
+
- Use local file system for development
|
|
167
|
+
- Coordinate through GitHub issues and PRs
|
|
168
|
+
|
|
169
|
+
## Tool Usage Guidelines
|
|
170
|
+
- Use local file system for development work
|
|
171
|
+
- Use GitHub MCP for issue management
|
|
172
|
+
- Use local Git for version control
|
|
173
|
+
- Test locally before committing
|
|
174
|
+
|
|
175
|
+
## FRAIM Integration
|
|
176
|
+
- Follow the RIGOR methodology
|
|
177
|
+
- Maintain isolation between agents
|
|
178
|
+
- Use GitOps for coordination
|
|
179
|
+
- Enable observability through clear documentation
|
|
180
|
+
`;
|
|
181
|
+
|
|
182
|
+
writeFile('.cursorrules', cursorRules);
|
|
183
|
+
logSuccess('Cursor rules created');
|
|
184
|
+
} else {
|
|
185
|
+
logInfo('Cursor rules already exist, skipping');
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Claude rules - only create if it doesn't exist
|
|
189
|
+
if (!fs.existsSync('CLAUDE.md')) {
|
|
190
|
+
const claudeRules = `# FRAIM Claude Rules
|
|
191
|
+
|
|
192
|
+
## Always-On Rules
|
|
193
|
+
- **ashley-architecture.mdc** - Follow the established architecture patterns
|
|
194
|
+
- **continuous-learning.mdc** - Always review retrospectives and RFCs before starting work
|
|
195
|
+
|
|
196
|
+
## Phase-Specific Rules (Manual Trigger Only)
|
|
197
|
+
- **design.mdc** - Design phase rules
|
|
198
|
+
- **implement.mdc** - Implementation phase rules
|
|
199
|
+
- **test.mdc** - Testing phase rules
|
|
200
|
+
|
|
201
|
+
## Key Behavioral Requirements
|
|
202
|
+
- Always verify actions taken
|
|
203
|
+
- Never expect user verification
|
|
204
|
+
- Run tests to verify expected behavior
|
|
205
|
+
- Link work to issues with "Closes #<n>"
|
|
206
|
+
- Open Draft PRs early for review
|
|
207
|
+
|
|
208
|
+
## Project Structure Awareness
|
|
209
|
+
- Work in feature branches only
|
|
210
|
+
- Never push to master
|
|
211
|
+
- Use local file system for development
|
|
212
|
+
- Coordinate through GitHub issues and PRs
|
|
213
|
+
|
|
214
|
+
## Tool Usage Guidelines
|
|
215
|
+
- Use local file system for development work
|
|
216
|
+
- Use GitHub MCP for issue management
|
|
217
|
+
- Use local Git for version control
|
|
218
|
+
- Test locally before committing
|
|
219
|
+
|
|
220
|
+
## FRAIM Integration
|
|
221
|
+
- Follow the RIGOR methodology
|
|
222
|
+
- Maintain isolation between agents
|
|
223
|
+
- Use GitOps for coordination
|
|
224
|
+
- Enable observability through clear documentation
|
|
225
|
+
`;
|
|
226
|
+
|
|
227
|
+
writeFile('CLAUDE.md', claudeRules);
|
|
228
|
+
logSuccess('Claude rules created');
|
|
229
|
+
} else {
|
|
230
|
+
logInfo('Claude rules already exist, skipping');
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// Windsurf rules - only create if it doesn't exist
|
|
234
|
+
if (!fs.existsSync('.windsurfrules')) {
|
|
235
|
+
const windsurfRules = `# FRAIM Windsurf Rules
|
|
236
|
+
|
|
237
|
+
## Core Rules (Always Apply)
|
|
238
|
+
- **ashley-architecture.mdc** - Follow the established architecture patterns
|
|
239
|
+
- **continuous-learning.mdc** - Always review retrospectives and RFCs before starting work
|
|
240
|
+
- **local-development.mdc** - Work locally, coordinate remotely
|
|
241
|
+
- **simplicity.mdc** - Keep it simple, don't over-engineer
|
|
242
|
+
- **issue-resolution-process.mdc** - Follow the established issue resolution process
|
|
243
|
+
|
|
244
|
+
## Key Behavioral Requirements
|
|
245
|
+
- Always verify actions taken
|
|
246
|
+
- Never expect user verification
|
|
247
|
+
- Run tests to verify expected behavior
|
|
248
|
+
- Link work to issues with "Closes #<n>"
|
|
249
|
+
- Open Draft PRs early for review
|
|
250
|
+
|
|
251
|
+
## Project Structure Awareness
|
|
252
|
+
- Work in feature branches only
|
|
253
|
+
- Never push to master
|
|
254
|
+
- Use local file system for development
|
|
255
|
+
- Coordinate through GitHub issues and PRs
|
|
256
|
+
|
|
257
|
+
## Tool Usage Guidelines
|
|
258
|
+
- Use local file system for development work
|
|
259
|
+
- Use GitHub MCP for issue management
|
|
260
|
+
- Use local Git for version control
|
|
261
|
+
- Test locally before committing
|
|
262
|
+
|
|
263
|
+
## Architecture and Optimization Principles
|
|
264
|
+
- Follow established patterns
|
|
265
|
+
- Optimize for performance and maintainability
|
|
266
|
+
- Document architectural decisions
|
|
267
|
+
- Consider scalability and security
|
|
268
|
+
|
|
269
|
+
## Your Role in FRAIM
|
|
270
|
+
- Provide technical expertise and optimization
|
|
271
|
+
- Maintain code quality and standards
|
|
272
|
+
- Ensure architectural consistency
|
|
273
|
+
- Support other agents with technical guidance
|
|
274
|
+
`;
|
|
275
|
+
|
|
276
|
+
writeFile('.windsurfrules', windsurfRules);
|
|
277
|
+
logSuccess('Windsurf rules created');
|
|
278
|
+
} else {
|
|
279
|
+
logInfo('Windsurf rules already exist, skipping');
|
|
61
280
|
}
|
|
62
|
-
|
|
63
|
-
console.log('🎯 Ready to become an AI manager?');
|
|
64
|
-
console.log(' Run: npx @fraim/framework init # For full setup');
|
|
65
|
-
console.log(' Or: npx @fraim/framework wizard # For interactive setup');
|
|
66
281
|
}
|
|
67
282
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
283
|
+
function createFRAIMConfig() {
|
|
284
|
+
const fraimConfig = {
|
|
285
|
+
version: "1.0.0",
|
|
286
|
+
framework: "FRAIM",
|
|
287
|
+
description: "Framework for Rigor-based AI Management",
|
|
288
|
+
created: new Date().toISOString(),
|
|
289
|
+
features: [
|
|
290
|
+
"GitHub label automation",
|
|
291
|
+
"AI agent coordination",
|
|
292
|
+
"Phase-based workflows",
|
|
293
|
+
"RIGOR methodology implementation"
|
|
294
|
+
],
|
|
295
|
+
agents: {
|
|
296
|
+
cursor: ".cursorrules",
|
|
297
|
+
claude: "CLAUDE.md",
|
|
298
|
+
windsurf: ".windsurfrules"
|
|
299
|
+
},
|
|
300
|
+
workflows: [
|
|
301
|
+
".github/workflows/phase-change.yml",
|
|
302
|
+
".github/workflows/status-change.yml"
|
|
303
|
+
]
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
writeFile('fraim-config.json', JSON.stringify(fraimConfig, null, 2));
|
|
307
|
+
logSuccess('FRAIM configuration created');
|
|
86
308
|
}
|
|
309
|
+
|
|
310
|
+
function runSetup() {
|
|
311
|
+
logHeader('🚀 FRAIM Setup Wizard');
|
|
312
|
+
log('Setting up FRAIM in current repository...\n');
|
|
313
|
+
|
|
314
|
+
try {
|
|
315
|
+
// Create only essential directory structure
|
|
316
|
+
ensureDirectory('.github/workflows');
|
|
317
|
+
|
|
318
|
+
// Create only essential components
|
|
319
|
+
createGitHubLabels();
|
|
320
|
+
createGitHubWorkflows();
|
|
321
|
+
createAgentConfigs();
|
|
322
|
+
createFRAIMConfig();
|
|
323
|
+
|
|
324
|
+
logHeader('🎉 Setup Complete!');
|
|
325
|
+
logSuccess('FRAIM has been successfully set up in your repository!');
|
|
326
|
+
logInfo('Next steps:');
|
|
327
|
+
logInfo('1. Commit and push these files to GitHub');
|
|
328
|
+
logInfo('2. Import the GitHub labels from .github/labels.json');
|
|
329
|
+
logInfo('3. Create your first issue with phase labels');
|
|
330
|
+
logInfo('4. Start coordinating your AI agents!');
|
|
331
|
+
|
|
332
|
+
logInfo('\n📚 Learn more about FRAIM:');
|
|
333
|
+
logInfo('https://github.com/mathursrus/Ashley-Calendar-AI/tree/master/FRAIM');
|
|
334
|
+
|
|
335
|
+
logInfo('\n🧠 Learn the RIGOR methodology:');
|
|
336
|
+
logInfo('npx fraim-framework rigor');
|
|
337
|
+
|
|
338
|
+
} catch (error) {
|
|
339
|
+
logError(`Setup failed: ${error.message}`);
|
|
340
|
+
process.exit(1);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
// Run setup if this script is executed directly
|
|
345
|
+
if (require.main === module) {
|
|
346
|
+
runSetup();
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
module.exports = { runSetup };
|