s9n-devops-agent 2.0.11-dev.9 → 2.0.12
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/package.json +1 -1
- package/src/session-coordinator.js +95 -5
package/package.json
CHANGED
|
@@ -23,7 +23,7 @@ import crypto from 'crypto';
|
|
|
23
23
|
import readline from 'readline';
|
|
24
24
|
import { fileURLToPath } from 'url';
|
|
25
25
|
import { dirname } from 'path';
|
|
26
|
-
import { spawn, execSync, exec } from 'child_process';
|
|
26
|
+
import { spawn, execSync, exec, fork } from 'child_process';
|
|
27
27
|
import { credentialsManager } from './credentials-manager.js';
|
|
28
28
|
|
|
29
29
|
// Inject credentials immediately
|
|
@@ -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
|
-
|
|
605
|
-
|
|
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(
|
|
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]);
|
|
@@ -906,6 +924,77 @@ class SessionCoordinator {
|
|
|
906
924
|
return `${timestamp}-${random}`;
|
|
907
925
|
}
|
|
908
926
|
|
|
927
|
+
/**
|
|
928
|
+
* Ensure GROQ API key is configured (for AI-powered commit messages)
|
|
929
|
+
*/
|
|
930
|
+
async ensureGroqApiKey() {
|
|
931
|
+
const globalSettings = this.loadGlobalSettings();
|
|
932
|
+
|
|
933
|
+
// Check if we've already asked or if key is set
|
|
934
|
+
if (globalSettings.groqApiKeyConfigured === 'never') {
|
|
935
|
+
return; // User chose never
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
if (credentialsManager.hasGroqApiKey()) {
|
|
939
|
+
return; // Key already configured
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
// First time - ask if they want AI-powered commit messages
|
|
943
|
+
console.log(`\n${CONFIG.colors.yellow}═══ AI-Powered Commit Messages ═══${CONFIG.colors.reset}`);
|
|
944
|
+
console.log(`${CONFIG.colors.dim}DevOps Agent can generate commit messages using AI (GROQ).${CONFIG.colors.reset}`);
|
|
945
|
+
console.log();
|
|
946
|
+
console.log(`${CONFIG.colors.bright}Options:${CONFIG.colors.reset}`);
|
|
947
|
+
console.log(` ${CONFIG.colors.green}Y${CONFIG.colors.reset}) Yes - Configure GROQ API key now`);
|
|
948
|
+
console.log(` ${CONFIG.colors.red}N${CONFIG.colors.reset}) Skip - Configure later with: npm run setup`);
|
|
949
|
+
console.log(` ${CONFIG.colors.magenta}Never${CONFIG.colors.reset}) Never ask again (disable AI commits)`);
|
|
950
|
+
|
|
951
|
+
const rl = readline.createInterface({
|
|
952
|
+
input: process.stdin,
|
|
953
|
+
output: process.stdout
|
|
954
|
+
});
|
|
955
|
+
|
|
956
|
+
const answer = await new Promise((resolve) => {
|
|
957
|
+
rl.question('\nEnable AI-powered commit messages? (Y/N/Never) [N]: ', (ans) => {
|
|
958
|
+
resolve(ans.trim().toLowerCase());
|
|
959
|
+
});
|
|
960
|
+
});
|
|
961
|
+
|
|
962
|
+
if (answer === 'never' || answer === 'nev') {
|
|
963
|
+
globalSettings.groqApiKeyConfigured = 'never';
|
|
964
|
+
this.saveGlobalSettings(globalSettings);
|
|
965
|
+
console.log(`${CONFIG.colors.dim}AI commit messages disabled. You can enable later by editing ~/.devops-agent/settings.json${CONFIG.colors.reset}`);
|
|
966
|
+
rl.close();
|
|
967
|
+
return;
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
if (answer === 'y' || answer === 'yes') {
|
|
971
|
+
console.log();
|
|
972
|
+
console.log(`${CONFIG.colors.bright}GROQ API Key Setup${CONFIG.colors.reset}`);
|
|
973
|
+
console.log(`${CONFIG.colors.dim}Get your free API key at: ${CONFIG.colors.cyan}https://console.groq.com/keys${CONFIG.colors.reset}`);
|
|
974
|
+
console.log();
|
|
975
|
+
|
|
976
|
+
const apiKey = await new Promise((resolve) => {
|
|
977
|
+
rl.question('Enter your GROQ API key: ', (key) => {
|
|
978
|
+
resolve(key.trim());
|
|
979
|
+
});
|
|
980
|
+
});
|
|
981
|
+
|
|
982
|
+
if (apiKey) {
|
|
983
|
+
credentialsManager.setGroqApiKey(apiKey);
|
|
984
|
+
credentialsManager.injectEnv();
|
|
985
|
+
globalSettings.groqApiKeyConfigured = 'yes';
|
|
986
|
+
this.saveGlobalSettings(globalSettings);
|
|
987
|
+
console.log(`${CONFIG.colors.green}✓${CONFIG.colors.reset} GROQ API key saved successfully!`);
|
|
988
|
+
} else {
|
|
989
|
+
console.log(`${CONFIG.colors.yellow}No key entered. You can configure later with: npm run setup${CONFIG.colors.reset}`);
|
|
990
|
+
}
|
|
991
|
+
} else {
|
|
992
|
+
console.log(`${CONFIG.colors.dim}Skipping for now. Configure later with: npm run setup${CONFIG.colors.reset}`);
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
rl.close();
|
|
996
|
+
}
|
|
997
|
+
|
|
909
998
|
/**
|
|
910
999
|
* Create a new session and generate Claude instructions
|
|
911
1000
|
*/
|
|
@@ -917,6 +1006,7 @@ class SessionCoordinator {
|
|
|
917
1006
|
await this.ensureGlobalSetup(); // Developer initials (once per user)
|
|
918
1007
|
await this.ensureProjectSetup(); // Version strategy (once per project)
|
|
919
1008
|
await this.ensureHouseRulesSetup(); // House rules setup (once per project)
|
|
1009
|
+
await this.ensureGroqApiKey(); // GROQ API key for AI commits (once per user)
|
|
920
1010
|
|
|
921
1011
|
const sessionId = this.generateSessionId();
|
|
922
1012
|
const task = options.task || 'development';
|