s9n-devops-agent 2.0.11-dev.0 → 2.0.11-dev.10

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.
@@ -1,3 +1,10 @@
1
+ # Release Notes - s9n-devops-agent v2.0.11-dev.0
2
+
3
+ ## 🐛 Fixed
4
+ - **Bin Path**: Fixed incorrect `bin` path in `package.json` to ensure the executable works correctly.
5
+
6
+ ---
7
+
1
8
  # Release Notes - CS_DevOpsAgent v2.0.0
2
9
 
3
10
  ## 🚀 Major Release: Multi-Agent Worktree Support & Infrastructure Tracking
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "s9n-devops-agent",
3
- "version": "2.0.11-dev.0",
3
+ "version": "2.0.11-dev.10",
4
4
  "description": "CS_DevOpsAgent - Intelligent Git Automation System with multi-agent support and session management",
5
5
  "type": "module",
6
6
  "main": "src/cs-devops-agent-worker.js",
@@ -29,11 +29,12 @@
29
29
  "house-rules:status": "node src/house-rules-manager.js status",
30
30
  "house-rules:update": "node src/house-rules-manager.js update",
31
31
  "house-rules:repair": "./scripts/repair-house-rules.sh",
32
- "test": "jest test_cases/",
32
+ "test": "NODE_OPTIONS=--experimental-vm-modules jest test_cases/",
33
33
  "test:watch": "jest --watch",
34
34
  "test:coverage": "jest --coverage",
35
35
  "test:worktree": "jest test_cases/worktree/",
36
36
  "test:e2e": "./test_scripts/test-multi-agent-e2e.sh",
37
+ "test:contracts": "jest tests/integration/contract-workflow.test.js",
37
38
  "test:push-behind": "jest test_scripts/push_behind_spec.js",
38
39
  "test:debug": "./debug-failing-tests.sh"
39
40
  },
@@ -51,9 +52,12 @@
51
52
  "dependencies": {
52
53
  "chokidar": "^3.5.3",
53
54
  "execa": "^7.1.1",
54
- "groq-sdk": "^0.37.0"
55
+ "groq-sdk": "^0.37.0",
56
+ "openai": "^4.20.0"
55
57
  },
56
58
  "devDependencies": {
59
+ "@jest/globals": "^29.7.0",
60
+ "eslint": "^8.56.0",
57
61
  "jest": "^29.7.0"
58
62
  },
59
63
  "engines": {
@@ -329,7 +329,8 @@ export function getAgentDisplayName(agentType) {
329
329
  cursor: 'Cursor',
330
330
  copilot: 'GitHub Copilot',
331
331
  cline: 'Cline',
332
- other: 'AI Assistant',
332
+ warp: 'Warp',
333
+ other: 'Other',
333
334
  };
334
335
  return names[agentType] || agentType;
335
336
  }
@@ -19,6 +19,8 @@
19
19
 
20
20
  import fs from 'fs';
21
21
  import path from 'path';
22
+ import crypto from 'crypto';
23
+ import readline from 'readline';
22
24
  import { fileURLToPath } from 'url';
23
25
  import { dirname } from 'path';
24
26
  import { spawn, execSync, exec } from 'child_process';
@@ -28,12 +30,10 @@ import { credentialsManager } from './credentials-manager.js';
28
30
  credentialsManager.injectEnv();
29
31
 
30
32
  const __filename = fileURLToPath(import.meta.url);
33
+ const __dirname = dirname(__filename);
31
34
  import { hasDockerConfiguration } from './docker-utils.js';
32
35
  import HouseRulesManager from './house-rules-manager.js';
33
36
 
34
- const __filename = fileURLToPath(import.meta.url);
35
- const __dirname = dirname(__filename);
36
-
37
37
  // ============================================================================
38
38
  // CONFIGURATION
39
39
  // ============================================================================
