@rigour-labs/cli 6.10.0 → 6.10.1-rc.1

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.
@@ -778,6 +778,8 @@ export async function hooksCheckCommand(cwd, options = {}) {
778
778
  }),
779
779
  logStudioEvent(root, {
780
780
  type: 'hook_check', requestId, outcome, status: repoResult.status, agentId,
781
+ // Only a --block hook stops the edit; without it the findings are reported and the agent carries on.
782
+ blocked: !!options.block && repoResult.status === 'fail',
781
783
  files: repoFiles, summary: `${repoFiles.length} file(s), ${repoResult.failures.length} finding(s)`,
782
784
  findings: repoResult.failures.slice(0, 10).map(f => ({ gate: f.gate, file: f.file, line: f.line, message: f.message, severity: f.severity })),
783
785
  }),
@@ -1,5 +1,5 @@
1
1
  import { type AgentEvent, type LedgerEntry, type Story } from '@rigour-labs/core';
2
- export type ActivityKind = 'stopped' | 'fixed' | 'checked' | 'reviewed' | 'taught' | 'pr';
2
+ export type ActivityKind = 'stopped' | 'reported' | 'fixed' | 'checked' | 'reviewed' | 'taught' | 'pr';
3
3
  export interface ActivityItem {
4
4
  at: string;
5
5
  kind: ActivityKind;
@@ -19,7 +19,7 @@ export interface ActivitySession {
19
19
  counts: Record<ActivityKind, number> & {
20
20
  reviewedFixed: number;
21
21
  };
22
- /** What a person should see: blocks, fixes, PR catches, fixes found in review. */
22
+ /** What a person should see: blocks, findings reported on an edit, fixes, PR catches, fixes found in review. */
23
23
  highlights: ActivityItem[];
24
24
  /** The routine rest, shown on request. */
25
25
  rest: ActivityItem[];
@@ -30,7 +30,7 @@ export function readableFunction(name, file) {
30
30
  }
31
31
  /** A gap this long between two things Rigour did starts a new session. */
32
32
  const SESSION_GAP_MS = 45 * 60 * 1000;
33
- const IMPORTANT = ['stopped', 'fixed', 'pr'];
33
+ const IMPORTANT = ['stopped', 'reported', 'fixed', 'pr'];
34
34
  /** Items (newest first) grouped into working sessions, each summarised. */
35
35
  export function groupSessions(items) {
36
36
  const sessions = [];
@@ -43,7 +43,7 @@ export function groupSessions(items) {
43
43
  sessions.push([item]);
44
44
  }
45
45
  return sessions.map(list => {
46
- const counts = { stopped: 0, fixed: 0, checked: 0, reviewed: 0, taught: 0, pr: 0, reviewedFixed: 0 };
46
+ const counts = { stopped: 0, reported: 0, fixed: 0, checked: 0, reviewed: 0, taught: 0, pr: 0, reviewedFixed: 0 };
47
47
  for (const item of list) {
48
48
  counts[item.kind]++;
49
49
  if (item.kind === 'reviewed' && item.text.startsWith('Fixed '))
@@ -62,7 +62,11 @@ function fromEvent(event) {
62
62
  const files = (raw.files ?? []).join(', ');
63
63
  if (findings.length === 0)
64
64
  return [{ at, kind: 'checked', text: `Checked an edit to ${files || 'a file'}: nothing found` }];
65
- return [{ at, kind: 'stopped', text: `Stopped an edit to ${files}: ${findings.map(f => f.message).filter(Boolean).join('; ')}` }];
65
+ const found = findings.map(f => f.message).filter(Boolean).join('; ');
66
+ // Stopped only when the hook ran with --block and said so; an event without the flag never claims a block.
67
+ return [event.blocked
68
+ ? { at, kind: 'stopped', text: `Stopped an edit to ${files}: ${found}` }
69
+ : { at, kind: 'reported', text: `Reported on an edit to ${files}: ${found}` }];
66
70
  }
67
71
  case 'stop_review':
68
72
  return [event.blocked
@@ -0,0 +1 @@
1
+ export declare function repoName(cwd: string): string;
@@ -0,0 +1,24 @@
1
+ /**
2
+ * What Studio's header names the repository by: the origin remote's repository name, else the checkout's folder name.
3
+ * Never its absolute path (which carries the person's username into every screenshot), and never package.json's name
4
+ * and version, which name a package, not the repository.
5
+ */
6
+ import { execFileSync } from 'child_process';
7
+ import path from 'path';
8
+ export function repoName(cwd) {
9
+ try {
10
+ const url = execFileSync('git', ['remote', 'get-url', 'origin'], { cwd, encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).trim();
11
+ const name = /([^/:]+?)(?:\.git)?\/?$/.exec(url)?.[1];
12
+ if (name)
13
+ return name;
14
+ }
15
+ catch {
16
+ // No origin: the folder.
17
+ }
18
+ try {
19
+ return path.basename(execFileSync('git', ['rev-parse', '--show-toplevel'], { cwd, encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).trim());
20
+ }
21
+ catch {
22
+ return path.basename(path.resolve(cwd));
23
+ }
24
+ }
@@ -126,8 +126,6 @@ async function handleApiRequest(req, res, url, ctx) {
126
126
  }
127
127
  if (url.pathname === '/api/info') {
128
128
  try {
129
- const pkgPath = path.join(cwd, 'package.json');
130
- const pkg = (await fs.pathExists(pkgPath)) ? await fs.readJson(pkgPath) : {};
131
129
  const __dirname = path.dirname(new URL(import.meta.url).pathname);
132
130
  const cliPkgPath = path.join(__dirname, '../../package.json');
133
131
  const mcpPkgCandidates = [
@@ -144,14 +142,10 @@ async function handleApiRequest(req, res, url, ctx) {
144
142
  }
145
143
  }
146
144
  const studioVersion = resolveStudioVersion(cliPkg.version, mcpVersion);
145
+ const { repoName } = await import('./studio-info.js');
146
+ // The repository's name only: never its path (the person's username in every screenshot), never a package's.
147
147
  sendJson(res, 200, {
148
- name: pkg.name || path.basename(cwd),
149
- projectName: pkg.name || path.basename(cwd),
150
- path: cwd,
151
- projectPath: cwd,
152
- // null, not a made-up 0.0.0, when the project declares no version
153
- version: pkg.version || null,
154
- projectVersion: pkg.version || null,
148
+ projectName: repoName(cwd),
155
149
  branch: currentBranch(cwd),
156
150
  teamSync: Boolean(await (await import('@rigour-labs/core')).loadTeamConfiguration()),
157
151
  studioVersion,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rigour-labs/cli",
3
- "version": "6.10.0",
3
+ "version": "6.10.1-rc.1",
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.10.0"
62
+ "@rigour-labs/core": "6.10.1-rc.1"
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.10.0"
68
+ "@rigour-labs/studio": "6.10.1-rc.1"
69
69
  },
70
70
  "scripts": {
71
71
  "build": "tsc && pnpm bundle-studio",