@hone-ai/cli 1.8.1 → 1.9.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.
Files changed (2) hide show
  1. package/hone-cli.js +87 -3
  2. package/package.json +1 -1
package/hone-cli.js CHANGED
@@ -362,10 +362,16 @@ program
362
362
  console.log('Running setup-ai-pipeline.sh v3.1...');
363
363
  console.log('');
364
364
 
365
+ // Auto-detect non-TTY (CI, piped, Claude Code) and add --non-interactive
366
+ const isNonInteractive = opts.nonInteractive || !process.stdin.isTTY;
367
+ if (isNonInteractive && !opts.nonInteractive) {
368
+ console.log(' (non-TTY detected — running in non-interactive mode)');
369
+ }
370
+
365
371
  const flags = [
366
372
  `--source "${path.join(tmpDir, 'enterprise-github')}"`,
367
- opts.dryRun ? '--dry-run' : '',
368
- opts.nonInteractive? '--non-interactive' : '',
373
+ opts.dryRun ? '--dry-run' : '',
374
+ isNonInteractive ? '--non-interactive' : '',
369
375
  ].filter(Boolean).join(' ');
370
376
 
371
377
  try {
@@ -4144,6 +4150,7 @@ program
4144
4150
  .option('--contracts', 'Run contract validation between pipeline agents')
4145
4151
  .option('--snapshot', 'Save current eval + contract results as regression baseline')
4146
4152
  .option('--regression', 'Compare current results against saved baseline (detect drift)')
4153
+ .option('--judge', 'Run LLM-as-judge scenarios (requires ANTHROPIC_API_KEY, costs tokens)')
4147
4154
  .action(async (opts) => {
4148
4155
  const path = require('path');
4149
4156
  const fs = require('fs');
@@ -4205,7 +4212,84 @@ program
4205
4212
  process.exit(results.failed > 0 ? 1 : 0);
4206
4213
  }
4207
4214
 
4208
- // Scenario evaluation mode
4215
+ // LLM-judge mode (HC-019i / #268)
4216
+ if (opts.judge) {
4217
+ const { loadScenarios, formatResults } = require('./lib/eval-runner');
4218
+ const { runJudgeScenario } = require('./lib/eval-llm-judge');
4219
+
4220
+ const apiKey = process.env.ANTHROPIC_API_KEY;
4221
+ if (!apiKey) {
4222
+ console.error('ANTHROPIC_API_KEY required for --judge mode. Set: export ANTHROPIC_API_KEY=sk-ant-...');
4223
+ process.exit(1);
4224
+ }
4225
+
4226
+ const scenarios = loadScenarios({
4227
+ evalDir, agent: opts.agent, tag: opts.tag, scenarioId: opts.scenario,
4228
+ readFile: (p) => fs.readFileSync(p, 'utf8'),
4229
+ listDir: (p) => fs.readdirSync(p), isDir: (p) => fs.statSync(p).isDirectory(),
4230
+ parseYaml: (text) => yaml.load(text),
4231
+ });
4232
+
4233
+ const judgeScenarios = scenarios.filter(s => s.grading?.mode === 'llm-judge');
4234
+ if (judgeScenarios.length === 0) {
4235
+ console.log('No llm-judge scenarios found. Add grading.mode: llm-judge to eval YAML files.');
4236
+ process.exit(0);
4237
+ }
4238
+
4239
+ // LLM call function using Anthropic API
4240
+ async function callLLM(systemPrompt, userPrompt) {
4241
+ const { data } = await axios.post('https://api.anthropic.com/v1/messages', {
4242
+ model: 'claude-sonnet-4-20250514',
4243
+ max_tokens: 2048,
4244
+ system: systemPrompt,
4245
+ messages: [{ role: 'user', content: userPrompt }],
4246
+ }, {
4247
+ headers: {
4248
+ 'x-api-key': apiKey,
4249
+ 'anthropic-version': '2023-06-01',
4250
+ 'content-type': 'application/json',
4251
+ },
4252
+ timeout: 60000,
4253
+ });
4254
+ return data.content?.[0]?.text || '';
4255
+ }
4256
+
4257
+ console.log(`Running ${judgeScenarios.length} LLM-judge scenario(s)...`);
4258
+ console.log('');
4259
+
4260
+ const results = [];
4261
+ for (const scenario of judgeScenarios) {
4262
+ const agentName = scenario.evalAgent || scenario.agent;
4263
+ const promptText = AGENT_PROMPTS[agentName];
4264
+ if (!promptText) {
4265
+ results.push({ id: scenario.id, agent: agentName, result: 'error',
4266
+ checks: 0, checks_passed: 0, failures: [{ type: 'missing_prompt', passed: false, detail: `agent "${agentName}" not found` }] });
4267
+ continue;
4268
+ }
4269
+ try {
4270
+ const result = await runJudgeScenario({ scenario, agentPrompt: promptText, callLLM });
4271
+ results.push(result);
4272
+ } catch (e) {
4273
+ results.push({ id: scenario.id, agent: agentName, result: 'error',
4274
+ checks: 0, checks_passed: 0, failures: [{ type: 'llm_error', passed: false, detail: e.message }] });
4275
+ }
4276
+
4277
+ if (opts.failFast && results[results.length - 1].result !== 'pass') break;
4278
+ }
4279
+
4280
+ const summary = {
4281
+ total: results.length,
4282
+ passed: results.filter(r => r.result === 'pass').length,
4283
+ failed: results.filter(r => r.result === 'fail').length,
4284
+ errors: results.filter(r => r.result === 'error').length,
4285
+ scenarios: results,
4286
+ };
4287
+
4288
+ console.log(formatResults(summary, opts.format));
4289
+ process.exit(summary.failed + summary.errors > 0 ? 1 : 0);
4290
+ }
4291
+
4292
+ // Scenario evaluation mode (deterministic)
4209
4293
  const { loadScenarios, runAllScenarios, formatResults } = require('./lib/eval-runner');
4210
4294
 
4211
4295
  if (!fs.existsSync(evalDir)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hone-ai/cli",
3
- "version": "1.8.1",
3
+ "version": "1.9.0",
4
4
  "description": "Hone AI — Enterprise SDLC Pipeline CLI",
5
5
  "main": "hone-cli.js",
6
6
  "bin": {