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/README.md +838 -0
- package/package.json +1 -1
- package/src/cli.js +110 -1
- package/src/doctor.js +573 -0
- package/src/models.js +59 -0
- package/src/models.test.js +139 -2
package/package.json
CHANGED
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 ───────────────────────────────────────────────────
|