@rigour-labs/cli 6.9.0-rc.3 → 6.9.0-rc.4

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.
@@ -27,6 +27,9 @@ export async function outcomesCommand(cwd, options) {
27
27
  for (const o of run.outcomes)
28
28
  console.log(outcomeLine(o));
29
29
  console.log(chalk.dim(`${run.outcomes.length} pull request(s), ${run.read} read now, the rest settled.${run.stopped ? ` Stopped early: ${run.stopped}.` : ''}`));
30
+ if (run.metrics)
31
+ for (const line of metricLines(run.metrics))
32
+ console.log(chalk.dim(line));
30
33
  if (run.lessons?.added)
31
34
  console.log(`Lessons: ${run.lessons.added} new piece(s) of evidence, ${run.lessons.suggested.length} to look at in Studio (a later fix changed their lines), ${run.lessons.demoted.length} taken back.`);
32
35
  return 0;
@@ -37,3 +40,13 @@ function outcomeLine(o) {
37
40
  const after = `${o.followUps.length} later commit(s) on its files${fixes ? `, ${chalk.yellow(`${fixes} fix(es)`)}` : ''}`;
38
41
  return `#${o.pr} ${o.mergeSha.slice(0, 9)} merged ${o.mergedAt.slice(0, 10)}: ${ci}, ${after}${o.reverted ? `, ${chalk.red(`reverted by ${o.reverted.sha.slice(0, 9)}`)}` : ''}${o.settled ? '' : chalk.dim(' (window open)')}`;
39
42
  }
43
+ /** The numbers, as counts; a percentage only where there are enough records for one (metrics.ts). Reviewed and not reviewed are side by side, never compared. */
44
+ function metricLines(m) {
45
+ const share = (s) => `${s.count} of ${s.of}${s.rate === null ? '' : ` (${Math.round(s.rate * 100)}%)`}`;
46
+ return [
47
+ `Numbers: ${m.records.merged} merged, ${m.records.settled} settled, ${m.records.unsettled} with the window still open.`,
48
+ ` Settled: CI regressed on the merge ${share(m.settled.ciRegressed)}${m.settled.ciUnknown ? ` (${m.settled.ciUnknown} with no CI to read)` : ''}, reverted ${share(m.settled.reverted)}, fixed later ${share(m.settled.fixedLater)}.`,
49
+ ` Reviewed by Rigour: ${m.settled.reviewed.prs} pull request(s), ${m.settled.reviewed.fixedLater.count} fixed later. Not reviewed: ${m.settled.notReviewed.prs}, ${m.settled.notReviewed.fixedLater.count} fixed later. (Teams choose what gets reviewed: not a comparison.)`,
50
+ ` Lessons: ${m.lessons.awaitingDecision} waiting on a person, ${m.lessons.promotedFromEvidence} promoted from evidence, ${m.lessons.dismissed} dismissed, ${m.lessons.takenBack} taken back.`,
51
+ ];
52
+ }
@@ -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 { type AgentEvent, type LessonRecord, type ReviewLesson, type Story } from '@rigour-labs/core';
10
+ import { type OutcomeMetrics, type AgentEvent, type LessonRecord, type ReviewLesson, type Story } from '@rigour-labs/core';
11
11
  export interface LessonJourney {
12
12
  id: string;
13
13
  text: string;
@@ -47,6 +47,8 @@ export interface StudioLearning {
47
47
  reachedPr: number | null;
48
48
  }>;
49
49
  prRecorded: boolean;
50
+ /** What happened after merges this checkout read (core outcomes/metrics.ts); absent before `rigour outcomes` has run. */
51
+ outcomes?: OutcomeMetrics;
50
52
  }
51
53
  export declare function buildLearning(input: {
52
54
  now: Date;
@@ -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 { decideLesson, fixLessonPrefix, listKnowledgeLessons, readLessons } from '@rigour-labs/core';
10
+ import { decideLesson, fixLessonPrefix, localOutcomeMetrics, pendingDecision, 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;
@@ -78,9 +78,7 @@ function learnedFromPoints(points) {
78
78
  * or a candidate with a later fix on its lines (promote it, or dismiss the evidence).
79
79
  */
80
80
  function decisionFor(lesson) {
81
- if (lesson.state !== 'candidate')
82
- return { canDecide: false };
83
- const last = lesson.evidence.filter(e => e.kind === 'demoted' || e.kind === 'lines' || e.kind === 'reclassified' || e.kind === 'accepted' || e.kind === 'rejected' || e.kind === 'dismissed').at(-1);
81
+ const last = pendingDecision(lesson);
84
82
  if (last?.kind === 'reclassified')
85
83
  return { canDecide: true, reclassified: { detail: last.detail ?? '', evidence: lesson.evidence.filter(e => e.kind === 'outcome' || e.kind === 'lines').map(e => e.detail ?? '').filter(Boolean) } };
86
84
  if (last?.kind === 'demoted')
@@ -103,7 +101,9 @@ export function decideReviewLesson(cwd, body) {
103
101
  }
104
102
  export async function loadLearning(cwd, now = new Date(), weeks = WEEKS) {
105
103
  const roots = checkoutRoots(cwd);
106
- return buildLearning({ now, lessons: await listKnowledgeLessons(cwd), reviewLessons: readLessons(cwd), stories: storiesAcross(roots), events: eventsAcross(roots), weeks });
104
+ const learning = buildLearning({ now, lessons: await listKnowledgeLessons(cwd), reviewLessons: readLessons(cwd), stories: storiesAcross(roots), events: eventsAcross(roots), weeks });
105
+ const outcomes = localOutcomeMetrics(cwd);
106
+ return outcomes ? { ...learning, outcomes } : learning;
107
107
  }
108
108
  /**
109
109
  * "Fixed before: Credential header follows redirects (semantic-bugs). The header…" → the defect,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rigour-labs/cli",
3
- "version": "6.9.0-rc.3",
3
+ "version": "6.9.0-rc.4",
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.9.0-rc.3"
62
+ "@rigour-labs/core": "6.9.0-rc.4"
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.9.0-rc.3"
68
+ "@rigour-labs/studio": "6.9.0-rc.4"
69
69
  },
70
70
  "scripts": {
71
71
  "build": "tsc && pnpm bundle-studio",