@@ -601,12 +601,30 @@ class SessionCoordinator {
601
601
 
602
602
  if (dockerInfo.composeFiles.length > 1) {
603
603
  console.log(`\n${CONFIG.colors.bright}Select docker-compose file:${CONFIG.colors.reset}`);
604
- dockerInfo.composeFiles.forEach((file, index) => {
605
- console.log(` ${index + 1}) ${file.name}`);
606
- });
604
+
605
+ // Check running containers for each compose file
606
+ for (let i = 0; i < dockerInfo.composeFiles.length; i++) {
607
+ const file = dockerInfo.composeFiles[i];
608
+ let runningInfo = '';
609
+
610
+ try {
611
+ // Try to get container count for this compose file
612
+ const { execSync } = await import('child_process');
613
+ const result = execSync(`docker compose -f "${file.path}" ps -q 2>/dev/null | wc -l`, { encoding: 'utf8' });
614
+ const count = parseInt(result.trim());
615
+ if (count > 0) {
616
+ runningInfo = ` ${CONFIG.colors.green}(${count} running)${CONFIG.colors.reset}`;
617
+ }
618
+ } catch (err) {
619
+ // Ignore errors, just don't show running info
620
+ }
621
+
622
+ console.log(` ${i + 1}) ${file.name}${runningInfo}`);
623
+ console.log(` ${CONFIG.colors.dim}${file.path}${CONFIG.colors.reset}`);
624
+ }
607
625
 
608
626
  const fileChoice = await new Promise((resolve) => {
609
- rl.question(`Choose file (1-${dockerInfo.composeFiles.length}) [1]: `, (answer) => {
627
+ rl.question(`\nChoose file (1-${dockerInfo.composeFiles.length}) [1]: `, (answer) => {
610
628
  const choice = parseInt(answer) || 1;
611
629
  if (choice >= 1 && choice <= dockerInfo.composeFiles.length) {
612
630
  resolve(dockerInfo.composeFiles[choice - 1]);
@@ -973,6 +973,47 @@ function printInstructions(initials) {
973
973
  log.header();
974
974
  }
975
975
 
976
+ async function setupEnvFile(projectRoot) {
977
+ log.header();
978
+ log.title('🔑 Setting up Environment Variables');
979
+
980
+ const envPath = path.join(projectRoot, '.env');
981
+ let envContent = '';
982
+
983
+ if (fs.existsSync(envPath)) {
984
+ envContent = fs.readFileSync(envPath, 'utf8');
985
+ log.info('.env file already exists');
986
+ } else {
987
+ log.info('Creating .env file');
988
+ }
989
+
990
+ // Check for OPENAI_API_KEY
991
+ if (!envContent.includes('OPENAI_API_KEY=')) {
992
+ console.log();
993
+ explain(`
994
+ ${colors.bright}Groq API Key Setup${colors.reset}
995
+ The contract automation features use Groq LLM (via OpenAI compatibility).
996
+ You can enter your API key now, or set it later in the .env file.
997
+ `);
998
+
999
+ const apiKey = await prompt('Enter Groq API Key (leave empty to skip)');
1000
+
1001
+ if (apiKey) {
1002
+ const newLine = envContent.endsWith('\n') || envContent === '' ? '' : '\n';
1003
+ envContent += `${newLine}# Groq API Key for Contract Automation\nOPENAI_API_KEY=${apiKey}\n`;
1004
+ fs.writeFileSync(envPath, envContent);
1005
+ log.success('Added OPENAI_API_KEY to .env');
1006
+ } else {
1007
+ log.warn('Skipped Groq API Key. Contract automation features may not work.');
1008
+ if (!fs.existsSync(envPath)) {
1009
+ fs.writeFileSync(envPath, '# Environment Variables\n');
1010
+ }
1011
+ }
1012
+ } else {
1013
+ log.info('OPENAI_API_KEY is already configured in .env');
1014
+ }
1015
+ }
1016
+
976
1017
  // ============================================================================
977
1018
  // CLEANUP FUNCTIONS
978
1019
  // ============================================================================
@@ -1178,6 +1219,9 @@ We can scan your codebase and generate them now.
1178
1219
  setupCommitFiles(projectRoot, initials);
1179
1220
  createRunScripts(projectRoot, initials, packageJson);
1180
1221
 
1222
+ // Setup .env with API keys
1223
+ await setupEnvFile(projectRoot);
1224
+
1181
1225
  // Clean up DevOpsAgent files to avoid duplicates
1182
1226
  cleanupDevOpsAgentFiles(projectRoot);
1183
1227
 
@@ -166,6 +166,8 @@ I'll show you what happens at each stage.
166
166
  console.log(` ${colors.bright}2)${colors.reset} Cursor`);
167
167
  console.log(` ${colors.bright}3)${colors.reset} GitHub Copilot`);
168
168
  console.log(` ${colors.bright}4)${colors.reset} Cline (VS Code)`);
169
+ console.log(` ${colors.bright}5)${colors.reset} Warp`);
170
+ console.log(` ${colors.bright}6)${colors.reset} Other`);
169
171
  console.log();
170
172
  console.log(` ${colors.cyan}?${colors.reset} Your choice: ${colors.dim}1${colors.reset}`);
171
173
  console.log();
@@ -147,13 +147,17 @@ create_new_session() {
147
147
  echo -e " ${GREEN}2)${NC} Cursor"
148
148
  echo -e " ${GREEN}3)${NC} GitHub Copilot"
149
149
  echo -e " ${GREEN}4)${NC} Cline (VS Code)"
150
- echo -n " Your choice [1-4, default: 1]: "
150
+ echo -e " ${GREEN}5)${NC} Warp"
151
+ echo -e " ${GREEN}6)${NC} Other"
152
+ echo -n "➜ Your choice [1-6, default: 1]: "
151
153
  read agent_choice
152
154
 
153
155
  case "$agent_choice" in
154
156
  2) agent_type="cursor" ;;
155
157
  3) agent_type="copilot" ;;
156
158
  4) agent_type="cline" ;;
159
+ 5) agent_type="warp" ;;
160
+ 6) agent_type="other" ;;
157
161
  *) agent_type="claude" ;;
158
162
  esac
159
163