@rigour-labs/cli 6.12.1 → 6.12.2-rc.2

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/dist/cli.js CHANGED
@@ -401,6 +401,7 @@ program
401
401
  .option('--limit <n>', 'Merged PRs to read at most', '100')
402
402
  .option('--rules', "Write each newly promoted lesson as the rule behind it, with the team's reviewer CLI (counts toward review.reviewer.max_usd_per_day)")
403
403
  .option('--list', 'List the lessons learned so far')
404
+ .option('--include-bots', 'With --list: also list candidates only review bots raised (hidden by default)')
404
405
  .option('--promote <id>', 'Accept a candidate as a lesson (recorded as your decision)')
405
406
  .option('--reject <id>', 'Reject a candidate or lesson: the judges are told this team decided against it')
406
407
  .option('--why <text>', 'Why, recorded with --promote or --reject')
@@ -6,6 +6,8 @@ export interface LearnReviewsOptions {
6
6
  reject?: string;
7
7
  why?: string;
8
8
  list?: boolean;
9
+ /** With --list: also list candidates only review bots raised (hidden by default, and counted). */
10
+ includeBots?: boolean;
9
11
  json?: boolean;
10
12
  /** Rewrite each new point as the rule behind it with the team's reviewer CLI (memory, never training). */
11
13
  rules?: boolean;
@@ -11,7 +11,7 @@ import { execFileSync } from 'child_process';
11
11
  import chalk from 'chalk';
12
12
  import path from 'path';
13
13
  import { personOf } from './git-identity.js';
14
- import { acceptSuggestedText, scopeLesson, branchBase, decideCompiledCheck, decideLesson, defaultExec, proposeCompiledChecks, readCompiledChecks, suspension, githubToken, learnFromReviews, lessonsPath, readLessons, ruleWriterFor, ConfigSchema } from '@rigour-labs/core';
14
+ import { acceptSuggestedText, scopeLesson, branchBase, decideCompiledCheck, decideLesson, defaultExec, proposeCompiledChecks, readCompiledChecks, suspension, githubToken, learnFromReviews, lessonsPath, pendingDecision, quietBotCandidate, readLessons, ruleWriterFor, ConfigSchema } from '@rigour-labs/core';
15
15
  import { loadConfig } from './review-config.js';
16
16
  export async function learnReviewsCommand(cwd, options) {
17
17
  if (options.promote)
@@ -19,7 +19,7 @@ export async function learnReviewsCommand(cwd, options) {
19
19
  if (options.reject)
20
20
  return decide(cwd, options.reject, 'rejected', options.why);
21
21
  if (options.list)
22
- return list(cwd, options.json);
22
+ return list(cwd, options.json, options.includeBots);
23
23
  if (options.useWording)
24
24
  return useWording(cwd, options.useWording);
25
25
  if (options.scope)
@@ -53,21 +53,38 @@ export async function learnReviewsCommand(cwd, options) {
53
53
  process.exitCode = 1;
54
54
  }
55
55
  }
56
- function list(cwd, json) {
57
- const lessons = readLessons(cwd);
56
+ function list(cwd, json, includeBots) {
57
+ const all = readLessons(cwd);
58
58
  if (json)
59
- return void console.log(JSON.stringify(lessons, null, 2));
60
- const label = { verified: chalk.green('lesson '), candidate: chalk.yellow('candidate'), rejected: chalk.red('rejected ') };
61
- for (const l of lessons) {
62
- const prs = [...new Set(l.evidence.map(e => `#${e.pr}`))].join(', ');
63
- const by = chalk.dim(`${l.promotedBy ? ` [${l.promotedBy}]` : ''}${l.scope ? ` [${l.scope === 'repo' ? 'every change' : 'its folder'}]` : ''}`);
64
- console.log(`${label[l.state]} ${chalk.dim(l.id)} ${l.file || '(team standard)'}: ${l.text}${by} ${chalk.dim(`(${prs})`)}`);
65
- if (l.suggestedText)
66
- console.log(chalk.cyan(` corrected wording (${l.suggestedWhy ?? 'reworded'}): ${l.suggestedText}`) + chalk.dim(` take it: rigour learn-reviews --use-wording ${l.id}`));
67
- }
68
- if (lessons.length === 0)
59
+ return void console.log(JSON.stringify(all, null, 2));
60
+ const lessons = includeBots ? all : all.filter(l => !quietBotCandidate(l));
61
+ for (const l of lessons)
62
+ printLesson(l);
63
+ const hidden = all.length - lessons.length;
64
+ if (hidden)
65
+ console.log(chalk.dim(`${hidden} candidate(s) from review bots, hidden: --include-bots lists them.`));
66
+ else if (all.length === 0)
69
67
  console.log('No review lessons yet. Run `rigour learn-reviews`.');
70
68
  }
69
+ function printLesson(l) {
70
+ const label = { verified: chalk.green('lesson '), candidate: chalk.yellow('candidate'), rejected: chalk.red('rejected ') };
71
+ const prs = [...new Set(l.evidence.map(e => `#${e.pr}`))].join(', ');
72
+ const by = chalk.dim(`${l.promotedBy ? ` [${l.promotedBy}]` : ''}${l.scope ? ` [${l.scope === 'repo' ? 'every change' : 'its folder'}]` : ''}`);
73
+ console.log(`${label[l.state]} ${chalk.dim(l.id)} ${l.file || '(team standard)'}: ${l.text}${by} ${chalk.dim(`(${prs})`)}`);
74
+ const pending = pendingDecision(l);
75
+ if (pending)
76
+ console.log(chalk.yellow(` ${pendingReason(pending)}`));
77
+ if (l.suggestedText)
78
+ console.log(chalk.cyan(` corrected wording (${l.suggestedWhy ?? 'reworded'}): ${l.suggestedText}`) + chalk.dim(` take it: rigour learn-reviews --use-wording ${l.id}`));
79
+ }
80
+ /** Why a candidate waits on a person, in the words Studio's chip uses. */
81
+ function pendingReason(e) {
82
+ if (e.kind === 'lines')
83
+ return `a later fix changed its lines: ${e.detail ?? ''}`.trim();
84
+ if (e.kind === 'reclassified')
85
+ return `back to candidate: ${e.detail ?? ''}`;
86
+ return e.detail ?? 'taken back';
87
+ }
71
88
  /** Proposes checks for the verified lessons a template fits, then lists every compiled check and its state. */
72
89
  function compile(cwd, json) {
73
90
  const proposed = proposeCompiledChecks(cwd);
@@ -48,6 +48,8 @@ export interface LessonJourney {
48
48
  scope: 'file' | 'folder' | 'repo';
49
49
  hasFile: boolean;
50
50
  };
51
+ /** A candidate only review bots raised, nothing waiting on a person (core quietBotCandidate): hidden until a person asks to see bot points. */
52
+ fromBots?: true;
51
53
  }
52
54
  export interface StudioLearning {
53
55
  lessons: LessonJourney[];
@@ -7,7 +7,7 @@
7
7
  * lesson's subject prefix). Counts that Rigour cannot know here are null, never 0: PR catches
8
8
  * recorded on another machine (CI) never reach this one.
9
9
  */
10
- import { acceptSuggestedText, scopeLesson, decideCompiledCheck, decideLesson, fixLessonPrefix, proposeCompiledChecks, readCompiledChecks, suspension, localOutcomeMetrics, pendingDecision, listKnowledgeLessons, readLessons } from '@rigour-labs/core';
10
+ import { acceptSuggestedText, scopeLesson, decideCompiledCheck, decideLesson, fixLessonPrefix, proposeCompiledChecks, readCompiledChecks, suspension, localOutcomeMetrics, pendingDecision, quietBotCandidate, listKnowledgeLessons, readLessons } from '@rigour-labs/core';
11
11
  import { personOf } from './git-identity.js';
12
12
  import { checkoutRoots, eventsAcross, storiesAcross } from './studio-checkouts.js';
13
13
  const WEEK_MS = 7 * 24 * 60 * 60 * 1000;
@@ -52,6 +52,7 @@ export function buildLearning(input) {
52
52
  ...decisionFor(l),
53
53
  ...(l.suggestedText ? { suggestedText: { text: l.suggestedText, why: l.suggestedWhy ?? 'reworded' } } : {}),
54
54
  reach: { scope: l.scope ?? 'file', hasFile: !!l.file },
55
+ ...(quietBotCandidate(l) ? { fromBots: true } : {}),
55
56
  })),
56
57
  // Lessons back to a candidate when outcomes stopped promoting come first: a person decides each once.
57
58
  ].sort((a, b) => Number(!!b.reclassified) - Number(!!a.reclassified) || b.learnedAt.localeCompare(a.learnedAt))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rigour-labs/cli",
3
- "version": "6.12.1",
3
+ "version": "6.12.2-rc.2",
4
4
  "description": "Code review that happens while your agent writes: deterministic checks on the lines it changed, quiet unless it can prove a defect, and learning from your team's fixes and dismissals. Works with Claude Code, Cursor, Codex, Cline and Windsurf.",
5
5
  "engines": {
6
6
  "node": ">=22.13"
@@ -59,13 +59,13 @@
59
59
  "inquirer": "9.2.16",
60
60
  "ora": "^8.0.1",
61
61
  "yaml": "^2.8.2",
62
- "@rigour-labs/core": "6.12.1"
62
+ "@rigour-labs/core": "6.12.2-rc.2"
63
63
  },
64
64
  "devDependencies": {
65
65
  "@types/fs-extra": "^11.0.4",
66
66
  "@types/inquirer": "9.0.7",
67
67
  "@types/node": "^25.0.3",
68
- "@rigour-labs/studio": "6.12.1"
68
+ "@rigour-labs/studio": "6.12.2-rc.2"
69
69
  },
70
70
  "scripts": {
71
71
  "build": "tsc && pnpm bundle-studio",