coderev-cli 1.0.25 → 1.1.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "coderev-cli",
3
- "version": "1.0.25",
3
+ "version": "1.1.0",
4
4
  "description": "Multi-agent AI code review for git -- parallel agents with confidence scoring",
5
5
  "main": "src/index.js",
6
6
  "bin": {
package/src/cli.js CHANGED
@@ -888,9 +888,11 @@ program
888
888
  .option('--agent-security <name>', 'Model for security agent')
889
889
  .option('--agent-bugs <name>', 'Model for bug detection agent')
890
890
  .option('--agent-quality <name>', 'Model for quality agent')
891
+ .option('--auto', 'Auto-detect available providers from environment variables')
892
+ .option('--quick', 'Alias for --auto')
891
893
  .action((options) => {
892
894
  const fs = require('fs');
893
- const { resolveTemplate } = require('./models');
895
+ const { resolveTemplate, autoDetectProvider, listTemplates } = require('./models');
894
896
  const configPath = path.join(process.cwd(), '.coderevrc.json');
895
897
 
896
898
  let config = {};
@@ -900,6 +902,86 @@ program
900
902
 
901
903
  if (!config.ai) config.ai = {};
902
904
 
905
+ // ── Auto-detect mode ──
906
+ if (options.auto || options.quick) {
907
+ console.log(chalk.bold('\n🔍 Auto-detecting AI providers...\n'));
908
+
909
+ const result = autoDetectProvider();
910
+
911
+ if (!result) {
912
+ console.log(chalk.yellow('⚠ No API key environment variables detected.'));
913
+ console.log(chalk.gray('\n Supported providers and their env vars:'));
914
+ const allTemplates = listTemplates();
915
+ const seen = new Set();
916
+ for (const t of allTemplates) {
917
+ if (!seen.has(t.apiKeyEnv)) {
918
+ seen.add(t.apiKeyEnv);
919
+ console.log(chalk.gray(` ${t.apiKeyEnv} → ${t.name} (${t.desc})`));
920
+ }
921
+ }
922
+ console.log(chalk.blue('\n 💡 Set one of these env vars and run `coderev setup --auto` again.'));
923
+ console.log(chalk.blue(' Or use `coderev setup --model <name>` to pick manually.'));
924
+ return;
925
+ }
926
+
927
+ // Show detection summary
928
+ console.log(chalk.bold('📋 Detection Results / 检测结果:'));
929
+ console.log('━'.repeat(50));
930
+
931
+ // List all detected keys
932
+ for (const name of result.allDetected) {
933
+ const t = result.allDetected.includes(name) ? require('./models').getTemplate(name) : null;
934
+ if (t) {
935
+ const masked = process.env[t.apiKeyEnv].slice(0, 6) + '...' + process.env[t.apiKeyEnv].slice(-4);
936
+ console.log(chalk.green(` ✔ ${t.apiKeyEnv}`) + chalk.gray(` → ${name} (${masked})`));
937
+ }
938
+ }
939
+
940
+ // Show providers that were NOT detected
941
+ const allNames = Object.keys(require('./models').BUILTIN_TEMPLATES);
942
+ const uniqueNotDetected = [...new Set(
943
+ allNames.filter(n => !result.allDetected.includes(n))
944
+ )];
945
+
946
+ console.log('');
947
+ console.log(chalk.bold(`✨ Selected: ${chalk.green(result.chosen)}`));
948
+ console.log(chalk.gray(` Provider: ${result.template.provider}`));
949
+ console.log(chalk.gray(` Model: ${result.template.model}`));
950
+ console.log(chalk.gray(` API Key: ${result.template.apiKeyEnv}`));
951
+ console.log('');
952
+
953
+ // Write config
954
+ try {
955
+ const resolved = resolveTemplate(result.chosen);
956
+ Object.assign(config.ai, resolved);
957
+
958
+ // Also add fallback if second provider is available
959
+ const remaining = result.allDetected.filter(n => n !== result.chosen);
960
+ if (remaining.length > 0) {
961
+ const fallbackName = remaining[0];
962
+ const fallbackResolved = resolveTemplate(fallbackName);
963
+ config.ai.fallback = {
964
+ enabled: true,
965
+ provider: fallbackResolved.provider,
966
+ baseURL: fallbackResolved.baseURL,
967
+ model: fallbackResolved.model,
968
+ apiKeyEnv: fallbackResolved.apiKeyEnv,
969
+ temperature: fallbackResolved.temperature,
970
+ maxTokens: fallbackResolved.maxTokens,
971
+ };
972
+ console.log(chalk.blue(` Fallback: ${fallbackName} (${fallbackResolved.model})`));
973
+ }
974
+
975
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
976
+ console.log(chalk.green(`\n✔ Config saved to ${configPath}`));
977
+ console.log(chalk.blue(' Run `coderev review` to start reviewing code!'));
978
+ } catch (err) {
979
+ console.error(chalk.red(`✖ ${err.message}`));
980
+ process.exit(1);
981
+ }
982
+ return;
983
+ }
984
+
903
985
  // Set primary model
904
986
  if (options.model) {
905
987
  try {
@@ -1078,6 +1160,33 @@ program
1078
1160
  }
1079
1161
  });
1080
1162
 
1163
+ // ── Doctor (Environment Diagnostic) ─────────────────────────────
1164
+ program
1165
+ .command('doctor')
1166
+ .description('Run environment diagnostic to troubleshoot common issues')
1167
+ .option('-c, --config <path>', 'Path to config file')
1168
+ .option('--json', 'Output as JSON')
1169
+ .action(async (options) => {
1170
+ try {
1171
+ const { runDoctor, formatDoctorReport } = require('./doctor');
1172
+ console.error(chalk.blue('↻ Running environment diagnostic...\n'));
1173
+ const { checks, allPassed } = await runDoctor({ config: options.config });
1174
+
1175
+ if (options.json) {
1176
+ console.log(JSON.stringify({ allPassed, checks }, null, 2));
1177
+ } else {
1178
+ console.log(formatDoctorReport(checks));
1179
+ }
1180
+
1181
+ if (!allPassed) {
1182
+ process.exitCode = 1;
1183
+ }
1184
+ } catch (err) {
1185
+ console.error(chalk.red(`✖ ${err.message}`));
1186
+ process.exit(1);
1187
+ }
1188
+ });
1189
+
1081
1190
  program.parse(process.argv);
1082
1191
 
1083
1192
  // ── Helpers ───────────────────────────────────────────────────