@rigour-labs/cli 6.12.0-rc.1 → 6.12.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.
@@ -43,6 +43,11 @@ export interface LessonJourney {
43
43
  text: string;
44
44
  why: string;
45
45
  };
46
+ /** How far a review lesson reaches (core scopeLesson): its file, its folder, or every change; `hasFile` false for a team standard. */
47
+ reach?: {
48
+ scope: 'file' | 'folder' | 'repo';
49
+ hasFile: boolean;
50
+ };
46
51
  }
47
52
  export interface StudioLearning {
48
53
  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, 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, 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;
@@ -51,6 +51,7 @@ export function buildLearning(input) {
51
51
  reachedPr: null,
52
52
  ...decisionFor(l),
53
53
  ...(l.suggestedText ? { suggestedText: { text: l.suggestedText, why: l.suggestedWhy ?? 'reworded' } } : {}),
54
+ reach: { scope: l.scope ?? 'file', hasFile: !!l.file },
54
55
  })),
55
56
  // Lessons back to a candidate when outcomes stopped promoting come first: a person decides each once.
56
57
  ].sort((a, b) => Number(!!b.reclassified) - Number(!!a.reclassified) || b.learnedAt.localeCompare(a.learnedAt))
@@ -88,6 +89,10 @@ function decisionFor(lesson) {
88
89
  return { canDecide: true, suggested: { detail: last.detail ?? '', pr: last.pr, at: last.at ?? '' } };
89
90
  return { canDecide: false };
90
91
  }
92
+ /** The reason a person gave in Studio, else that they decided there. */
93
+ function studioWhy(why) {
94
+ return typeof why === 'string' && why.trim() ? why.trim() : 'decided in Studio';
95
+ }
91
96
  /** A person's decision on a review lesson from Studio, recorded as `rigour learn-reviews --promote / --reject` records it: with their git email, and final. */
92
97
  export function decideReviewLesson(cwd, body) {
93
98
  const { id, decision, why } = (body ?? {});
@@ -95,9 +100,26 @@ export function decideReviewLesson(cwd, body) {
95
100
  throw new Error('a review lesson id (12 hex characters) is required');
96
101
  if (decision === 'reworded')
97
102
  return rewordFromStudio(cwd, id);
103
+ if (decision === 'scope')
104
+ return scopeFromStudio(cwd, id, body.to, why);
98
105
  if (decision !== 'accepted' && decision !== 'rejected' && decision !== 'dismissed')
99
- throw new Error('decision is accepted, rejected, dismissed or reworded');
100
- const lesson = decideLesson(cwd, id, decision, personOf(cwd), typeof why === 'string' && why.trim() ? why.trim() : 'decided in Studio');
106
+ throw new Error('decision is accepted, rejected, dismissed, reworded or scope');
107
+ const lesson = decideLesson(cwd, id, decision, personOf(cwd), studioWhy(why));
108
+ if (!lesson)
109
+ throw new Error(`no review lesson ${id}`);
110
+ return { id: lesson.id, state: lesson.state };
111
+ }
112
+ /**
113
+ * A person sets how far a review lesson reaches from Studio, as `rigour learn-reviews --scope` records it: with their
114
+ * git email, so with no git email set it is refused, like a compiled check's decision.
115
+ */
116
+ function scopeFromStudio(cwd, id, to, why) {
117
+ if (to !== 'file' && to !== 'folder' && to !== 'repo')
118
+ throw new Error('to is file, folder or repo');
119
+ const by = personOf(cwd);
120
+ if (by === 'unknown')
121
+ throw new Error('no git email is set in this checkout (git config user.email): who decides how far a lesson reaches is recorded with it');
122
+ const lesson = scopeLesson(cwd, id, to, by, studioWhy(why));
101
123
  if (!lesson)
102
124
  throw new Error(`no review lesson ${id}`);
103
125
  return { id: lesson.id, state: lesson.state };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rigour-labs/cli",
3
- "version": "6.12.0-rc.1",
3
+ "version": "6.12.0",
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.0-rc.1"
62
+ "@rigour-labs/core": "6.12.0"
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.0-rc.1"
68
+ "@rigour-labs/studio": "6.12.0"
69
69
  },
70
70
  "scripts": {
71
71
  "build": "tsc && pnpm bundle-studio",