@rigour-labs/cli 6.10.0-rc.2 → 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.
- package/dist/commands/hooks.js +2 -0
- package/dist/commands/studio-activity.d.ts +2 -2
- package/dist/commands/studio-activity.js +7 -3
- package/dist/commands/studio-info.d.ts +1 -0
- package/dist/commands/studio-info.js +24 -0
- package/dist/commands/studio.js +3 -9
- package/package.json +3 -3
- package/studio-dist/assets/index-D0ngbwSa.js +166 -0
- package/studio-dist/assets/{index-D64sXWtB.css → index-UWYx4t8T.css} +1 -1
- package/studio-dist/index.html +3 -3
- package/studio-dist/assets/index-s5PnfZkK.js +0 -166
package/dist/commands/hooks.js
CHANGED
|
@@ -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
|
-
|
|
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
|
+
}
|
package/dist/commands/studio.js
CHANGED
|
@@ -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
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
68
|
+
"@rigour-labs/studio": "6.10.1-rc.1"
|
|
69
69
|
},
|
|
70
70
|
"scripts": {
|
|
71
71
|
"build": "tsc && pnpm bundle-studio",
|