fraim-framework 1.0.3 → 1.0.5

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 (3) hide show
  1. package/bin/fraim.js +17 -9
  2. package/package.json +1 -1
  3. package/setup.js +193 -185
package/bin/fraim.js CHANGED
@@ -83,7 +83,20 @@ async function runSetup() {
83
83
  }
84
84
  }
85
85
 
86
- function main() {
86
+ async function runWizard() {
87
+ try {
88
+ // Import and run the wizard function
89
+ const { runWizard: wizardFunction } = require('../setup.js');
90
+ await wizardFunction();
91
+ } catch (error) {
92
+ console.error('āŒ Failed to run wizard:', error.message);
93
+ console.log('\nšŸ’” Try running the setup script directly:');
94
+ console.log(' node setup.js');
95
+ process.exit(1);
96
+ }
97
+ }
98
+
99
+ async function main() {
87
100
  const args = process.argv.slice(2);
88
101
 
89
102
  if (args.length === 0 || args.includes('--help') || args.includes('-h')) {
@@ -99,20 +112,15 @@ function main() {
99
112
  if (args.includes('init') || args.includes('setup')) {
100
113
  console.log(banner);
101
114
  console.log('šŸš€ Setting up FRAIM in current repository...\n');
102
- runSetup();
115
+ await runSetup();
103
116
  return;
104
117
  }
105
118
 
106
119
  if (args.includes('wizard')) {
107
120
  console.log(banner);
108
121
  console.log('šŸ”® FRAIM Interactive Setup Wizard\n');
109
- console.log('This wizard will guide you through:');
110
- console.log(' 1. Repository configuration');
111
- console.log(' 2. AI agent setup (with tested rules)');
112
- console.log(' 3. Workflow customization');
113
- console.log(' 4. Team member onboarding\n');
114
- console.log('šŸ’” Starting setup wizard...\n');
115
- runSetup();
122
+ console.log('Starting interactive wizard...\n');
123
+ await runWizard();
116
124
  return;
117
125
  }
118
126
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fraim-framework",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "FRAIM: Framework for Rigor-based AI Management - Where humans become AI managers through rigorous methodology",
5
5
  "main": "index.js",
6
6
  "bin": {
package/setup.js CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  const fs = require('fs');
4
4
  const path = require('path');
5
+ const { execSync } = require('child_process');
6
+ const readline = require('readline');
5
7
 
6
8
  // Colors for console output
7
9
  const colors = {
@@ -40,6 +42,10 @@ function logHeader(message) {
40
42
  log('─'.repeat(message.length));
41
43
  }
42
44
 
45
+ function logStep(message) {
46
+ log(`\n${colors.bright}${colors.magenta}${message}${colors.reset}`);
47
+ }
48
+
43
49
  function ensureDirectory(dirPath) {
44
50
  if (!fs.existsSync(dirPath)) {
45
51
  fs.mkdirSync(dirPath, { recursive: true });
@@ -53,141 +59,73 @@ function writeFile(filePath, content) {
53
59
  logSuccess(`Created file: ${filePath}`);
54
60
  }
55
61
 
56
- function createAgentStructure() {
57
- // Create the proper agent directory structure
58
- ensureDirectory('agents/cursor/rules');
59
- ensureDirectory('agents/claude/rules');
60
- ensureDirectory('agents/windsurf/rules');
61
-
62
- // Create .cursorrules that references modular rules
63
- const cursorRules = `# FRAIM Cursor Rules
64
-
65
- ## Core Rules (Always Apply)
66
- - **ashley-architecture.mdc** - Follow the established architecture patterns
67
- - **continuous-learning.mdc** - Always review retrospectives and RFCs before starting work
68
- - **local-development.mdc** - Work locally, coordinate remotely
69
- - **simplicity.mdc** - Keep it simple, don't over-engineer
70
- - **software-development-lifecycle.mdc** - Follow the established SDLC
71
-
72
- ## Phase-Specific Rules (Manual Trigger Only)
73
- - **prep.mdc** - Preparation phase rules
74
- - **design.mdc** - Design phase rules
75
- - **implement.mdc** - Implementation phase rules
76
- - **test.mdc** - Testing phase rules
77
- - **resolve.mdc** - Resolution phase rules
78
- - **cursor-workflow.mdc** - Cursor-specific workflow rules
79
-
80
- ## Key Behavioral Requirements
81
- - Always verify actions taken
82
- - Never expect user verification
83
- - Run tests to verify expected behavior
84
- - Link work to issues with "Closes #<n>"
85
- - Open Draft PRs early for review
86
-
87
- ## Project Structure Awareness
88
- - Work in feature branches only
89
- - Never push to master
90
- - Use local file system for development
91
- - Coordinate through GitHub issues and PRs
92
-
93
- ## Tool Usage Guidelines
94
- - Use local file system for development work
95
- - Use GitHub MCP for issue management
96
- - Use local Git for version control
97
- - Test locally before committing
98
-
99
- ## FRAIM Integration
100
- - Follow the RIGOR methodology
101
- - Maintain isolation between agents
102
- - Use GitOps for coordination
103
- - Enable observability through clear documentation
104
- `;
62
+ function copyDirectory(src, dest) {
63
+ if (!fs.existsSync(dest)) {
64
+ fs.mkdirSync(dest, { recursive: true });
65
+ }
66
+
67
+ const items = fs.readdirSync(src);
68
+ for (const item of items) {
69
+ const srcPath = path.join(src, item);
70
+ const destPath = path.join(dest, item);
71
+
72
+ if (fs.statSync(srcPath).isDirectory()) {
73
+ copyDirectory(srcPath, destPath);
74
+ } else {
75
+ fs.copyFileSync(srcPath, destPath);
76
+ logSuccess(`Copied: ${destPath}`);
77
+ }
78
+ }
79
+ }
105
80
 
106
- // Create .windsurfrules that references modular rules
107
- const windsurfRules = `# FRAIM Windsurf Rules
108
-
109
- ## Core Rules (Always Apply)
110
- - **ashley-architecture.mdc** - Follow the established architecture patterns
111
- - **continuous-learning.mdc** - Always review retrospectives and RFCs before starting work
112
- - **local-development.mdc** - Work locally, coordinate remotely
113
- - **simplicity.mdc** - Keep it simple, don't over-engineer
114
- - **issue-resolution-process.mdc** - Follow the established issue resolution process
115
-
116
- ## Key Behavioral Requirements
117
- - Always verify actions taken
118
- - Never expect user verification
119
- - Run tests to verify expected behavior
120
- - Link work to issues with "Closes #<n>"
121
- - Open Draft PRs early for review
122
-
123
- ## Project Structure Awareness
124
- - Work in feature branches only
125
- - Never push to master
126
- - Use local file system for development
127
- - Coordinate through GitHub issues and PRs
128
-
129
- ## Tool Usage Guidelines
130
- - Use local file system for development work
131
- - Use GitHub MCP for issue management
132
- - Use local Git for version control
133
- - Test locally before committing
134
-
135
- ## Architecture and Optimization Principles
136
- - Follow established patterns
137
- - Optimize for performance and maintainability
138
- - Document architectural decisions
139
- - Consider scalability and security
140
-
141
- ## Your Role in FRAIM
142
- - Provide technical expertise and optimization
143
- - Maintain code quality and standards
144
- - Ensure architectural consistency
145
- - Support other agents with technical guidance
146
- `;
81
+ function askQuestion(question, defaultValue = 'y') {
82
+ return new Promise((resolve) => {
83
+ const rl = readline.createInterface({
84
+ input: process.stdin,
85
+ output: process.stdout
86
+ });
87
+
88
+ const defaultText = defaultValue ? ` (${defaultValue})` : '';
89
+ rl.question(`${question}${defaultText}: `, (answer) => {
90
+ rl.close();
91
+ const finalAnswer = answer.trim() || defaultValue;
92
+ resolve(finalAnswer.toLowerCase());
93
+ });
94
+ });
95
+ }
147
96
 
148
- // Create CLAUDE.md that references modular rules
149
- const claudeRules = `# FRAIM Claude Rules
150
-
151
- ## Always-On Rules
152
- - **ashley-architecture.mdc** - Follow the established architecture patterns
153
- - **continuous-learning.mdc** - Always review retrospectives and RFCs before starting work
154
-
155
- ## Phase-Specific Rules (Manual Trigger Only)
156
- - **design.mdc** - Design phase rules
157
- - **implement.mdc** - Implementation phase rules
158
- - **test.mdc** - Testing phase rules
159
-
160
- ## Key Behavioral Requirements
161
- - Always verify actions taken
162
- - Never expect user verification
163
- - Run tests to verify expected behavior
164
- - Link work to issues with "Closes #<n>"
165
- - Open Draft PRs early for review
166
-
167
- ## Project Structure Awareness
168
- - Work in feature branches only
169
- - Never push to master
170
- - Use local file system for development
171
- - Coordinate through GitHub issues and PRs
172
-
173
- ## Tool Usage Guidelines
174
- - Use local file system for development work
175
- - Use GitHub MCP for issue management
176
- - Use local Git for version control
177
- - Test locally before committing
178
-
179
- ## FRAIM Integration
180
- - Follow the RIGOR methodology
181
- - Maintain isolation between agents
182
- - Use GitOps for coordination
183
- - Enable observability through clear documentation
184
- `;
97
+ function createGitHubLabels() {
98
+ const labels = [
99
+ { name: 'phase:design', color: '0e8a16', description: 'Design phase - RFC creation and review' },
100
+ { name: 'phase:impl', color: '1d76db', description: 'Implementation phase - coding and testing' },
101
+ { name: 'phase:tests', color: 'fef2c0', description: 'Testing phase - validation and QA' },
102
+ { name: 'status:wip', color: 'fbca04', description: 'Work in progress' },
103
+ { name: 'status:needs-review', color: 'd93f0b', description: 'Ready for review' },
104
+ { name: 'status:complete', color: '0e8a16', description: 'Completed and approved' },
105
+ { name: 'status:approved', color: '0e8a16', description: 'Approved and ready to merge' },
106
+ { name: 'status:changes-requested', color: 'd93f0b', description: 'Changes requested in review' },
107
+ { name: 'ai-agent:cursor', color: '5319e7', description: 'Assigned to Cursor AI agent' },
108
+ { name: 'ai-agent:claude', color: 'c2e0c6', description: 'Assigned to Claude AI agent' },
109
+ { name: 'ai-agent:windsurf', color: 'bfdadc', description: 'Assigned to Windsurf AI agent' }
110
+ ];
185
111
 
186
- writeFile('.cursorrules', cursorRules);
187
- writeFile('.windsurfrules', windsurfRules);
188
- writeFile('CLAUDE.md', claudeRules);
112
+ logInfo('Creating GitHub labels...');
189
113
 
190
- logSuccess('AI agent configuration files created');
114
+ for (const label of labels) {
115
+ try {
116
+ const command = `gh label create "${label.name}" --color "${label.color}" --description "${label.description}"`;
117
+ execSync(command, { stdio: 'pipe' });
118
+ logSuccess(`Created label: ${label.name}`);
119
+ } catch (error) {
120
+ if (error.message.includes('already exists')) {
121
+ logInfo(`Label already exists: ${label.name}`);
122
+ } else {
123
+ logWarning(`Failed to create label ${label.name}: ${error.message}`);
124
+ }
125
+ }
126
+ }
127
+
128
+ logSuccess('GitHub labels created');
191
129
  }
192
130
 
193
131
  function createGitHubWorkflows() {
@@ -285,76 +223,146 @@ jobs:
285
223
  logSuccess('GitHub workflows created');
286
224
  }
287
225
 
288
- function createGitHubLabels() {
289
- const labels = [
290
- { name: 'phase:design', color: '0e8a16', description: 'Design phase - RFC creation and review' },
291
- { name: 'phase:impl', color: '1d76db', description: 'Implementation phase - coding and testing' },
292
- { name: 'phase:tests', color: 'fef2c0', description: 'Testing phase - validation and QA' },
293
- { name: 'status:wip', color: 'fbca04', description: 'Work in progress' },
294
- { name: 'status:needs-review', color: 'd93f0b', description: 'Ready for review' },
295
- { name: 'status:complete', color: '0e8a16', description: 'Completed and approved' },
296
- { name: 'status:approved', color: '0e8a16', description: 'Approved and ready to merge' },
297
- { name: 'status:changes-requested', color: 'd93f0b', description: 'Changes requested in review' },
298
- { name: 'ai-agent:cursor', color: '5319e7', description: 'Assigned to Cursor AI agent' },
299
- { name: 'ai-agent:claude', color: 'c2e0c6', description: 'Assigned to Claude AI agent' },
300
- { name: 'ai-agent:windsurf', color: 'bfdadc', description: 'Assigned to Windsurf AI agent' }
301
- ];
226
+ function createAgentFolders() {
227
+ // Create .cursor folder at top level with all contents
228
+ if (fs.existsSync('agents/cursor')) {
229
+ copyDirectory('agents/cursor', '.cursor');
230
+ logSuccess('Created .cursor folder with all contents');
231
+ } else {
232
+ logWarning('agents/cursor directory not found, skipping .cursor creation');
233
+ }
302
234
 
303
- const labelsContent = JSON.stringify(labels, null, 2);
304
- writeFile('.github/labels.json', labelsContent);
305
-
306
- logInfo('GitHub labels configuration created');
307
- logInfo('You can import these labels using GitHub CLI or the web interface');
308
- logInfo('Or use the GitHub web interface: Settings > Labels > Import labels');
235
+ // Create .windsurf folder at top level with all contents
236
+ if (fs.existsSync('agents/windsurf')) {
237
+ copyDirectory('agents/windsurf', '.windsurf');
238
+ logSuccess('Created .windsurf folder with all contents');
239
+ } else {
240
+ logWarning('agents/windsurf directory not found, skipping .windsurf creation');
241
+ }
242
+
243
+ // Create CLAUDE.md at top level
244
+ if (fs.existsSync('agents/claude/CLAUDE.md')) {
245
+ const claudeContent = fs.readFileSync('agents/claude/CLAUDE.md', 'utf8');
246
+ writeFile('CLAUDE.md', claudeContent);
247
+ logSuccess('Created CLAUDE.md at top level');
248
+ } else {
249
+ logWarning('agents/claude/CLAUDE.md not found, skipping CLAUDE.md creation');
250
+ }
309
251
  }
310
252
 
311
- function createFRAIMConfig() {
312
- const fraimConfig = {
313
- version: "1.0.0",
314
- framework: "FRAIM",
315
- description: "Framework for Rigor-based AI Management",
316
- created: new Date().toISOString(),
317
- features: [
318
- "GitHub label automation",
319
- "AI agent coordination",
320
- "Phase-based workflows",
321
- "RIGOR methodology implementation"
322
- ],
323
- agents: {
324
- cursor: ".cursorrules",
325
- claude: "CLAUDE.md",
326
- windsurf: ".windsurfrules"
327
- },
328
- workflows: [
329
- ".github/workflows/phase-change.yml",
330
- ".github/workflows/status-change.yml",
331
- ".github/workflows/sync-on-pr-review.yml"
332
- ]
333
- };
334
-
335
- writeFile('fraim-config.json', JSON.stringify(fraimConfig, null, 2));
336
- logSuccess('FRAIM configuration created');
253
+ async function runWizard() {
254
+ logHeader('šŸ”® FRAIM Interactive Setup Wizard');
255
+ log('Welcome to the FRAIM setup wizard! I\'ll guide you through each step.\n');
256
+
257
+ try {
258
+ // Check prerequisites
259
+ logStep('Step 1: Checking Prerequisites');
260
+
261
+ // Check if gh CLI is available
262
+ try {
263
+ execSync('gh --version', { stdio: 'pipe' });
264
+ logSuccess('GitHub CLI (gh) is available');
265
+ } catch (error) {
266
+ logError('GitHub CLI (gh) is not installed or not available');
267
+ logInfo('Please install GitHub CLI: https://cli.github.com/');
268
+ return;
269
+ }
270
+
271
+ // Check if we're in a git repository
272
+ try {
273
+ execSync('git rev-parse --git-dir', { stdio: 'pipe' });
274
+ logSuccess('Running in a git repository');
275
+ } catch (error) {
276
+ logError('Not in a git repository');
277
+ logInfo('Please run this command from within a git repository');
278
+ return;
279
+ }
280
+
281
+ // Step 2: AI Agent Setup
282
+ logStep('Step 2: AI Agent Configuration');
283
+ const setupAgents = await askQuestion('Would you like to set up AI agent configurations (.cursor, .windsurf, CLAUDE.md)?', 'y');
284
+
285
+ if (setupAgents === 'y' || setupAgents === 'yes') {
286
+ createAgentFolders();
287
+ } else {
288
+ logInfo('Skipping AI agent setup');
289
+ }
290
+
291
+ // Step 3: GitHub Workflows
292
+ logStep('Step 3: GitHub Workflows');
293
+ const setupWorkflows = await askQuestion('Would you like to set up GitHub workflows for automation?', 'y');
294
+
295
+ if (setupWorkflows === 'y' || setupWorkflows === 'yes') {
296
+ ensureDirectory('.github/workflows');
297
+ createGitHubWorkflows();
298
+ } else {
299
+ logInfo('Skipping GitHub workflow setup');
300
+ }
301
+
302
+ // Step 4: GitHub Labels
303
+ logStep('Step 4: GitHub Labels');
304
+ const setupLabels = await askQuestion('Would you like to create GitHub labels for FRAIM?', 'y');
305
+
306
+ if (setupLabels === 'y' || setupLabels === 'yes') {
307
+ createGitHubLabels();
308
+ } else {
309
+ logInfo('Skipping GitHub label setup');
310
+ }
311
+
312
+ // Step 5: Summary
313
+ logStep('Step 5: Setup Summary');
314
+ logHeader('šŸŽ‰ Setup Complete!');
315
+ logSuccess('FRAIM has been successfully set up in your repository!');
316
+ logInfo('Next steps:');
317
+ logInfo('1. Commit and push these files to GitHub');
318
+ logInfo('2. Create your first issue with phase labels');
319
+ logInfo('3. Start coordinating your AI agents!');
320
+
321
+ logInfo('\nšŸ“š Learn more about FRAIM:');
322
+ logInfo('https://github.com/mathursrus/Ashley-Calendar-AI/tree/master/FRAIM');
323
+
324
+ logInfo('\n🧠 Learn the RIGOR methodology:');
325
+ logInfo('npx fraim-framework rigor');
326
+
327
+ } catch (error) {
328
+ logError(`Wizard failed: ${error.message}`);
329
+ process.exit(1);
330
+ }
337
331
  }
338
332
 
339
333
  function runSetup() {
340
- logHeader('šŸš€ FRAIM Setup Wizard');
334
+ logHeader('šŸš€ FRAIM Quick Setup');
341
335
  log('Setting up FRAIM in current repository...\n');
342
336
 
343
337
  try {
344
- // Create only essential directory structure
338
+ // Check prerequisites
339
+ try {
340
+ execSync('gh --version', { stdio: 'pipe' });
341
+ } catch (error) {
342
+ logError('GitHub CLI (gh) is not installed or not available');
343
+ logInfo('Please install GitHub CLI: https://cli.github.com/');
344
+ process.exit(1);
345
+ }
346
+
347
+ try {
348
+ execSync('git rev-parse --git-dir', { stdio: 'pipe' });
349
+ } catch (error) {
350
+ logError('Not in a git repository');
351
+ logInfo('Please run this command from within a git repository');
352
+ process.exit(1);
353
+ }
354
+
355
+ // Create everything at once
345
356
  ensureDirectory('.github/workflows');
346
-
347
- // Create all components
348
- createAgentStructure();
357
+ createAgentFolders();
349
358
  createGitHubWorkflows();
350
359
  createGitHubLabels();
351
- createFRAIMConfig();
352
360
 
353
361
  logHeader('šŸŽ‰ Setup Complete!');
354
362
  logSuccess('FRAIM has been successfully set up in your repository!');
355
363
  logInfo('Next steps:');
356
364
  logInfo('1. Commit and push these files to GitHub');
357
- logInfo('2. Import the GitHub labels from .github/labels.json');
365
+ logInfo('2. The GitHub labels have been created automatically');
358
366
  logInfo('3. Create your first issue with phase labels');
359
367
  logInfo('4. Start coordinating your AI agents!');
360
368
 
@@ -375,4 +383,4 @@ if (require.main === module) {
375
383
  runSetup();
376
384
  }
377
385
 
378
- module.exports = { runSetup };
386
+ module.exports = { runSetup, runWizard };