s9n-devops-agent 2.0.13 → 2.0.18-dev.0
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/House_Rules_Contracts/API_CONTRACT.md +612 -0
- package/House_Rules_Contracts/DATABASE_SCHEMA_CONTRACT.md +373 -0
- package/House_Rules_Contracts/DEVOPS_AGENT_INSTRUCTIONS.md +743 -0
- package/House_Rules_Contracts/FEATURES_CONTRACT.md +655 -0
- package/House_Rules_Contracts/INFRA_CONTRACT.md +638 -0
- package/House_Rules_Contracts/README.md +671 -0
- package/House_Rules_Contracts/SQL_CONTRACT.json +346 -0
- package/House_Rules_Contracts/THIRD_PARTY_INTEGRATIONS.md +604 -0
- package/bin/cs-devops-agent +20 -2
- package/houserules.md +1412 -0
- package/houserules_structured.md +1442 -0
- package/package.json +6 -2
- package/scripts/generate-ai-commit.js +135 -0
- package/scripts/local-install.sh +42 -0
- package/src/agent-chat.js +457 -0
- package/src/credentials-manager.js +1 -1
- package/src/cs-devops-agent-worker.js +84 -4
- package/src/house-rules-manager.js +4 -14
- package/src/instruction-formatter.js +9 -1
- package/src/session-coordinator.js +170 -15
- package/src/setup-cs-devops-agent.js +214 -236
- package/src/worktree-manager.js +2 -1
- package/start-devops-session.sh +9 -2
|
@@ -146,10 +146,6 @@ Standard folders help organize your code, tests, and documentation.
|
|
|
146
146
|
This structure is compatible with the DevOps Agent's automation tools.
|
|
147
147
|
`);
|
|
148
148
|
|
|
149
|
-
// We can't use await here because this function is synchronous in the flow,
|
|
150
|
-
// but the main flow is async. We should probably make this async or use prompt from ui-utils.
|
|
151
|
-
// However, looking at the code structure, helper functions are sync or async.
|
|
152
|
-
// Let's return the missing folders and handle the prompt in the main function or make this async.
|
|
153
149
|
return missingFolders;
|
|
154
150
|
}
|
|
155
151
|
|
|
@@ -271,7 +267,7 @@ async function setupNpmPackages(projectRoot) {
|
|
|
271
267
|
return packageJson;
|
|
272
268
|
}
|
|
273
269
|
|
|
274
|
-
function setupVSCodeSettings(projectRoot, initials) {
|
|
270
|
+
function setupVSCodeSettings(projectRoot, initials, agentName = 'Claude') {
|
|
275
271
|
log.header();
|
|
276
272
|
log.title('⚙️ Setting up VS Code Configuration');
|
|
277
273
|
|
|
@@ -317,8 +313,8 @@ function setupVSCodeSettings(projectRoot, initials) {
|
|
|
317
313
|
|
|
318
314
|
// Add file associations for commit messages
|
|
319
315
|
settings['files.associations'] = settings['files.associations'] || {};
|
|
320
|
-
settings['files.associations'][
|
|
321
|
-
settings['files.associations'][
|
|
316
|
+
settings['files.associations'][`.${agentName.toLowerCase()}-commit-msg`] = 'markdown';
|
|
317
|
+
settings['files.associations'][`${agentName.toUpperCase()}_CHANGELOG.md`] = 'markdown';
|
|
322
318
|
|
|
323
319
|
// Add file watchers
|
|
324
320
|
settings['files.watcherExclude'] = settings['files.watcherExclude'] || {};
|
|
@@ -331,7 +327,7 @@ function setupVSCodeSettings(projectRoot, initials) {
|
|
|
331
327
|
return settings;
|
|
332
328
|
}
|
|
333
329
|
|
|
334
|
-
function setupVSCodeTasks(projectRoot, initials) {
|
|
330
|
+
function setupVSCodeTasks(projectRoot, initials, agentName = 'Claude') {
|
|
335
331
|
log.title('📋 Setting up VS Code Tasks');
|
|
336
332
|
|
|
337
333
|
const vscodeDir = path.join(projectRoot, '.vscode');
|
|
@@ -395,7 +391,7 @@ function setupVSCodeTasks(projectRoot, initials) {
|
|
|
395
391
|
{
|
|
396
392
|
label: '📝 Create Commit Message',
|
|
397
393
|
type: 'shell',
|
|
398
|
-
command:
|
|
394
|
+
command: `echo "feat(): " > .${agentName.toLowerCase()}-commit-msg && code .${agentName.toLowerCase()}-commit-msg`,
|
|
399
395
|
problemMatcher: [],
|
|
400
396
|
presentation: {
|
|
401
397
|
echo: false,
|
|
@@ -424,25 +420,25 @@ function setupVSCodeTasks(projectRoot, initials) {
|
|
|
424
420
|
return tasks;
|
|
425
421
|
}
|
|
426
422
|
|
|
427
|
-
function setupCommitFiles(projectRoot, initials) {
|
|
423
|
+
function setupCommitFiles(projectRoot, initials, agentName = 'Claude') {
|
|
428
424
|
log.header();
|
|
429
425
|
log.title('📝 Setting up Commit Message Files');
|
|
430
426
|
|
|
431
|
-
// Setup
|
|
432
|
-
const commitMsgPath = path.join(projectRoot,
|
|
427
|
+
// Setup commit message file (dynamic name)
|
|
428
|
+
const commitMsgPath = path.join(projectRoot, `.${agentName.toLowerCase()}-commit-msg`);
|
|
433
429
|
if (!fs.existsSync(commitMsgPath)) {
|
|
434
430
|
fs.writeFileSync(commitMsgPath, '');
|
|
435
|
-
log.success(
|
|
431
|
+
log.success(`Created .${agentName.toLowerCase()}-commit-msg file`);
|
|
436
432
|
} else {
|
|
437
|
-
log.info(
|
|
433
|
+
log.info(`.${agentName.toLowerCase()}-commit-msg already exists`);
|
|
438
434
|
}
|
|
439
435
|
|
|
440
|
-
// Setup
|
|
441
|
-
const changelogPath = path.join(projectRoot,
|
|
436
|
+
// Setup CHANGELOG (dynamic name)
|
|
437
|
+
const changelogPath = path.join(projectRoot, `${agentName.toUpperCase()}_CHANGELOG.md`);
|
|
442
438
|
if (!fs.existsSync(changelogPath)) {
|
|
443
|
-
const initialContent = `#
|
|
439
|
+
const initialContent = `# ${agentName} AI Assistant Changelog
|
|
444
440
|
|
|
445
|
-
This file tracks all changes made by
|
|
441
|
+
This file tracks all changes made by ${agentName} AI assistant to this codebase.
|
|
446
442
|
Each entry includes a timestamp, commit type, and detailed description.
|
|
447
443
|
|
|
448
444
|
Developer: ${initials.toUpperCase()}
|
|
@@ -455,9 +451,9 @@ Initialized: ${new Date().toISOString()}
|
|
|
455
451
|
|
|
456
452
|
`;
|
|
457
453
|
fs.writeFileSync(changelogPath, initialContent);
|
|
458
|
-
log.success(
|
|
454
|
+
log.success(`Created ${agentName.toUpperCase()}_CHANGELOG.md`);
|
|
459
455
|
} else {
|
|
460
|
-
log.info(
|
|
456
|
+
log.info(`${agentName.toUpperCase()}_CHANGELOG.md already exists`);
|
|
461
457
|
}
|
|
462
458
|
|
|
463
459
|
// Setup Documentation/infrastructure.md
|
|
@@ -500,10 +496,10 @@ Each entry should follow this format:
|
|
|
500
496
|
log.info('Documentation/infrastructure.md already exists');
|
|
501
497
|
}
|
|
502
498
|
|
|
503
|
-
// Setup
|
|
504
|
-
const
|
|
505
|
-
if (!fs.existsSync(
|
|
506
|
-
const
|
|
499
|
+
// Setup Agent Rules (dynamic name)
|
|
500
|
+
const agentMdPath = path.join(projectRoot, `${agentName.toUpperCase()}.md`);
|
|
501
|
+
if (!fs.existsSync(agentMdPath)) {
|
|
502
|
+
const agentRules = `# House Rules for ${agentName}
|
|
507
503
|
|
|
508
504
|
## Developer Information
|
|
509
505
|
- Developer Initials: ${initials.toUpperCase()}
|
|
@@ -514,9 +510,9 @@ Each entry should follow this format:
|
|
|
514
510
|
## Commit Policy
|
|
515
511
|
After applying any file edits, you must document changes in two places:
|
|
516
512
|
|
|
517
|
-
### 1. Single Commit Message File (
|
|
513
|
+
### 1. Single Commit Message File (\`.${agentName.toLowerCase()}-commit-msg\`)
|
|
518
514
|
|
|
519
|
-
**Location**:
|
|
515
|
+
**Location**: \`/.${agentName.toLowerCase()}-commit-msg\`
|
|
520
516
|
**Action**: APPEND to this file (don't overwrite) - the worker will clean it
|
|
521
517
|
**Format**:
|
|
522
518
|
\`\`\`
|
|
@@ -543,8 +539,8 @@ type(scope): subject line describing the change (max 72 characters)
|
|
|
543
539
|
- Keep the subject line under 72 characters
|
|
544
540
|
- Use present tense ("add" not "added", "fix" not "fixed")
|
|
545
541
|
|
|
546
|
-
### 2. Changelog Documentation (
|
|
547
|
-
**Location**:
|
|
542
|
+
### 2. Changelog Documentation (\`${agentName.toUpperCase()}_CHANGELOG.md\`)
|
|
543
|
+
**Location**: \`/${agentName.toUpperCase()}_CHANGELOG.md\`
|
|
548
544
|
**Action**: APPEND a new section (don't overwrite)
|
|
549
545
|
**Format**:
|
|
550
546
|
\`\`\`markdown
|
|
@@ -561,7 +557,7 @@ type(scope): exact same subject line from commit message
|
|
|
561
557
|
|
|
562
558
|
### Example of Both Files
|
|
563
559
|
|
|
564
|
-
|
|
560
|
+
**.${agentName.toLowerCase()}-commit-msg** (append new entries):
|
|
565
561
|
\`\`\`
|
|
566
562
|
feat(api): add webhook support for real-time notifications
|
|
567
563
|
|
|
@@ -570,7 +566,7 @@ feat(api): add webhook support for real-time notifications
|
|
|
570
566
|
- Integrated webhook triggers into event processing pipeline
|
|
571
567
|
\`\`\`
|
|
572
568
|
|
|
573
|
-
|
|
569
|
+
**${agentName.toUpperCase()}_CHANGELOG.md** (appended):
|
|
574
570
|
\`\`\`markdown
|
|
575
571
|
## 2025-09-15T14:35:00Z
|
|
576
572
|
feat(api): add webhook support for real-time notifications
|
|
@@ -583,7 +579,7 @@ feat(api): add webhook support for real-time notifications
|
|
|
583
579
|
The cs-devops-agent worker is configured to:
|
|
584
580
|
- Use branch prefix: dev_${initials}_
|
|
585
581
|
- Create daily branches: dev_${initials}_YYYY-MM-DD
|
|
586
|
-
- Auto-commit when .
|
|
582
|
+
- Auto-commit when .${agentName.toLowerCase()}-commit-msg changes
|
|
587
583
|
- Handle daily rollover at midnight
|
|
588
584
|
- Automatically stage, commit, and push changes
|
|
589
585
|
- Clear commit message after successful push
|
|
@@ -614,7 +610,7 @@ Every file should start with a comprehensive description:
|
|
|
614
610
|
* import { MainClass } from './this-module';
|
|
615
611
|
* const instance = new MainClass();
|
|
616
612
|
* const result = instance.process();
|
|
617
|
-
*/
|
|
613
|
+
* */
|
|
618
614
|
\`\`\`
|
|
619
615
|
|
|
620
616
|
### 2. Function/Method Documentation
|
|
@@ -639,22 +635,7 @@ Every file should start with a comprehensive description:
|
|
|
639
635
|
* }
|
|
640
636
|
*/
|
|
641
637
|
async function executeProcess(processName, inputText, context) {
|
|
642
|
-
//
|
|
643
|
-
if (!processes[processName]) {
|
|
644
|
-
throw new Error(\`Process '\${processName}' not found\`);
|
|
645
|
-
}
|
|
646
|
-
|
|
647
|
-
// Step 2: Initialize execution context
|
|
648
|
-
// This tracks state across all process steps
|
|
649
|
-
const executionContext = initContext(context);
|
|
650
|
-
|
|
651
|
-
// Step 3: Execute each step sequentially
|
|
652
|
-
// Note: Future versions will support parallel execution
|
|
653
|
-
for (const step of process.steps) {
|
|
654
|
-
// Process step with automatic retry on failure
|
|
655
|
-
const stepResult = await executeStep(step, executionContext);
|
|
656
|
-
// ...
|
|
657
|
-
}
|
|
638
|
+
// ...
|
|
658
639
|
}
|
|
659
640
|
\`\`\`
|
|
660
641
|
|
|
@@ -668,15 +649,7 @@ if (mode === 'production') {
|
|
|
668
649
|
// Force secure connections in production
|
|
669
650
|
// This ensures data privacy for sensitive operations
|
|
670
651
|
options.secure = true;
|
|
671
|
-
} else if (mode === 'development') {
|
|
672
|
-
// Allow insecure connections for local testing
|
|
673
|
-
// Speeds up development workflow
|
|
674
|
-
options.secure = false;
|
|
675
652
|
}
|
|
676
|
-
|
|
677
|
-
// Explain non-obvious code
|
|
678
|
-
// Using exponential backoff to avoid overwhelming the API
|
|
679
|
-
const waitTime = Math.min(2 ** attempt * 0.5, 30); // Cap at 30 seconds
|
|
680
653
|
\`\`\`
|
|
681
654
|
|
|
682
655
|
### 4. TODO/FIXME Comments
|
|
@@ -685,41 +658,6 @@ const waitTime = Math.min(2 ** attempt * 0.5, 30); // Cap at 30 seconds
|
|
|
685
658
|
// This would reduce API calls by ~40% based on usage patterns
|
|
686
659
|
|
|
687
660
|
// FIXME(${initials}, YYYY-MM-DD): Handle edge case when input is null
|
|
688
|
-
// Current behavior: Throws unhandled exception
|
|
689
|
-
// Desired: Return graceful error message
|
|
690
|
-
\`\`\`
|
|
691
|
-
|
|
692
|
-
### 5. Configuration & Constants
|
|
693
|
-
\`\`\`javascript
|
|
694
|
-
// Configuration constants should explain their purpose and valid ranges
|
|
695
|
-
const MAX_RETRIES = 3; // Maximum retry attempts for failed operations
|
|
696
|
-
const TIMEOUT_MS = 30000; // Request timeout in milliseconds (30 seconds)
|
|
697
|
-
const BATCH_SIZE = 100; // Process items in batches to manage memory
|
|
698
|
-
|
|
699
|
-
// Document configuration structures
|
|
700
|
-
const MODES = {
|
|
701
|
-
'fast': 'Prioritize speed over accuracy',
|
|
702
|
-
'balanced': 'Balance between speed and accuracy',
|
|
703
|
-
'accurate': 'Prioritize accuracy over speed'
|
|
704
|
-
};
|
|
705
|
-
\`\`\`
|
|
706
|
-
|
|
707
|
-
### 6. Error Handling Comments
|
|
708
|
-
\`\`\`javascript
|
|
709
|
-
try {
|
|
710
|
-
const response = await apiClient.request(endpoint);
|
|
711
|
-
} catch (error) {
|
|
712
|
-
if (error.code === 'ECONNREFUSED') {
|
|
713
|
-
// Service might be starting up or under maintenance
|
|
714
|
-
// Retry with exponential backoff before failing
|
|
715
|
-
logger.warn(\`Service unavailable: \${error.message}\`);
|
|
716
|
-
return await retryWithBackoff(request);
|
|
717
|
-
} else if (error.code === 'INVALID_INPUT') {
|
|
718
|
-
// Invalid input is unrecoverable - notify user
|
|
719
|
-
logger.error(\`Invalid input: \${error.message}\`);
|
|
720
|
-
throw error;
|
|
721
|
-
}
|
|
722
|
-
}
|
|
723
661
|
\`\`\`
|
|
724
662
|
|
|
725
663
|
## Code Quality Standards
|
|
@@ -728,61 +666,31 @@ try {
|
|
|
728
666
|
- Update related documentation when changing functionality
|
|
729
667
|
- Write self-documenting code with clear variable and function names
|
|
730
668
|
- Add JSDoc comments for all public functions and classes
|
|
731
|
-
- Comment complex algorithms and business logic
|
|
732
|
-
- Document assumptions and constraints
|
|
733
|
-
- Include examples in function documentation
|
|
734
|
-
|
|
735
|
-
## File Organization
|
|
736
|
-
- Use descriptive file names that reflect their purpose
|
|
737
|
-
- Group related changes in a single commit when they're part of the same feature
|
|
738
|
-
- If making multiple unrelated changes, document them separately
|
|
739
|
-
- Keep files focused on a single responsibility
|
|
740
|
-
- Create new files rather than making existing files too large
|
|
741
|
-
|
|
742
|
-
## Testing Guidelines
|
|
743
|
-
- Write tests for new functionality
|
|
744
|
-
- Update tests when modifying existing functionality
|
|
745
|
-
- Ensure all tests pass before committing
|
|
746
|
-
- Document test scenarios and expected outcomes
|
|
747
|
-
- Include edge cases in test coverage
|
|
748
669
|
|
|
749
670
|
## Communication
|
|
750
|
-
- When asked about changes, reference the
|
|
671
|
+
- When asked about changes, reference the ${agentName.toUpperCase()}_CHANGELOG.md for history
|
|
751
672
|
- Provide context about why changes were made, not just what was changed
|
|
752
673
|
- Alert user to any breaking changes or required migrations
|
|
753
|
-
- Be clear about dependencies and prerequisites
|
|
754
674
|
|
|
755
675
|
## Image and Asset Creation
|
|
756
676
|
- **NEVER create or generate images without explicit user permission**
|
|
757
677
|
- Always ask before creating any image files (PNG, JPG, SVG, etc.)
|
|
758
|
-
- Do not automatically generate placeholder images or logos
|
|
759
|
-
- Wait for specific user request before creating visual assets
|
|
760
678
|
|
|
761
679
|
## Version Control Best Practices
|
|
762
680
|
- Make atomic commits - each commit should represent one logical change
|
|
763
681
|
- Write meaningful commit messages following the conventional format
|
|
764
682
|
- Review changes before committing to ensure quality
|
|
765
|
-
- Don't commit commented-out code - remove it or document why it's kept
|
|
766
683
|
- Keep commits focused and avoid mixing unrelated changes
|
|
767
684
|
|
|
768
685
|
## Security Considerations
|
|
769
686
|
- Never commit sensitive information (passwords, API keys, tokens)
|
|
770
687
|
- Use environment variables for configuration that varies by environment
|
|
771
688
|
- Validate all user input before processing
|
|
772
|
-
- Follow the principle of least privilege
|
|
773
|
-
- Document security considerations in code comments
|
|
774
|
-
|
|
775
|
-
## Performance Guidelines
|
|
776
|
-
- Comment on performance implications of algorithms
|
|
777
|
-
- Document O(n) complexity for non-trivial algorithms
|
|
778
|
-
- Explain caching strategies where implemented
|
|
779
|
-
- Note potential bottlenecks or scaling concerns
|
|
780
|
-
- Include performance considerations in technical decisions
|
|
781
689
|
`;
|
|
782
|
-
fs.writeFileSync(
|
|
783
|
-
log.success(
|
|
690
|
+
fs.writeFileSync(agentMdPath, agentRules);
|
|
691
|
+
log.success(`Created ${agentName.toUpperCase()}.md with house rules`);
|
|
784
692
|
} else {
|
|
785
|
-
log.info(
|
|
693
|
+
log.info(`${agentName.toUpperCase()}.md already exists`);
|
|
786
694
|
}
|
|
787
695
|
|
|
788
696
|
// Update .gitignore
|
|
@@ -792,9 +700,11 @@ try {
|
|
|
792
700
|
|
|
793
701
|
// Check if entries already exist
|
|
794
702
|
const entriesToAdd = [
|
|
795
|
-
|
|
703
|
+
`.${agentName.toLowerCase()}-commit-msg`,
|
|
796
704
|
'**/Archive/',
|
|
797
|
-
'*.backup.*'
|
|
705
|
+
'*.backup.*',
|
|
706
|
+
'local_deploy/',
|
|
707
|
+
'.file-coordination/'
|
|
798
708
|
];
|
|
799
709
|
|
|
800
710
|
let modified = false;
|
|
@@ -813,7 +723,7 @@ try {
|
|
|
813
723
|
}
|
|
814
724
|
}
|
|
815
725
|
|
|
816
|
-
function createRunScripts(projectRoot, initials, packageJson) {
|
|
726
|
+
function createRunScripts(projectRoot, initials, packageJson, agentName = 'Claude') {
|
|
817
727
|
log.header();
|
|
818
728
|
log.title('🎯 Creating Run Scripts');
|
|
819
729
|
|
|
@@ -850,6 +760,8 @@ export AC_CLEAR_MSG_WHEN="push"
|
|
|
850
760
|
# Daily rollover is automatic - no prompting needed
|
|
851
761
|
export AC_ROLLOVER_PROMPT="false"
|
|
852
762
|
export AC_DEBUG="false"
|
|
763
|
+
# Set message file explicitly to match dynamic configuration
|
|
764
|
+
export AC_MSG_FILE=".${agentName.toLowerCase()}-commit-msg"
|
|
853
765
|
|
|
854
766
|
# Check for debug flag
|
|
855
767
|
if [ "$1" == "--debug" ] || [ "$1" == "-d" ]; then
|
|
@@ -890,6 +802,7 @@ AC_PUSH=true
|
|
|
890
802
|
AC_REQUIRE_MSG=true
|
|
891
803
|
AC_MSG_MIN_BYTES=20
|
|
892
804
|
AC_MSG_PATTERN=^(feat|fix|refactor|docs|test|chore)(\\([^)]+\\))?:\\s
|
|
805
|
+
AC_MSG_FILE=.${agentName.toLowerCase()}-commit-msg
|
|
893
806
|
|
|
894
807
|
# Timing Settings
|
|
895
808
|
AC_DEBOUNCE_MS=1500
|
|
@@ -907,72 +820,6 @@ AC_DEBUG=false
|
|
|
907
820
|
log.success('Created .env.example file');
|
|
908
821
|
}
|
|
909
822
|
|
|
910
|
-
function printInstructions(initials) {
|
|
911
|
-
log.header();
|
|
912
|
-
log.title('✅ Setup Complete!');
|
|
913
|
-
console.log('');
|
|
914
|
-
log.info(`Developer Initials: ${colors.bright}${initials.toUpperCase()}${colors.reset}`);
|
|
915
|
-
log.info(`Branch Prefix: ${colors.bright}dev_${initials}_${colors.reset}`);
|
|
916
|
-
console.log('');
|
|
917
|
-
|
|
918
|
-
log.title('📚 Quick Start Guide:');
|
|
919
|
-
console.log('');
|
|
920
|
-
console.log('1. Start the cs-devops-agent worker:');
|
|
921
|
-
console.log(` ${colors.green}npm run cs-devops-agent${colors.reset}`);
|
|
922
|
-
console.log(` ${colors.yellow}OR${colors.reset}`);
|
|
923
|
-
console.log(` ${colors.green}./run-cs-devops-agent-${initials}.sh${colors.reset}`);
|
|
924
|
-
console.log(` ${colors.yellow}OR${colors.reset}`);
|
|
925
|
-
console.log(` ${colors.green}Use VS Code: Cmd+Shift+P → Tasks: Run Task → 🚀 Start DevOps Agent Worker${colors.reset}`);
|
|
926
|
-
console.log('');
|
|
927
|
-
|
|
928
|
-
console.log('2. Make your code changes');
|
|
929
|
-
console.log('');
|
|
930
|
-
|
|
931
|
-
console.log('3. Create a commit message:');
|
|
932
|
-
console.log(` ${colors.green}echo "feat(module): description" > .claude-commit-msg${colors.reset}`);
|
|
933
|
-
console.log(` ${colors.yellow}OR${colors.reset}`);
|
|
934
|
-
console.log(` ${colors.green}Use VS Code: Cmd+Shift+P → Tasks: Run Task → 📝 Create Commit Message${colors.reset}`);
|
|
935
|
-
console.log('');
|
|
936
|
-
|
|
937
|
-
console.log('4. The worker will automatically commit and push!');
|
|
938
|
-
console.log('');
|
|
939
|
-
|
|
940
|
-
log.title('🎯 Daily Workflow:');
|
|
941
|
-
console.log('');
|
|
942
|
-
console.log(`• Your daily branches will be: ${colors.bright}dev_${initials}_YYYY-MM-DD${colors.reset}`);
|
|
943
|
-
console.log('• The worker automatically creates new daily branches at midnight');
|
|
944
|
-
console.log('• Commits require valid conventional format (feat/fix/docs/etc)');
|
|
945
|
-
console.log('• Message file is cleared after successful push');
|
|
946
|
-
console.log('');
|
|
947
|
-
|
|
948
|
-
log.title('📁 Files Created/Updated:');
|
|
949
|
-
console.log('');
|
|
950
|
-
console.log('• .vscode/settings.json - VS Code environment settings');
|
|
951
|
-
console.log('• .vscode/tasks.json - VS Code task shortcuts');
|
|
952
|
-
console.log('• package.json - NPM scripts');
|
|
953
|
-
console.log(`• run-cs-devops-agent-${initials}.sh - Personal run script`);
|
|
954
|
-
console.log('• .claude-commit-msg - Commit message file');
|
|
955
|
-
console.log('• CLAUDE_CHANGELOG.md - Change tracking');
|
|
956
|
-
console.log('• CLAUDE.md - House rules for Claude');
|
|
957
|
-
console.log('• .env.example - Configuration template');
|
|
958
|
-
console.log('');
|
|
959
|
-
|
|
960
|
-
log.title('🔧 Debugging:');
|
|
961
|
-
console.log('');
|
|
962
|
-
console.log('Run with debug output:');
|
|
963
|
-
console.log(` ${colors.green}npm run cs-devops-agent:debug${colors.reset}`);
|
|
964
|
-
console.log(` ${colors.yellow}OR${colors.reset}`);
|
|
965
|
-
console.log(` ${colors.green}./run-cs-devops-agent-${initials}.sh --debug${colors.reset}`);
|
|
966
|
-
console.log('');
|
|
967
|
-
|
|
968
|
-
log.title('📖 Environment Variables:');
|
|
969
|
-
console.log('');
|
|
970
|
-
console.log('See .env.example for all configuration options');
|
|
971
|
-
console.log('');
|
|
972
|
-
|
|
973
|
-
log.header();
|
|
974
|
-
}
|
|
975
|
-
|
|
976
823
|
async function setupEnvFile(projectRoot) {
|
|
977
824
|
log.header();
|
|
978
825
|
log.title('🔑 Setting up Environment Variables');
|
|
@@ -1018,7 +865,7 @@ You can enter your API key now, or set it later in the .env file.
|
|
|
1018
865
|
// CLEANUP FUNCTIONS
|
|
1019
866
|
// ============================================================================
|
|
1020
867
|
|
|
1021
|
-
function cleanupDevOpsAgentFiles(projectRoot) {
|
|
868
|
+
function cleanupDevOpsAgentFiles(projectRoot, agentName = 'Claude') {
|
|
1022
869
|
log.header();
|
|
1023
870
|
log.title('🧹 Cleaning Up DevOpsAgent Files');
|
|
1024
871
|
|
|
@@ -1069,6 +916,16 @@ function cleanupDevOpsAgentFiles(projectRoot) {
|
|
|
1069
916
|
// ============================================================================
|
|
1070
917
|
|
|
1071
918
|
async function main() {
|
|
919
|
+
const args = process.argv.slice(2);
|
|
920
|
+
const skipPrompts = args.includes('--yes') || args.includes('-y');
|
|
921
|
+
const rootArgIndex = args.indexOf('--root');
|
|
922
|
+
const initialsArgIndex = args.indexOf('--initials');
|
|
923
|
+
const agentArgIndex = args.indexOf('--agent');
|
|
924
|
+
|
|
925
|
+
const providedRoot = rootArgIndex !== -1 ? args[rootArgIndex + 1] : null;
|
|
926
|
+
const providedInitials = initialsArgIndex !== -1 ? args[initialsArgIndex + 1] : null;
|
|
927
|
+
const providedAgent = agentArgIndex !== -1 ? args[agentArgIndex + 1] : null;
|
|
928
|
+
|
|
1072
929
|
console.clear();
|
|
1073
930
|
|
|
1074
931
|
// Show welcome
|
|
@@ -1090,7 +947,7 @@ ${colors.dim}This takes about 2 minutes.${colors.reset}
|
|
|
1090
947
|
console.log();
|
|
1091
948
|
|
|
1092
949
|
// Find project root
|
|
1093
|
-
const projectRoot = findProjectRoot();
|
|
950
|
+
const projectRoot = providedRoot ? path.resolve(providedRoot) : findProjectRoot();
|
|
1094
951
|
log.info(`Project root: ${projectRoot}`);
|
|
1095
952
|
|
|
1096
953
|
// Ensure ScriptCS_DevOpsAgent directory exists
|
|
@@ -1104,54 +961,96 @@ ${colors.dim}This takes about 2 minutes.${colors.reset}
|
|
|
1104
961
|
// Get developer initials
|
|
1105
962
|
console.log();
|
|
1106
963
|
sectionTitle('Developer Identification');
|
|
1107
|
-
|
|
964
|
+
|
|
965
|
+
let initials = providedInitials;
|
|
966
|
+
|
|
967
|
+
if (!initials) {
|
|
968
|
+
explain(`
|
|
1108
969
|
${colors.bright}What:${colors.reset} Your 3-letter initials (e.g., abc, xyz)
|
|
1109
970
|
${colors.bright}Why:${colors.reset} Identifies your branches and configuration
|
|
1110
971
|
${colors.bright}How:${colors.reset} Creates branches like dev_abc_2025-10-31
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
let initials = null;
|
|
1114
|
-
while (!initials) {
|
|
1115
|
-
const input = await prompt('Enter your 3-letter initials');
|
|
1116
|
-
initials = validateInitials(input);
|
|
972
|
+
`);
|
|
1117
973
|
|
|
974
|
+
while (!initials) {
|
|
975
|
+
const input = await prompt('Enter your 3-letter initials');
|
|
976
|
+
initials = validateInitials(input);
|
|
977
|
+
|
|
978
|
+
if (!initials) {
|
|
979
|
+
errorMsg('Please enter exactly 3 letters (a-z)');
|
|
980
|
+
tip('Examples: abc, xyz, jdoe');
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
} else {
|
|
984
|
+
initials = validateInitials(initials);
|
|
1118
985
|
if (!initials) {
|
|
1119
|
-
|
|
1120
|
-
|
|
986
|
+
log.error(`Invalid initials provided: ${providedInitials}`);
|
|
987
|
+
process.exit(1);
|
|
1121
988
|
}
|
|
1122
989
|
}
|
|
1123
990
|
|
|
1124
991
|
success(`Using initials: ${colors.cyan}${initials.toUpperCase()}${colors.reset}`);
|
|
1125
992
|
tip(`Your branches will be named: ${colors.cyan}dev_${initials}_YYYY-MM-DD${colors.reset}`);
|
|
1126
993
|
console.log();
|
|
994
|
+
|
|
995
|
+
// Get Primary Agent
|
|
996
|
+
console.log();
|
|
997
|
+
sectionTitle('Primary AI Assistant');
|
|
998
|
+
|
|
999
|
+
let agentName = providedAgent;
|
|
1000
|
+
|
|
1001
|
+
if (!agentName) {
|
|
1002
|
+
explain(`
|
|
1003
|
+
${colors.bright}What:${colors.reset} The AI assistant you primarily use (Claude, Warp, Cursor, etc.)
|
|
1004
|
+
${colors.bright}Why:${colors.reset} Customizes file names (e.g., .warp-commit-msg, WARP.md)
|
|
1005
|
+
`);
|
|
1006
|
+
|
|
1007
|
+
if (skipPrompts) {
|
|
1008
|
+
agentName = 'Claude'; // Default if skipping prompts
|
|
1009
|
+
} else {
|
|
1010
|
+
agentName = await prompt('Primary AI Assistant? [Claude]');
|
|
1011
|
+
agentName = agentName.trim() || 'Claude';
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
success(`Using assistant: ${colors.cyan}${agentName}${colors.reset}`);
|
|
1016
|
+
console.log();
|
|
1127
1017
|
|
|
1128
1018
|
// Groq API Key Setup
|
|
1129
1019
|
sectionTitle('Groq API Key (Contract Automation)');
|
|
1130
|
-
|
|
1020
|
+
|
|
1021
|
+
const hasKey = credentialsManager.hasGroqApiKey();
|
|
1022
|
+
let groqKey = null;
|
|
1023
|
+
|
|
1024
|
+
if (!skipPrompts) {
|
|
1025
|
+
explain(`
|
|
1131
1026
|
${colors.bright}What:${colors.reset} API Key for Groq (llama-3.1-70b-versatile)
|
|
1132
1027
|
${colors.bright}Why:${colors.reset} Required for AI-Optimized Contract Automation System
|
|
1133
1028
|
${colors.bright}Security:${colors.reset} Stored locally in ${colors.yellow}local_deploy/credentials.json${colors.reset} (gitignored)
|
|
1134
|
-
|
|
1029
|
+
`);
|
|
1135
1030
|
|
|
1136
|
-
|
|
1137
|
-
|
|
1031
|
+
if (hasKey) {
|
|
1032
|
+
info('Groq API Key is already configured.');
|
|
1033
|
+
const update = await confirm('Do you want to update it?', false);
|
|
1034
|
+
if (update) {
|
|
1035
|
+
groqKey = await prompt('Enter your Groq API Key');
|
|
1036
|
+
}
|
|
1037
|
+
} else {
|
|
1038
|
+
groqKey = await prompt('Enter your Groq API Key (leave empty to skip)');
|
|
1039
|
+
}
|
|
1138
1040
|
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1041
|
+
if (groqKey && groqKey.trim()) {
|
|
1042
|
+
credentialsManager.setGroqApiKey(groqKey.trim());
|
|
1043
|
+
success('Groq API Key saved securely.');
|
|
1044
|
+
} else if (!hasKey) {
|
|
1045
|
+
warn('Skipping Groq API Key setup.');
|
|
1046
|
+
warn('NOTE: Contract Automation features (analyze-with-llm.js) will NOT work without this key.');
|
|
1047
|
+
}
|
|
1145
1048
|
} else {
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
success('Groq API Key saved securely.');
|
|
1152
|
-
} else if (!hasKey) {
|
|
1153
|
-
warn('Skipping Groq API Key setup.');
|
|
1154
|
-
warn('NOTE: Contract Automation features (analyze-with-llm.js) will NOT work without this key.');
|
|
1049
|
+
if (hasKey) {
|
|
1050
|
+
info('Using existing Groq API Key.');
|
|
1051
|
+
} else {
|
|
1052
|
+
warn('Skipping Groq API Key setup (non-interactive mode).');
|
|
1053
|
+
}
|
|
1155
1054
|
}
|
|
1156
1055
|
|
|
1157
1056
|
console.log();
|
|
@@ -1169,7 +1068,7 @@ ${colors.bright}Security:${colors.reset} Stored locally in ${colors.yellow}local
|
|
|
1169
1068
|
]);
|
|
1170
1069
|
console.log();
|
|
1171
1070
|
|
|
1172
|
-
const proceed = await confirm('Ready to configure DevOps Agent?', true);
|
|
1071
|
+
const proceed = skipPrompts ? true : await confirm('Ready to configure DevOps Agent?', true);
|
|
1173
1072
|
|
|
1174
1073
|
if (!proceed) {
|
|
1175
1074
|
warn('Setup cancelled');
|
|
@@ -1184,7 +1083,7 @@ ${colors.bright}Security:${colors.reset} Stored locally in ${colors.yellow}local
|
|
|
1184
1083
|
// Check and setup folder structure first
|
|
1185
1084
|
const missingFolders = setupFolderStructure(projectRoot);
|
|
1186
1085
|
if (missingFolders && missingFolders.length > 0) {
|
|
1187
|
-
const createFolders = await confirm('Create missing standard folders?', true);
|
|
1086
|
+
const createFolders = skipPrompts ? true : await confirm('Create missing standard folders?', true);
|
|
1188
1087
|
if (createFolders) {
|
|
1189
1088
|
missingFolders.forEach(folder => {
|
|
1190
1089
|
ensureDirectoryExists(path.join(projectRoot, folder));
|
|
@@ -1199,14 +1098,17 @@ ${colors.bright}Security:${colors.reset} Stored locally in ${colors.yellow}local
|
|
|
1199
1098
|
if (!checkContractsExist(projectRoot)) {
|
|
1200
1099
|
log.header();
|
|
1201
1100
|
log.title('📜 Contract Files Missing');
|
|
1202
|
-
|
|
1101
|
+
|
|
1102
|
+
if (!skipPrompts) {
|
|
1103
|
+
explain(`
|
|
1203
1104
|
${colors.bright}Contract System:${colors.reset}
|
|
1204
1105
|
This project uses a Contract System to coordinate multiple AI agents.
|
|
1205
1106
|
It seems like this is a fresh setup or contracts are missing.
|
|
1206
1107
|
We can scan your codebase and generate them now.
|
|
1207
|
-
|
|
1108
|
+
`);
|
|
1109
|
+
}
|
|
1208
1110
|
|
|
1209
|
-
const shouldGenerate = await confirm('Generate contract files now?', true);
|
|
1111
|
+
const shouldGenerate = skipPrompts ? true : await confirm('Generate contract files now?', true);
|
|
1210
1112
|
if (shouldGenerate) {
|
|
1211
1113
|
await generateContracts(projectRoot);
|
|
1212
1114
|
}
|
|
@@ -1214,19 +1116,28 @@ We can scan your codebase and generate them now.
|
|
|
1214
1116
|
|
|
1215
1117
|
// Run setup steps
|
|
1216
1118
|
const packageJson = await setupNpmPackages(projectRoot);
|
|
1217
|
-
setupVSCodeSettings(projectRoot, initials);
|
|
1218
|
-
setupVSCodeTasks(projectRoot, initials);
|
|
1219
|
-
setupCommitFiles(projectRoot, initials);
|
|
1220
|
-
createRunScripts(projectRoot, initials, packageJson);
|
|
1119
|
+
setupVSCodeSettings(projectRoot, initials, agentName);
|
|
1120
|
+
setupVSCodeTasks(projectRoot, initials, agentName);
|
|
1121
|
+
setupCommitFiles(projectRoot, initials, agentName);
|
|
1122
|
+
createRunScripts(projectRoot, initials, packageJson, agentName);
|
|
1221
1123
|
|
|
1222
1124
|
// Setup .env with API keys
|
|
1223
|
-
|
|
1125
|
+
if (!skipPrompts) {
|
|
1126
|
+
await setupEnvFile(projectRoot);
|
|
1127
|
+
} else {
|
|
1128
|
+
// Just create .env if missing in non-interactive mode
|
|
1129
|
+
const envPath = path.join(projectRoot, '.env');
|
|
1130
|
+
if (!fs.existsSync(envPath)) {
|
|
1131
|
+
fs.writeFileSync(envPath, '# Environment Variables\n');
|
|
1132
|
+
log.success('Created .env file');
|
|
1133
|
+
}
|
|
1134
|
+
}
|
|
1224
1135
|
|
|
1225
1136
|
// Clean up DevOpsAgent files to avoid duplicates
|
|
1226
|
-
cleanupDevOpsAgentFiles(projectRoot);
|
|
1137
|
+
cleanupDevOpsAgentFiles(projectRoot, agentName);
|
|
1227
1138
|
|
|
1228
1139
|
// Print instructions
|
|
1229
|
-
printInstructions(initials);
|
|
1140
|
+
printInstructions(initials, agentName);
|
|
1230
1141
|
|
|
1231
1142
|
} catch (error) {
|
|
1232
1143
|
log.error(`Setup failed: ${error.message}`);
|
|
@@ -1235,5 +1146,72 @@ We can scan your codebase and generate them now.
|
|
|
1235
1146
|
}
|
|
1236
1147
|
}
|
|
1237
1148
|
|
|
1149
|
+
function printInstructions(initials, agentName = 'Claude') {
|
|
1150
|
+
log.header();
|
|
1151
|
+
log.title('✅ Setup Complete!');
|
|
1152
|
+
console.log('');
|
|
1153
|
+
log.info(`Developer Initials: ${colors.bright}${initials.toUpperCase()}${colors.reset}`);
|
|
1154
|
+
log.info(`Branch Prefix: ${colors.bright}dev_${initials}_${colors.reset}`);
|
|
1155
|
+
log.info(`Primary Agent: ${colors.bright}${agentName}${colors.reset}`);
|
|
1156
|
+
console.log('');
|
|
1157
|
+
|
|
1158
|
+
log.title('📚 Quick Start Guide:');
|
|
1159
|
+
console.log('');
|
|
1160
|
+
console.log('1. Start the cs-devops-agent worker:');
|
|
1161
|
+
console.log(` ${colors.green}npm run cs-devops-agent${colors.reset}`);
|
|
1162
|
+
console.log(` ${colors.yellow}OR${colors.reset}`);
|
|
1163
|
+
console.log(` ${colors.green}./run-cs-devops-agent-${initials}.sh${colors.reset}`);
|
|
1164
|
+
console.log(` ${colors.yellow}OR${colors.reset}`);
|
|
1165
|
+
console.log(` ${colors.green}Use VS Code: Cmd+Shift+P → Tasks: Run Task → 🚀 Start DevOps Agent Worker${colors.reset}`);
|
|
1166
|
+
console.log('');
|
|
1167
|
+
|
|
1168
|
+
console.log('2. Make your code changes');
|
|
1169
|
+
console.log('');
|
|
1170
|
+
|
|
1171
|
+
console.log('3. Create a commit message:');
|
|
1172
|
+
console.log(` ${colors.green}echo "feat(module): description" > .${agentName.toLowerCase()}-commit-msg${colors.reset}`);
|
|
1173
|
+
console.log(` ${colors.yellow}OR${colors.reset}`);
|
|
1174
|
+
console.log(` ${colors.green}Use VS Code: Cmd+Shift+P → Tasks: Run Task → 📝 Create Commit Message${colors.reset}`);
|
|
1175
|
+
console.log('');
|
|
1176
|
+
|
|
1177
|
+
console.log('4. The worker will automatically commit and push!');
|
|
1178
|
+
console.log('');
|
|
1179
|
+
|
|
1180
|
+
log.title('🎯 Daily Workflow:');
|
|
1181
|
+
console.log('');
|
|
1182
|
+
console.log(`• Your daily branches will be: ${colors.bright}dev_${initials}_YYYY-MM-DD${colors.reset}`);
|
|
1183
|
+
console.log('• The worker automatically creates new daily branches at midnight');
|
|
1184
|
+
console.log('• Commits require valid conventional format (feat/fix/docs/etc)');
|
|
1185
|
+
console.log('• Message file is cleared after successful push');
|
|
1186
|
+
console.log('');
|
|
1187
|
+
|
|
1188
|
+
log.title('📁 Files Created/Updated:');
|
|
1189
|
+
console.log('');
|
|
1190
|
+
console.log('• .vscode/settings.json - VS Code environment settings');
|
|
1191
|
+
console.log('• .vscode/tasks.json - VS Code task shortcuts');
|
|
1192
|
+
console.log('• package.json - NPM scripts');
|
|
1193
|
+
console.log(`• run-cs-devops-agent-${initials}.sh - Personal run script`);
|
|
1194
|
+
console.log(`• .${agentName.toLowerCase()}-commit-msg - Commit message file`);
|
|
1195
|
+
console.log(`• ${agentName.toUpperCase()}_CHANGELOG.md - Change tracking`);
|
|
1196
|
+
console.log(`• ${agentName.toUpperCase()}.md - House rules for ${agentName}`);
|
|
1197
|
+
console.log('• .env.example - Configuration template');
|
|
1198
|
+
console.log('');
|
|
1199
|
+
|
|
1200
|
+
log.title('🔧 Debugging:');
|
|
1201
|
+
console.log('');
|
|
1202
|
+
console.log('Run with debug output:');
|
|
1203
|
+
console.log(` ${colors.green}npm run cs-devops-agent:debug${colors.reset}`);
|
|
1204
|
+
console.log(` ${colors.yellow}OR${colors.reset}`);
|
|
1205
|
+
console.log(` ${colors.green}./run-cs-devops-agent-${initials}.sh --debug${colors.reset}`);
|
|
1206
|
+
console.log('');
|
|
1207
|
+
|
|
1208
|
+
log.title('📖 Environment Variables:');
|
|
1209
|
+
console.log('');
|
|
1210
|
+
console.log('See .env.example for all configuration options');
|
|
1211
|
+
console.log('');
|
|
1212
|
+
|
|
1213
|
+
log.header();
|
|
1214
|
+
}
|
|
1215
|
+
|
|
1238
1216
|
// Run the setup
|
|
1239
1217
|
main().catch(console.error);
|