@rigour-labs/core 6.11.1-rc.2 → 6.11.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/gates/base.d.ts +2 -0
- package/dist/gates/language-adapters/python-adapter.js +2 -1
- package/dist/gates/language-adapters/types.d.ts +6 -3
- package/dist/gates/language-adapters/types.js +10 -2
- package/dist/gates/logic-drift-git-base.d.ts +2 -0
- package/dist/gates/logic-drift-git-base.js +2 -0
- package/dist/gates/logic-drift.js +2 -2
- package/dist/gates/runner.js +8 -1
- package/dist/gates/style-drift-rules.d.ts +0 -4
- package/dist/gates/style-drift-rules.js +0 -19
- package/dist/gates/style-drift.js +6 -3
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/services/terminal-renderer.d.ts +2 -0
- package/dist/services/terminal-renderer.js +4 -1
- package/dist/types/index.d.ts +4 -0
- package/dist/types/index.js +2 -0
- package/dist/utils/user-state.d.ts +11 -1
- package/dist/utils/user-state.js +42 -2
- package/package.json +6 -6
package/dist/gates/base.d.ts
CHANGED
|
@@ -8,6 +8,8 @@ export interface GateContext {
|
|
|
8
8
|
patterns?: string[];
|
|
9
9
|
/** Shared file cache across gates — reduces memory ~80% on large repos */
|
|
10
10
|
fileCache?: FileSystemCache;
|
|
11
|
+
/** A gate that could not check (nothing to compare with) says why: the run shows SKIP, never PASS. */
|
|
12
|
+
skip?: (reason: string) => void;
|
|
11
13
|
}
|
|
12
14
|
export declare abstract class Gate {
|
|
13
15
|
readonly id: string;
|
|
@@ -104,7 +104,8 @@ class PythonAdapter {
|
|
|
104
104
|
if (match && !line.includes('def') && !line.includes('class')) {
|
|
105
105
|
const name = match[1];
|
|
106
106
|
// Distinguish constants from regular variables
|
|
107
|
-
|
|
107
|
+
// A private constant (`_RETRY_DELAYS`) is a constant too: the same reading classifyCasing gives it.
|
|
108
|
+
const kind = classifyCasing(name) === 'SCREAMING_SNAKE' ? 'constant' : 'variable';
|
|
108
109
|
patterns.push({
|
|
109
110
|
name, kind,
|
|
110
111
|
convention: classifyCasing(name),
|
|
@@ -53,8 +53,11 @@ export interface NamingPattern {
|
|
|
53
53
|
kind: 'function' | 'class' | 'variable' | 'constant' | 'method';
|
|
54
54
|
convention: NamingConvention;
|
|
55
55
|
}
|
|
56
|
-
export type NamingConvention = 'camelCase' | 'PascalCase' | 'snake_case' | 'SCREAMING_SNAKE' | 'kebab-case' | 'other'
|
|
56
|
+
export type NamingConvention = 'camelCase' | 'PascalCase' | 'snake_case' | 'SCREAMING_SNAKE' | 'kebab-case' | 'other'
|
|
57
|
+
/** One lowercase word (`run`, `data`): camelCase and snake_case alike, so evidence of neither. */
|
|
58
|
+
| 'ambiguous';
|
|
57
59
|
/**
|
|
58
|
-
* Classify a name into its casing convention.
|
|
60
|
+
* Classify a name into its casing convention. Leading underscores mark privacy, not casing (`_load_rows` is
|
|
61
|
+
* snake_case, `_Private` PascalCase), and a dunder (`__init__`) is the language's own name, so it is ambiguous.
|
|
59
62
|
*/
|
|
60
|
-
export declare function classifyCasing(
|
|
63
|
+
export declare function classifyCasing(raw: string): NamingConvention;
|
|
@@ -5,13 +5,21 @@
|
|
|
5
5
|
* Gates use these adapters instead of inline `if ext === '.py'` chains.
|
|
6
6
|
*/
|
|
7
7
|
/**
|
|
8
|
-
* Classify a name into its casing convention.
|
|
8
|
+
* Classify a name into its casing convention. Leading underscores mark privacy, not casing (`_load_rows` is
|
|
9
|
+
* snake_case, `_Private` PascalCase), and a dunder (`__init__`) is the language's own name, so it is ambiguous.
|
|
9
10
|
*/
|
|
10
|
-
export function classifyCasing(
|
|
11
|
+
export function classifyCasing(raw) {
|
|
12
|
+
if (/^__\w+__$/.test(raw))
|
|
13
|
+
return 'ambiguous';
|
|
14
|
+
const name = raw.replace(/^_+/, '');
|
|
15
|
+
if (!name)
|
|
16
|
+
return 'other';
|
|
11
17
|
if (/^[A-Z][A-Z0-9_]*$/.test(name))
|
|
12
18
|
return 'SCREAMING_SNAKE';
|
|
13
19
|
if (/^[A-Z][a-zA-Z0-9]*$/.test(name))
|
|
14
20
|
return 'PascalCase';
|
|
21
|
+
if (/^[a-z][a-z0-9]*$/.test(name))
|
|
22
|
+
return 'ambiguous';
|
|
15
23
|
if (/^[a-z][a-zA-Z0-9]*$/.test(name))
|
|
16
24
|
return 'camelCase';
|
|
17
25
|
if (/^[a-z][a-z0-9_]*$/.test(name))
|
|
@@ -5,6 +5,8 @@ export interface GitLogicBase {
|
|
|
5
5
|
changedFiles: Set<string>;
|
|
6
6
|
readAtBase: (file: string) => string | null;
|
|
7
7
|
}
|
|
8
|
+
/** Why a check that compares with the main branch could not run in a git checkout (resolveGitLogicBase gave null). */
|
|
9
|
+
export declare const NO_GIT_BASE = "nothing to compare with: no main branch (GITHUB_BASE_REF, origin/main, main, origin/master or master), or run from below the repository root";
|
|
8
10
|
export declare function isGitWorktree(cwd: string): boolean;
|
|
9
11
|
export interface BranchBase {
|
|
10
12
|
/** The main branch as found: GITHUB_BASE_REF, else origin/main, main, origin/master, master. */
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { execFileSync } from 'node:child_process';
|
|
2
|
+
/** Why a check that compares with the main branch could not run in a git checkout (resolveGitLogicBase gave null). */
|
|
3
|
+
export const NO_GIT_BASE = 'nothing to compare with: no main branch (GITHUB_BASE_REF, origin/main, main, origin/master or master), or run from below the repository root';
|
|
2
4
|
export function isGitWorktree(cwd) {
|
|
3
5
|
return git(cwd, ['rev-parse', '--is-inside-work-tree'])?.trim() === 'true';
|
|
4
6
|
}
|
|
@@ -26,7 +26,7 @@ import { FileScanner } from '../utils/scanner.js';
|
|
|
26
26
|
import { Logger } from '../utils/logger.js';
|
|
27
27
|
import { languageAdapters } from './language-adapters/index.js';
|
|
28
28
|
import { extractCallSequence, isDangerousMutation } from './logic-drift-extractors.js';
|
|
29
|
-
import { isGitWorktree, resolveGitLogicBase } from './logic-drift-git-base.js';
|
|
29
|
+
import { NO_GIT_BASE, isGitWorktree, resolveGitLogicBase } from './logic-drift-git-base.js';
|
|
30
30
|
import { isScoped } from '../utils/scope.js';
|
|
31
31
|
import fs from 'fs-extra';
|
|
32
32
|
import path from 'path';
|
|
@@ -60,7 +60,7 @@ export class LogicDriftGate extends Gate {
|
|
|
60
60
|
// In Git worktrees, compare only files changed from an immutable base.
|
|
61
61
|
const gitBase = resolveGitLogicBase(context.cwd);
|
|
62
62
|
if (!gitBase && isGitWorktree(context.cwd)) {
|
|
63
|
-
|
|
63
|
+
context.skip?.(NO_GIT_BASE);
|
|
64
64
|
return [];
|
|
65
65
|
}
|
|
66
66
|
const scanFiles = gitBase ? files.filter(file => gitBase.changedFiles.has(file)) : files;
|
package/dist/gates/runner.js
CHANGED
|
@@ -145,6 +145,7 @@ export class GateRunner {
|
|
|
145
145
|
const start = Date.now();
|
|
146
146
|
const failures = [];
|
|
147
147
|
const summary = {};
|
|
148
|
+
const skips = {};
|
|
148
149
|
const ignore = this.config.ignore;
|
|
149
150
|
// 0. Run Context Discovery
|
|
150
151
|
let record;
|
|
@@ -162,11 +163,16 @@ export class GateRunner {
|
|
|
162
163
|
gateIndex++;
|
|
163
164
|
try {
|
|
164
165
|
onProgress?.(` [${gateIndex}/${totalGates}] Running ${gate.id}...`);
|
|
165
|
-
|
|
166
|
+
let skipped;
|
|
167
|
+
const gateFailures = await gate.run({ cwd, record, ignore, patterns, fileCache, skip: reason => { skipped = reason; } });
|
|
166
168
|
if (gateFailures.length > 0) {
|
|
167
169
|
failures.push(...gateFailures);
|
|
168
170
|
summary[gate.id] = 'FAIL';
|
|
169
171
|
}
|
|
172
|
+
else if (skipped !== undefined) {
|
|
173
|
+
summary[gate.id] = 'SKIP';
|
|
174
|
+
skips[gate.id] = skipped;
|
|
175
|
+
}
|
|
170
176
|
else {
|
|
171
177
|
summary[gate.id] = 'PASS';
|
|
172
178
|
}
|
|
@@ -299,6 +305,7 @@ export class GateRunner {
|
|
|
299
305
|
const report = {
|
|
300
306
|
status,
|
|
301
307
|
summary,
|
|
308
|
+
...(Object.keys(skips).length ? { skips } : {}),
|
|
302
309
|
failures,
|
|
303
310
|
stats: {
|
|
304
311
|
duration_ms: Date.now() - start,
|
|
@@ -3,10 +3,6 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Contains per-language naming convention rules and naming pattern regexes.
|
|
5
5
|
*/
|
|
6
|
-
/**
|
|
7
|
-
* Casing classification rules
|
|
8
|
-
*/
|
|
9
|
-
export declare function classifyCasing(name: string): 'camelCase' | 'snake_case' | 'PascalCase' | 'SCREAMING_SNAKE' | null;
|
|
10
6
|
/**
|
|
11
7
|
* Function name pattern for JavaScript
|
|
12
8
|
*/
|
|
@@ -3,25 +3,6 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Contains per-language naming convention rules and naming pattern regexes.
|
|
5
5
|
*/
|
|
6
|
-
/**
|
|
7
|
-
* Casing classification rules
|
|
8
|
-
*/
|
|
9
|
-
export function classifyCasing(name) {
|
|
10
|
-
if (name.startsWith('_') || name.length <= 1)
|
|
11
|
-
return null;
|
|
12
|
-
if (/^[A-Z][A-Z0-9_]+$/.test(name)) {
|
|
13
|
-
return 'SCREAMING_SNAKE';
|
|
14
|
-
}
|
|
15
|
-
else if (/^[A-Z]/.test(name)) {
|
|
16
|
-
return 'PascalCase';
|
|
17
|
-
}
|
|
18
|
-
else if (name.includes('_')) {
|
|
19
|
-
return 'snake_case';
|
|
20
|
-
}
|
|
21
|
-
else {
|
|
22
|
-
return 'camelCase';
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
6
|
/**
|
|
26
7
|
* Function name pattern for JavaScript
|
|
27
8
|
*/
|
|
@@ -25,7 +25,7 @@ import { Logger } from '../utils/logger.js';
|
|
|
25
25
|
import { languageAdapters } from './language-adapters/index.js';
|
|
26
26
|
import { extractComparableJsNames } from './js-style-context.js';
|
|
27
27
|
import { isScoped } from '../utils/scope.js';
|
|
28
|
-
import { filesAtCommit, isGitWorktree, readManyAtCommit, resolveGitLogicBase, untrackedFiles } from './logic-drift-git-base.js';
|
|
28
|
+
import { filesAtCommit, isGitWorktree, NO_GIT_BASE, readManyAtCommit, resolveGitLogicBase, untrackedFiles } from './logic-drift-git-base.js';
|
|
29
29
|
import { TRY_CATCH_PATTERN, CATCH_PATTERN, RESULT_TYPE_PATTERN, NAMED_IMPORT_PATTERN, WILDCARD_IMPORT_PATTERN, SIDE_EFFECT_IMPORT_PATTERN, DEFAULT_IMPORT_PATTERN, countQuotes, } from './style-drift-rules.js';
|
|
30
30
|
import fs from 'fs-extra';
|
|
31
31
|
import path from 'path';
|
|
@@ -59,7 +59,7 @@ export class StyleDriftGate extends Gate {
|
|
|
59
59
|
// can change a verdict, and a .rigour/style-baseline.json left by an older version is never read.
|
|
60
60
|
const gitBase = resolveGitLogicBase(context.cwd);
|
|
61
61
|
if (!gitBase && isGitWorktree(context.cwd)) {
|
|
62
|
-
|
|
62
|
+
context.skip?.(NO_GIT_BASE);
|
|
63
63
|
return [];
|
|
64
64
|
}
|
|
65
65
|
if (gitBase)
|
|
@@ -210,10 +210,13 @@ export class StyleDriftGate extends Gate {
|
|
|
210
210
|
? extractComparableJsNames(content, filePath)
|
|
211
211
|
: adapter.extractNamingPatterns(content);
|
|
212
212
|
for (const pattern of namingPatterns) {
|
|
213
|
+
if (pattern.convention === 'ambiguous')
|
|
214
|
+
continue; // a one-word name says nothing about the casing
|
|
213
215
|
if (pattern.kind === 'function' || pattern.kind === 'method') {
|
|
214
216
|
fp.naming.functions[pattern.convention]++;
|
|
215
217
|
}
|
|
216
|
-
else if (pattern.kind === 'variable'
|
|
218
|
+
else if (pattern.kind === 'variable') {
|
|
219
|
+
// A constant follows the constant convention (`MAX_ROWS`), never the variables': it is not compared.
|
|
217
220
|
fp.naming.variables[pattern.convention]++;
|
|
218
221
|
}
|
|
219
222
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ export { FrontendSecretExposureGate } from './gates/frontend-secret-exposure.js'
|
|
|
11
11
|
export * from './utils/logger.js';
|
|
12
12
|
export { normalizeScopePatterns, isScoped } from './utils/scope.js';
|
|
13
13
|
export { deepAnalysisError } from './utils/deep-status.js';
|
|
14
|
-
export { rigourUserDir, repoStateDir } from './utils/user-state.js';
|
|
14
|
+
export { rigourUserDir, repoStateDir, legacyStateNote } from './utils/user-state.js';
|
|
15
15
|
export { locateTransformers, semanticRuntimeDir, semanticRuntimeInstalled, TRANSFORMERS_SPEC } from './pattern-index/semantic-runtime.js';
|
|
16
16
|
export { reviewChange, toReviewFinding, type ReviewInput, type ReviewResult, type ReviewFinding } from './review/review.js';
|
|
17
17
|
export { splitByChangedLines, type ChangedLineSplit } from './review/changed-lines.js';
|
package/dist/index.js
CHANGED
|
@@ -11,7 +11,7 @@ export { FrontendSecretExposureGate } from './gates/frontend-secret-exposure.js'
|
|
|
11
11
|
export * from './utils/logger.js';
|
|
12
12
|
export { normalizeScopePatterns, isScoped } from './utils/scope.js';
|
|
13
13
|
export { deepAnalysisError } from './utils/deep-status.js';
|
|
14
|
-
export { rigourUserDir, repoStateDir } from './utils/user-state.js';
|
|
14
|
+
export { rigourUserDir, repoStateDir, legacyStateNote } from './utils/user-state.js';
|
|
15
15
|
export { locateTransformers, semanticRuntimeDir, semanticRuntimeInstalled, TRANSFORMERS_SPEC } from './pattern-index/semantic-runtime.js';
|
|
16
16
|
export { reviewChange, toReviewFinding } from './review/review.js';
|
|
17
17
|
export { splitByChangedLines } from './review/changed-lines.js';
|
|
@@ -16,6 +16,8 @@ export interface RenderOptions {
|
|
|
16
16
|
export interface GateResult {
|
|
17
17
|
id: string;
|
|
18
18
|
status: Status;
|
|
19
|
+
/** Why a SKIP: the check could not check. */
|
|
20
|
+
reason?: string;
|
|
19
21
|
}
|
|
20
22
|
export declare function renderScoreGauge(score: number, label: string): string;
|
|
21
23
|
export declare function renderSeveritySection(failures: Failure[], severity: Severity, maxItems?: number): string;
|
|
@@ -65,6 +65,9 @@ export function renderGateGrid(gates) {
|
|
|
65
65
|
const row = entries.slice(i, i + 3).map(e => e.padEnd(22)).join('');
|
|
66
66
|
lines.push(` ${row}`);
|
|
67
67
|
}
|
|
68
|
+
for (const g of gates)
|
|
69
|
+
if (g.status === 'SKIP' && g.reason)
|
|
70
|
+
lines.push(chalk.dim(` \u{23ED} ${g.id} skipped: ${g.reason}`));
|
|
68
71
|
return lines.join('\n');
|
|
69
72
|
}
|
|
70
73
|
// ── Brain Status ───────────────────────────────────────────────────
|
|
@@ -155,7 +158,7 @@ export function renderFullReport(report, options = {}) {
|
|
|
155
158
|
}
|
|
156
159
|
// Gate grid from report summary
|
|
157
160
|
if (report.summary) {
|
|
158
|
-
const gates = Object.entries(report.summary).map(([id, status]) => ({ id, status }));
|
|
161
|
+
const gates = Object.entries(report.summary).map(([id, status]) => ({ id, status, reason: report.skips?.[id] }));
|
|
159
162
|
if (gates.length > 0) {
|
|
160
163
|
boxContent.push(renderGateGrid(gates));
|
|
161
164
|
boxContent.push('');
|
package/dist/types/index.d.ts
CHANGED
|
@@ -3435,6 +3435,8 @@ export type Failure = z.infer<typeof FailureSchema>;
|
|
|
3435
3435
|
export declare const ReportSchema: z.ZodObject<{
|
|
3436
3436
|
status: z.ZodEnum<["PASS", "FAIL", "SKIP", "ERROR"]>;
|
|
3437
3437
|
summary: z.ZodRecord<z.ZodString, z.ZodEnum<["PASS", "FAIL", "SKIP", "ERROR"]>>;
|
|
3438
|
+
/** Why a check reported SKIP: it could not check (for example, no main branch to compare with). */
|
|
3439
|
+
skips: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
3438
3440
|
failures: z.ZodArray<z.ZodObject<{
|
|
3439
3441
|
id: z.ZodString;
|
|
3440
3442
|
title: z.ZodString;
|
|
@@ -3764,6 +3766,7 @@ export declare const ReportSchema: z.ZodObject<{
|
|
|
3764
3766
|
category?: string | undefined;
|
|
3765
3767
|
advisory?: boolean | undefined;
|
|
3766
3768
|
}[];
|
|
3769
|
+
skips?: Record<string, string> | undefined;
|
|
3767
3770
|
}, {
|
|
3768
3771
|
stats: {
|
|
3769
3772
|
duration_ms: number;
|
|
@@ -3828,6 +3831,7 @@ export declare const ReportSchema: z.ZodObject<{
|
|
|
3828
3831
|
category?: string | undefined;
|
|
3829
3832
|
advisory?: boolean | undefined;
|
|
3830
3833
|
}[];
|
|
3834
|
+
skips?: Record<string, string> | undefined;
|
|
3831
3835
|
}>;
|
|
3832
3836
|
export type Report = z.infer<typeof ReportSchema>;
|
|
3833
3837
|
/** Options passed from CLI --deep / --pro / --max / -k flags */
|
package/dist/types/index.js
CHANGED
|
@@ -521,6 +521,8 @@ export const FailureSchema = z.object({
|
|
|
521
521
|
export const ReportSchema = z.object({
|
|
522
522
|
status: StatusSchema,
|
|
523
523
|
summary: z.record(StatusSchema),
|
|
524
|
+
/** Why a check reported SKIP: it could not check (for example, no main branch to compare with). */
|
|
525
|
+
skips: z.record(z.string()).optional(),
|
|
524
526
|
failures: z.array(FailureSchema),
|
|
525
527
|
stats: z.object({
|
|
526
528
|
duration_ms: z.number(),
|
|
@@ -1,5 +1,15 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/**
|
|
2
|
+
* The home Rigour keeps its state under (`<home>/.rigour`): RIGOUR_HOME when set (a profile, a sandbox, tests),
|
|
3
|
+
* else the OS home. A RIGOUR_HOME ending in `.rigour` names the state directory itself, so its parent is the home.
|
|
4
|
+
* Earlier versions kept state one level deeper (`<RIGOUR_HOME>/.rigour`): where that holds state, it stays in use
|
|
5
|
+
* and nothing is moved (legacyStateNote says how).
|
|
6
|
+
*/
|
|
2
7
|
export declare function rigourHome(): string;
|
|
8
|
+
/**
|
|
9
|
+
* For `rigour doctor`: state an earlier version wrote under `<RIGOUR_HOME>/.rigour`, still in use, and how to move
|
|
10
|
+
* it; or, when the named directory holds state of its own too, both places. Nothing is moved for anyone.
|
|
11
|
+
*/
|
|
12
|
+
export declare function legacyStateNote(): string | undefined;
|
|
3
13
|
/** The user's Rigour directory: `<rigourHome()>/.rigour`. Every piece of Rigour's own state lives under it. */
|
|
4
14
|
export declare function rigourUserDir(): string;
|
|
5
15
|
/**
|
package/dist/utils/user-state.js
CHANGED
|
@@ -2,9 +2,49 @@ import crypto from 'crypto';
|
|
|
2
2
|
import fs from 'fs';
|
|
3
3
|
import os from 'os';
|
|
4
4
|
import path from 'path';
|
|
5
|
-
/**
|
|
5
|
+
/**
|
|
6
|
+
* The home Rigour keeps its state under (`<home>/.rigour`): RIGOUR_HOME when set (a profile, a sandbox, tests),
|
|
7
|
+
* else the OS home. A RIGOUR_HOME ending in `.rigour` names the state directory itself, so its parent is the home.
|
|
8
|
+
* Earlier versions kept state one level deeper (`<RIGOUR_HOME>/.rigour`): where that holds state, it stays in use
|
|
9
|
+
* and nothing is moved (legacyStateNote says how).
|
|
10
|
+
*/
|
|
6
11
|
export function rigourHome() {
|
|
7
|
-
|
|
12
|
+
const set = process.env.RIGOUR_HOME;
|
|
13
|
+
if (!set)
|
|
14
|
+
return os.homedir();
|
|
15
|
+
if (path.basename(path.resolve(set)) !== '.rigour')
|
|
16
|
+
return set;
|
|
17
|
+
return hasState(path.join(set, '.rigour')) ? set : path.dirname(path.resolve(set));
|
|
18
|
+
}
|
|
19
|
+
function hasState(dir) {
|
|
20
|
+
try {
|
|
21
|
+
return fs.readdirSync(dir).length > 0;
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* For `rigour doctor`: state an earlier version wrote under `<RIGOUR_HOME>/.rigour`, still in use, and how to move
|
|
29
|
+
* it; or, when the named directory holds state of its own too, both places. Nothing is moved for anyone.
|
|
30
|
+
*/
|
|
31
|
+
export function legacyStateNote() {
|
|
32
|
+
const set = process.env.RIGOUR_HOME;
|
|
33
|
+
if (!set || path.basename(path.resolve(set)) !== '.rigour')
|
|
34
|
+
return undefined;
|
|
35
|
+
const named = path.resolve(set);
|
|
36
|
+
const doubled = path.join(named, '.rigour');
|
|
37
|
+
if (!hasState(doubled))
|
|
38
|
+
return undefined;
|
|
39
|
+
const own = (() => { try {
|
|
40
|
+
return fs.readdirSync(named).filter(entry => entry !== '.rigour').length > 0;
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return false;
|
|
44
|
+
} })();
|
|
45
|
+
return own
|
|
46
|
+
? `Rigour state is in both ${named} and ${doubled}. This run uses ${doubled}, where your tools have been writing; merge the two by hand if you need both.`
|
|
47
|
+
: `Rigour state is in ${doubled}, written by an earlier version. RIGOUR_HOME=${set} now names the state directory itself: to use ${named}, move the contents of ${doubled} up one level.`;
|
|
8
48
|
}
|
|
9
49
|
/** The user's Rigour directory: `<rigourHome()>/.rigour`. Every piece of Rigour's own state lives under it. */
|
|
10
50
|
export function rigourUserDir() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rigour-labs/core",
|
|
3
|
-
"version": "6.11.1
|
|
3
|
+
"version": "6.11.1",
|
|
4
4
|
"description": "Rigour's review engine: deterministic gates on changed lines, rules and lessons learned from your team's fixes, and per-check precision from what you fix versus dismiss, across TypeScript, JavaScript, Python, Go, Ruby and C#.",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=22.13"
|
|
@@ -75,11 +75,11 @@
|
|
|
75
75
|
"@anthropic-ai/sdk": "^0.132.1",
|
|
76
76
|
"pg": "^8.16.3",
|
|
77
77
|
"openai": "^5.23.2",
|
|
78
|
-
"@rigour-labs/brain-
|
|
79
|
-
"@rigour-labs/brain-
|
|
80
|
-
"@rigour-labs/brain-linux-
|
|
81
|
-
"@rigour-labs/brain-
|
|
82
|
-
"@rigour-labs/brain-
|
|
78
|
+
"@rigour-labs/brain-darwin-x64": "6.11.1",
|
|
79
|
+
"@rigour-labs/brain-linux-x64": "6.11.1",
|
|
80
|
+
"@rigour-labs/brain-linux-arm64": "6.11.1",
|
|
81
|
+
"@rigour-labs/brain-win-x64": "6.11.1",
|
|
82
|
+
"@rigour-labs/brain-darwin-arm64": "6.11.1"
|
|
83
83
|
},
|
|
84
84
|
"devDependencies": {
|
|
85
85
|
"@types/fs-extra": "^11.0.4",
|