@webpieces/rules-config 0.3.196 → 0.3.198

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webpieces/rules-config",
3
- "version": "0.3.196",
3
+ "version": "0.3.198",
4
4
  "description": "Shared webpieces.config.json loader. Single source of truth for validation rule configuration consumed by @webpieces/ai-hook-rules, @webpieces/code-rules, and @webpieces/nx-webpieces-rules.",
5
5
  "type": "commonjs",
6
6
  "main": "./src/index.js",
@@ -11,7 +11,7 @@ const DEFAULT_EXCLUDE_PATHS = [
11
11
  ];
12
12
  // On/off is driven by `mode` ("OFF" disables; an absent mode leaves a rule
13
13
  // on). Code-rules entries omit `mode` so each executor keeps its own default
14
- // scope; simple on/off rules declare `mode: 'ON'` explicitly.
14
+ // scope; structural rules declare `mode: 'RUN_EVERY_TIME'`, bash guards `mode: 'ON'`.
15
15
  // webpieces-disable no-any-unknown -- rule options are opaque at framework level
16
16
  exports.defaultRules = {
17
17
  'no-any-unknown': {},
@@ -24,15 +24,15 @@ exports.defaultRules = {
24
24
  'catch-error-pattern': {},
25
25
  'no-unmanaged-exceptions': {},
26
26
  'no-shell-substitution': { mode: 'ON' },
27
- 'no-file-import-cycles': { mode: 'ON' },
28
- 'runtime-architecture': { mode: 'ON', servicePaths: [], apiProjectPaths: [], allowedCycles: [] },
27
+ 'no-file-import-cycles': { mode: 'RUN_EVERY_TIME' },
28
+ 'runtime-architecture': { mode: 'RUN_EVERY_TIME', servicePaths: [], apiProjectPaths: [], allowedCycles: [] },
29
29
  'prisma-validate-dtos': {},
30
30
  'prisma-converter': {},
31
31
  'angular-no-direct-api-in-resolver': {},
32
32
  'no-symbol-di-tokens': {},
33
- 'nx-wiring': { mode: 'ON' },
33
+ 'nx-wiring': { mode: 'RUN_EVERY_TIME' },
34
34
  'validate-ts-in-src': {
35
- mode: 'MODIFIED_FILES',
35
+ mode: 'NEW_AND_MODIFIED_FILES',
36
36
  allowedRootFiles: ['jest.setup.ts'],
37
37
  excludePaths: [...DEFAULT_EXCLUDE_PATHS],
38
38
  },
@@ -1 +1 @@
1
- {"version":3,"file":"default-rules.js","sourceRoot":"","sources":["../../../../../packages/tooling/rules-config/src/default-rules.ts"],"names":[],"mappings":";;;AAAA,2DAA2D;AAC3D,4EAA4E;AAC5E,kEAAkE;AAClE,0EAA0E;AAC1E,MAAM,qBAAqB,GAAsB;IAC7C,cAAc,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;IACrC,WAAW,EAAE,mBAAmB;CACnC,CAAC;AAEF,2EAA2E;AAC3E,6EAA6E;AAC7E,8DAA8D;AAC9D,iFAAiF;AACpE,QAAA,YAAY,GAA4C;IACjE,gBAAgB,EAAE,EAAE;IACpB,iBAAiB,EAAE,EAAE;IACrB,gBAAgB,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE;IAChC,kBAAkB,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;IACjC,qBAAqB,EAAE,EAAE;IACzB,yBAAyB,EAAE,EAAE;IAC7B,gBAAgB,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE;IACzC,qBAAqB,EAAE,EAAE;IACzB,yBAAyB,EAAE,EAAE;IAC7B,uBAAuB,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;IACvC,uBAAuB,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;IACvC,sBAAsB,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,EAAE,eAAe,EAAE,EAAE,EAAE,aAAa,EAAE,EAAE,EAAE;IAChG,sBAAsB,EAAE,EAAE;IAC1B,kBAAkB,EAAE,EAAE;IACtB,mCAAmC,EAAE,EAAE;IACvC,qBAAqB,EAAE,EAAE;IACzB,WAAW,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;IAC3B,oBAAoB,EAAE;QAClB,IAAI,EAAE,gBAAgB;QACtB,gBAAgB,EAAE,CAAC,eAAe,CAAC;QACnC,YAAY,EAAE,CAAC,GAAG,qBAAqB,CAAC;KAC3C;IACD,aAAa,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE;IAC9B,uBAAuB,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,eAAe,EAAE,sCAAsC,EAAE;IAChG,mBAAmB,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;IACnC,yBAAyB,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;IACzC,kBAAkB,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;IAClC,uBAAuB,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;CAC1C,CAAC;AAEW,QAAA,eAAe,GAAsB,EAAE,CAAC","sourcesContent":["// Default holistic exclude list for the validate-ts-in-src\n// rules. Bare names match a directory segment at any depth; globs match the\n// workspace-relative path. `**/*.d.ts` (ambient declarations) and\n// `**/jest.config.ts` legitimately live outside src/ and are exempt here.\nconst DEFAULT_EXCLUDE_PATHS: readonly string[] = [\n 'node_modules', 'dist', '.nx', '.git',\n '**/*.d.ts', '**/jest.config.ts',\n];\n\n// On/off is driven by `mode` (\"OFF\" disables; an absent mode leaves a rule\n// on). Code-rules entries omit `mode` so each executor keeps its own default\n// scope; simple on/off rules declare `mode: 'ON'` explicitly.\n// webpieces-disable no-any-unknown -- rule options are opaque at framework level\nexport const defaultRules: Record<string, Record<string, unknown>> = {\n 'no-any-unknown': {},\n 'no-implicit-any': {},\n 'max-file-lines': { limit: 900 },\n 'max-method-lines': { limit: 80 },\n 'require-return-type': {},\n 'no-inline-type-literals': {},\n 'no-destructure': { allowTopLevel: true },\n 'catch-error-pattern': {},\n 'no-unmanaged-exceptions': {},\n 'no-shell-substitution': { mode: 'ON' },\n 'no-file-import-cycles': { mode: 'ON' },\n 'runtime-architecture': { mode: 'ON', servicePaths: [], apiProjectPaths: [], allowedCycles: [] },\n 'prisma-validate-dtos': {},\n 'prisma-converter': {},\n 'angular-no-direct-api-in-resolver': {},\n 'no-symbol-di-tokens': {},\n 'nx-wiring': { mode: 'ON' },\n 'validate-ts-in-src': {\n mode: 'MODIFIED_FILES',\n allowedRootFiles: ['jest.setup.ts'],\n excludePaths: [...DEFAULT_EXCLUDE_PATHS],\n },\n 'no-js-files': { mode: 'OFF' },\n 'branch-creation-guard': { mode: 'ON', subBranchNaming: 'feature/<ticket>/<short-description>' },\n 'pr-creation-guard': { mode: 'ON' },\n 'merge-in-progress-guard': { mode: 'ON' },\n 'pr-merge-cleanup': { mode: 'ON' },\n 'no-direct-main-update': { mode: 'ON' },\n};\n\nexport const defaultRulesDir: readonly string[] = [];\n"]}
1
+ {"version":3,"file":"default-rules.js","sourceRoot":"","sources":["../../../../../packages/tooling/rules-config/src/default-rules.ts"],"names":[],"mappings":";;;AAAA,2DAA2D;AAC3D,4EAA4E;AAC5E,kEAAkE;AAClE,0EAA0E;AAC1E,MAAM,qBAAqB,GAAsB;IAC7C,cAAc,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;IACrC,WAAW,EAAE,mBAAmB;CACnC,CAAC;AAEF,2EAA2E;AAC3E,6EAA6E;AAC7E,sFAAsF;AACtF,iFAAiF;AACpE,QAAA,YAAY,GAA4C;IACjE,gBAAgB,EAAE,EAAE;IACpB,iBAAiB,EAAE,EAAE;IACrB,gBAAgB,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE;IAChC,kBAAkB,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;IACjC,qBAAqB,EAAE,EAAE;IACzB,yBAAyB,EAAE,EAAE;IAC7B,gBAAgB,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE;IACzC,qBAAqB,EAAE,EAAE;IACzB,yBAAyB,EAAE,EAAE;IAC7B,uBAAuB,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;IACvC,uBAAuB,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE;IACnD,sBAAsB,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE,YAAY,EAAE,EAAE,EAAE,eAAe,EAAE,EAAE,EAAE,aAAa,EAAE,EAAE,EAAE;IAC5G,sBAAsB,EAAE,EAAE;IAC1B,kBAAkB,EAAE,EAAE;IACtB,mCAAmC,EAAE,EAAE;IACvC,qBAAqB,EAAE,EAAE;IACzB,WAAW,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE;IACvC,oBAAoB,EAAE;QAClB,IAAI,EAAE,wBAAwB;QAC9B,gBAAgB,EAAE,CAAC,eAAe,CAAC;QACnC,YAAY,EAAE,CAAC,GAAG,qBAAqB,CAAC;KAC3C;IACD,aAAa,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE;IAC9B,uBAAuB,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,eAAe,EAAE,sCAAsC,EAAE;IAChG,mBAAmB,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;IACnC,yBAAyB,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;IACzC,kBAAkB,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;IAClC,uBAAuB,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;CAC1C,CAAC;AAEW,QAAA,eAAe,GAAsB,EAAE,CAAC","sourcesContent":["// Default holistic exclude list for the validate-ts-in-src\n// rules. Bare names match a directory segment at any depth; globs match the\n// workspace-relative path. `**/*.d.ts` (ambient declarations) and\n// `**/jest.config.ts` legitimately live outside src/ and are exempt here.\nconst DEFAULT_EXCLUDE_PATHS: readonly string[] = [\n 'node_modules', 'dist', '.nx', '.git',\n '**/*.d.ts', '**/jest.config.ts',\n];\n\n// On/off is driven by `mode` (\"OFF\" disables; an absent mode leaves a rule\n// on). Code-rules entries omit `mode` so each executor keeps its own default\n// scope; structural rules declare `mode: 'RUN_EVERY_TIME'`, bash guards `mode: 'ON'`.\n// webpieces-disable no-any-unknown -- rule options are opaque at framework level\nexport const defaultRules: Record<string, Record<string, unknown>> = {\n 'no-any-unknown': {},\n 'no-implicit-any': {},\n 'max-file-lines': { limit: 900 },\n 'max-method-lines': { limit: 80 },\n 'require-return-type': {},\n 'no-inline-type-literals': {},\n 'no-destructure': { allowTopLevel: true },\n 'catch-error-pattern': {},\n 'no-unmanaged-exceptions': {},\n 'no-shell-substitution': { mode: 'ON' },\n 'no-file-import-cycles': { mode: 'RUN_EVERY_TIME' },\n 'runtime-architecture': { mode: 'RUN_EVERY_TIME', servicePaths: [], apiProjectPaths: [], allowedCycles: [] },\n 'prisma-validate-dtos': {},\n 'prisma-converter': {},\n 'angular-no-direct-api-in-resolver': {},\n 'no-symbol-di-tokens': {},\n 'nx-wiring': { mode: 'RUN_EVERY_TIME' },\n 'validate-ts-in-src': {\n mode: 'NEW_AND_MODIFIED_FILES',\n allowedRootFiles: ['jest.setup.ts'],\n excludePaths: [...DEFAULT_EXCLUDE_PATHS],\n },\n 'no-js-files': { mode: 'OFF' },\n 'branch-creation-guard': { mode: 'ON', subBranchNaming: 'feature/<ticket>/<short-description>' },\n 'pr-creation-guard': { mode: 'ON' },\n 'merge-in-progress-guard': { mode: 'ON' },\n 'pr-merge-cleanup': { mode: 'ON' },\n 'no-direct-main-update': { mode: 'ON' },\n};\n\nexport const defaultRulesDir: readonly string[] = [];\n"]}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Shared git-diff + diff-scoping helpers for ALL rule validators (code-rules) and nx executors
3
+ * (nx-webpieces-rules). Centralized here in rules-config because it is the one package both of
4
+ * those depend on, and it already shells out to git (see skip-rule.ts).
5
+ *
6
+ * Before this module these functions were copy-pasted ~15× (one private copy per validator + the
7
+ * validate-ts-in-src executor). They are now defined once; every consumer imports from
8
+ * `@webpieces/rules-config`. The two historical variants are preserved as parameters:
9
+ * - `getChangedFiles(..., { tsOnly: false })` reproduces validate-dtos' all-files diff.
10
+ * - `detectBase` replaces both the nested-try and the ref-loop spellings (identical behavior).
11
+ */
12
+ /** A git diff range: the base ref to compare against and an optional head (else the working tree). */
13
+ export declare class DiffRange {
14
+ base?: string;
15
+ head?: string;
16
+ }
17
+ /** Options for getChangedFiles. `tsOnly` (default true) restricts to *.ts/*.tsx and drops test files. */
18
+ export declare class ChangedFilesOptions {
19
+ tsOnly?: boolean;
20
+ }
21
+ /**
22
+ * Auto-detect the diff base: the merge-base of HEAD with origin/main, falling back to local main.
23
+ * Returns null when neither ref resolves (e.g. shallow clone with no main) — callers treat null as
24
+ * "no base detected" and typically skip.
25
+ */
26
+ export declare function detectBase(workspaceRoot: string): string | null;
27
+ /**
28
+ * Resolve the diff range a rule should compare against. Honors nx's NX_BASE / NX_HEAD (set by
29
+ * `nx affected --base=.. --head=..`); when NX_BASE is unset, auto-detects via detectBase. A returned
30
+ * `base` of undefined means "could not determine a base" (caller should skip).
31
+ */
32
+ export declare function resolveBase(workspaceRoot: string): DiffRange;
33
+ /**
34
+ * Changed files between base and head (or base→working-tree when head is omitted). When head is
35
+ * omitted, untracked files are unioned in too (matching `nx affected`). `tsOnly` (default true)
36
+ * restricts to *.ts/*.tsx and drops test files; pass false for an all-files diff.
37
+ */
38
+ export declare function getChangedFiles(workspaceRoot: string, base: string, head?: string, opts?: ChangedFilesOptions): string[];
39
+ /**
40
+ * Diff content for a single file. When the file is untracked (and no head is given) a synthetic
41
+ * all-added diff is produced so new files count as fully-changed.
42
+ */
43
+ export declare function getFileDiff(workspaceRoot: string, file: string, base: string, head?: string): string;
44
+ /**
45
+ * Parse a unified diff and return the set of added/changed line numbers (the `+` lines per hunk).
46
+ * This is the basis of MODIFIED_CODE (line-level) scoping.
47
+ */
48
+ export declare function getChangedLineNumbers(diffContent: string): Set<number>;
49
+ /**
50
+ * Method names whose signature line is a `+` addition in the diff — the basis of "NEW" methods.
51
+ */
52
+ export declare function findNewMethodSignaturesInDiff(diffContent: string): Set<string>;
53
+ /**
54
+ * True if any line in [startLine, endLine] is in the changedLines set.
55
+ */
56
+ export declare function hasChangesInRange(startLine: number, endLine: number, changedLines: Set<number>): boolean;
57
+ /**
58
+ * True if a node (method/function) is newly added or has any changed line in its range.
59
+ */
60
+ export declare function isNewOrModified(name: string, startLine: number, endLine: number, changedLines: Set<number>, newMethodNames: Set<string>): boolean;
@@ -0,0 +1,232 @@
1
+ "use strict";
2
+ /**
3
+ * Shared git-diff + diff-scoping helpers for ALL rule validators (code-rules) and nx executors
4
+ * (nx-webpieces-rules). Centralized here in rules-config because it is the one package both of
5
+ * those depend on, and it already shells out to git (see skip-rule.ts).
6
+ *
7
+ * Before this module these functions were copy-pasted ~15× (one private copy per validator + the
8
+ * validate-ts-in-src executor). They are now defined once; every consumer imports from
9
+ * `@webpieces/rules-config`. The two historical variants are preserved as parameters:
10
+ * - `getChangedFiles(..., { tsOnly: false })` reproduces validate-dtos' all-files diff.
11
+ * - `detectBase` replaces both the nested-try and the ref-loop spellings (identical behavior).
12
+ */
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.ChangedFilesOptions = exports.DiffRange = void 0;
15
+ exports.detectBase = detectBase;
16
+ exports.resolveBase = resolveBase;
17
+ exports.getChangedFiles = getChangedFiles;
18
+ exports.getFileDiff = getFileDiff;
19
+ exports.getChangedLineNumbers = getChangedLineNumbers;
20
+ exports.findNewMethodSignaturesInDiff = findNewMethodSignaturesInDiff;
21
+ exports.hasChangesInRange = hasChangesInRange;
22
+ exports.isNewOrModified = isNewOrModified;
23
+ const tslib_1 = require("tslib");
24
+ const child_process_1 = require("child_process");
25
+ const fs = tslib_1.__importStar(require("fs"));
26
+ const path = tslib_1.__importStar(require("path"));
27
+ const to_error_1 = require("./to-error");
28
+ /** A git diff range: the base ref to compare against and an optional head (else the working tree). */
29
+ class DiffRange {
30
+ base;
31
+ head;
32
+ }
33
+ exports.DiffRange = DiffRange;
34
+ /** Options for getChangedFiles. `tsOnly` (default true) restricts to *.ts/*.tsx and drops test files. */
35
+ class ChangedFilesOptions {
36
+ tsOnly;
37
+ }
38
+ exports.ChangedFilesOptions = ChangedFilesOptions;
39
+ /**
40
+ * A file is "a test file" (excluded from diff-scoped rules) when it is a .spec/.test file or lives
41
+ * under a __tests__/ directory. Union of every per-validator filter so no consumer loses coverage.
42
+ */
43
+ function isTestFile(file) {
44
+ return file.includes('.spec.ts') || file.includes('.test.ts') || file.includes('__tests__/');
45
+ }
46
+ /**
47
+ * Auto-detect the diff base: the merge-base of HEAD with origin/main, falling back to local main.
48
+ * Returns null when neither ref resolves (e.g. shallow clone with no main) — callers treat null as
49
+ * "no base detected" and typically skip.
50
+ */
51
+ function detectBase(workspaceRoot) {
52
+ for (const ref of ['origin/main', 'main']) {
53
+ // eslint-disable-next-line @webpieces/no-unmanaged-exceptions
54
+ try {
55
+ const merged = (0, child_process_1.execSync)(`git merge-base HEAD ${ref}`, {
56
+ cwd: workspaceRoot, encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'],
57
+ }).trim();
58
+ if (merged)
59
+ return merged;
60
+ }
61
+ catch (err) {
62
+ const error = (0, to_error_1.toError)(err);
63
+ void error; // swallow — try the next ref
64
+ }
65
+ }
66
+ return null;
67
+ }
68
+ /**
69
+ * Resolve the diff range a rule should compare against. Honors nx's NX_BASE / NX_HEAD (set by
70
+ * `nx affected --base=.. --head=..`); when NX_BASE is unset, auto-detects via detectBase. A returned
71
+ * `base` of undefined means "could not determine a base" (caller should skip).
72
+ */
73
+ function resolveBase(workspaceRoot) {
74
+ const range = new DiffRange();
75
+ range.base = process.env['NX_BASE'];
76
+ range.head = process.env['NX_HEAD'];
77
+ if (!range.base) {
78
+ range.base = detectBase(workspaceRoot) ?? undefined;
79
+ }
80
+ return range;
81
+ }
82
+ /**
83
+ * Changed files between base and head (or base→working-tree when head is omitted). When head is
84
+ * omitted, untracked files are unioned in too (matching `nx affected`). `tsOnly` (default true)
85
+ * restricts to *.ts/*.tsx and drops test files; pass false for an all-files diff.
86
+ */
87
+ // webpieces-disable max-lines-new-methods -- git command handling with untracked files needs several code paths
88
+ function getChangedFiles(workspaceRoot, base, head, opts) {
89
+ const tsOnly = opts?.tsOnly ?? true;
90
+ const glob = tsOnly ? " -- '*.ts' '*.tsx'" : '';
91
+ const keep = (f) => f.length > 0 && (!tsOnly || !isTestFile(f));
92
+ // eslint-disable-next-line @webpieces/no-unmanaged-exceptions
93
+ try {
94
+ const diffTarget = head ? `${base} ${head}` : base;
95
+ const output = (0, child_process_1.execSync)(`git diff --name-only ${diffTarget}${glob}`, {
96
+ cwd: workspaceRoot,
97
+ encoding: 'utf-8',
98
+ });
99
+ const changedFiles = output.trim().split('\n').filter(keep);
100
+ // Working-tree comparison (no head): also include untracked files, as nx affected does.
101
+ if (!head) {
102
+ // eslint-disable-next-line @webpieces/no-unmanaged-exceptions
103
+ try {
104
+ const untrackedOutput = (0, child_process_1.execSync)(`git ls-files --others --exclude-standard${glob}`, {
105
+ cwd: workspaceRoot,
106
+ encoding: 'utf-8',
107
+ });
108
+ const untrackedFiles = untrackedOutput.trim().split('\n').filter(keep);
109
+ return Array.from(new Set([...changedFiles, ...untrackedFiles]));
110
+ }
111
+ catch (err) {
112
+ const error = (0, to_error_1.toError)(err);
113
+ void error; // swallow — ls-files failure falls back to the tracked list
114
+ return changedFiles;
115
+ }
116
+ }
117
+ return changedFiles;
118
+ }
119
+ catch (err) {
120
+ const error = (0, to_error_1.toError)(err);
121
+ void error; // swallow — git diff failure returns an empty list
122
+ return [];
123
+ }
124
+ }
125
+ /**
126
+ * Diff content for a single file. When the file is untracked (and no head is given) a synthetic
127
+ * all-added diff is produced so new files count as fully-changed.
128
+ */
129
+ function getFileDiff(workspaceRoot, file, base, head) {
130
+ // eslint-disable-next-line @webpieces/no-unmanaged-exceptions
131
+ try {
132
+ const diffTarget = head ? `${base} ${head}` : base;
133
+ const diff = (0, child_process_1.execSync)(`git diff ${diffTarget} -- "${file}"`, {
134
+ cwd: workspaceRoot,
135
+ encoding: 'utf-8',
136
+ });
137
+ if (!diff && !head) {
138
+ const fullPath = path.join(workspaceRoot, file);
139
+ if (fs.existsSync(fullPath)) {
140
+ const isUntracked = (0, child_process_1.execSync)(`git ls-files --others --exclude-standard "${file}"`, {
141
+ cwd: workspaceRoot,
142
+ encoding: 'utf-8',
143
+ }).trim();
144
+ if (isUntracked) {
145
+ const content = fs.readFileSync(fullPath, 'utf-8');
146
+ return content.split('\n').map((l) => `+${l}`).join('\n');
147
+ }
148
+ }
149
+ }
150
+ return diff;
151
+ }
152
+ catch (err) {
153
+ const error = (0, to_error_1.toError)(err);
154
+ void error; // swallow — git diff failure returns no diff
155
+ return '';
156
+ }
157
+ }
158
+ /**
159
+ * Parse a unified diff and return the set of added/changed line numbers (the `+` lines per hunk).
160
+ * This is the basis of MODIFIED_CODE (line-level) scoping.
161
+ */
162
+ function getChangedLineNumbers(diffContent) {
163
+ const changedLines = new Set();
164
+ const lines = diffContent.split('\n');
165
+ let currentLine = 0;
166
+ for (const line of lines) {
167
+ const hunkMatch = line.match(/^@@ -\d+(?:,\d+)? \+(\d+)(?:,\d+)? @@/);
168
+ if (hunkMatch) {
169
+ currentLine = parseInt(hunkMatch[1], 10);
170
+ continue;
171
+ }
172
+ if (line.startsWith('+') && !line.startsWith('+++')) {
173
+ changedLines.add(currentLine);
174
+ currentLine++;
175
+ }
176
+ else if (line.startsWith('-') && !line.startsWith('---')) {
177
+ // Deletions don't advance the new-file line counter.
178
+ }
179
+ else {
180
+ currentLine++;
181
+ }
182
+ }
183
+ return changedLines;
184
+ }
185
+ /**
186
+ * Method names whose signature line is a `+` addition in the diff — the basis of "NEW" methods.
187
+ */
188
+ function findNewMethodSignaturesInDiff(diffContent) {
189
+ const newMethods = new Set();
190
+ const lines = diffContent.split('\n');
191
+ const patterns = [
192
+ /^\+\s*(?:export\s+)?(?:async\s+)?function\s+(\w+)\s*\(/,
193
+ /^\+\s*(?:export\s+)?(?:const|let)\s+(\w+)\s*=\s*(?:async\s*)?\(/,
194
+ /^\+\s*(?:export\s+)?(?:const|let)\s+(\w+)\s*=\s*(?:async\s+)?function/,
195
+ /^\+\s*(?:(?:public|private|protected)\s+)?(?:static\s+)?(?:async\s+)?(\w+)\s*\(/,
196
+ ];
197
+ for (const line of lines) {
198
+ if (line.startsWith('+') && !line.startsWith('+++')) {
199
+ for (const pattern of patterns) {
200
+ const match = line.match(pattern);
201
+ if (match) {
202
+ const methodName = match[1];
203
+ if (methodName && !['if', 'for', 'while', 'switch', 'catch', 'constructor'].includes(methodName)) {
204
+ newMethods.add(methodName);
205
+ }
206
+ break;
207
+ }
208
+ }
209
+ }
210
+ }
211
+ return newMethods;
212
+ }
213
+ /**
214
+ * True if any line in [startLine, endLine] is in the changedLines set.
215
+ */
216
+ function hasChangesInRange(startLine, endLine, changedLines) {
217
+ for (let line = startLine; line <= endLine; line++) {
218
+ if (changedLines.has(line)) {
219
+ return true;
220
+ }
221
+ }
222
+ return false;
223
+ }
224
+ /**
225
+ * True if a node (method/function) is newly added or has any changed line in its range.
226
+ */
227
+ function isNewOrModified(name, startLine, endLine, changedLines, newMethodNames) {
228
+ if (newMethodNames.has(name))
229
+ return true;
230
+ return hasChangesInRange(startLine, endLine, changedLines);
231
+ }
232
+ //# sourceMappingURL=diff-scope.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff-scope.js","sourceRoot":"","sources":["../../../../../packages/tooling/rules-config/src/diff-scope.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Shared git-diff + diff-scoping helpers for ALL rule validators (code-rules) and nx executors\n * (nx-webpieces-rules). Centralized here in rules-config because it is the one package both of\n * those depend on, and it already shells out to git (see skip-rule.ts).\n *\n * Before this module these functions were copy-pasted ~15× (one private copy per validator + the\n * validate-ts-in-src executor). They are now defined once; every consumer imports from\n * `@webpieces/rules-config`. The two historical variants are preserved as parameters:\n * - `getChangedFiles(..., { tsOnly: false })` reproduces validate-dtos' all-files diff.\n * - `detectBase` replaces both the nested-try and the ref-loop spellings (identical behavior).\n */\n\nimport { execSync } from 'child_process';\nimport * as fs from 'fs';\nimport * as path from 'path';\n\nimport { toError } from './to-error';\n\n/** A git diff range: the base ref to compare against and an optional head (else the working tree). */\nexport class DiffRange {\n base?: string;\n head?: string;\n}\n\n/** Options for getChangedFiles. `tsOnly` (default true) restricts to *.ts/*.tsx and drops test files. */\nexport class ChangedFilesOptions {\n tsOnly?: boolean;\n}\n\n/**\n * A file is \"a test file\" (excluded from diff-scoped rules) when it is a .spec/.test file or lives\n * under a __tests__/ directory. Union of every per-validator filter so no consumer loses coverage.\n */\nfunction isTestFile(file: string): boolean {\n return file.includes('.spec.ts') || file.includes('.test.ts') || file.includes('__tests__/');\n}\n\n/**\n * Auto-detect the diff base: the merge-base of HEAD with origin/main, falling back to local main.\n * Returns null when neither ref resolves (e.g. shallow clone with no main) — callers treat null as\n * \"no base detected\" and typically skip.\n */\nexport function detectBase(workspaceRoot: string): string | null {\n for (const ref of ['origin/main', 'main']) {\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n const merged = execSync(`git merge-base HEAD ${ref}`, {\n cwd: workspaceRoot, encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'],\n }).trim();\n if (merged) return merged;\n } catch (err: unknown) {\n const error = toError(err);\n void error; // swallow — try the next ref\n }\n }\n return null;\n}\n\n/**\n * Resolve the diff range a rule should compare against. Honors nx's NX_BASE / NX_HEAD (set by\n * `nx affected --base=.. --head=..`); when NX_BASE is unset, auto-detects via detectBase. A returned\n * `base` of undefined means \"could not determine a base\" (caller should skip).\n */\nexport function resolveBase(workspaceRoot: string): DiffRange {\n const range = new DiffRange();\n range.base = process.env['NX_BASE'];\n range.head = process.env['NX_HEAD'];\n if (!range.base) {\n range.base = detectBase(workspaceRoot) ?? undefined;\n }\n return range;\n}\n\n/**\n * Changed files between base and head (or base→working-tree when head is omitted). When head is\n * omitted, untracked files are unioned in too (matching `nx affected`). `tsOnly` (default true)\n * restricts to *.ts/*.tsx and drops test files; pass false for an all-files diff.\n */\n// webpieces-disable max-lines-new-methods -- git command handling with untracked files needs several code paths\nexport function getChangedFiles(\n workspaceRoot: string,\n base: string,\n head?: string,\n opts?: ChangedFilesOptions,\n): string[] {\n const tsOnly = opts?.tsOnly ?? true;\n const glob = tsOnly ? \" -- '*.ts' '*.tsx'\" : '';\n const keep = (f: string): boolean => f.length > 0 && (!tsOnly || !isTestFile(f));\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n const diffTarget = head ? `${base} ${head}` : base;\n const output = execSync(`git diff --name-only ${diffTarget}${glob}`, {\n cwd: workspaceRoot,\n encoding: 'utf-8',\n });\n const changedFiles = output.trim().split('\\n').filter(keep);\n\n // Working-tree comparison (no head): also include untracked files, as nx affected does.\n if (!head) {\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n const untrackedOutput = execSync(`git ls-files --others --exclude-standard${glob}`, {\n cwd: workspaceRoot,\n encoding: 'utf-8',\n });\n const untrackedFiles = untrackedOutput.trim().split('\\n').filter(keep);\n return Array.from(new Set([...changedFiles, ...untrackedFiles]));\n } catch (err: unknown) {\n const error = toError(err);\n void error; // swallow — ls-files failure falls back to the tracked list\n return changedFiles;\n }\n }\n\n return changedFiles;\n } catch (err: unknown) {\n const error = toError(err);\n void error; // swallow — git diff failure returns an empty list\n return [];\n }\n}\n\n/**\n * Diff content for a single file. When the file is untracked (and no head is given) a synthetic\n * all-added diff is produced so new files count as fully-changed.\n */\nexport function getFileDiff(workspaceRoot: string, file: string, base: string, head?: string): string {\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n const diffTarget = head ? `${base} ${head}` : base;\n const diff = execSync(`git diff ${diffTarget} -- \"${file}\"`, {\n cwd: workspaceRoot,\n encoding: 'utf-8',\n });\n\n if (!diff && !head) {\n const fullPath = path.join(workspaceRoot, file);\n if (fs.existsSync(fullPath)) {\n const isUntracked = execSync(`git ls-files --others --exclude-standard \"${file}\"`, {\n cwd: workspaceRoot,\n encoding: 'utf-8',\n }).trim();\n\n if (isUntracked) {\n const content = fs.readFileSync(fullPath, 'utf-8');\n return content.split('\\n').map((l: string) => `+${l}`).join('\\n');\n }\n }\n }\n\n return diff;\n } catch (err: unknown) {\n const error = toError(err);\n void error; // swallow — git diff failure returns no diff\n return '';\n }\n}\n\n/**\n * Parse a unified diff and return the set of added/changed line numbers (the `+` lines per hunk).\n * This is the basis of MODIFIED_CODE (line-level) scoping.\n */\nexport function getChangedLineNumbers(diffContent: string): Set<number> {\n const changedLines = new Set<number>();\n const lines = diffContent.split('\\n');\n let currentLine = 0;\n\n for (const line of lines) {\n const hunkMatch = line.match(/^@@ -\\d+(?:,\\d+)? \\+(\\d+)(?:,\\d+)? @@/);\n if (hunkMatch) {\n currentLine = parseInt(hunkMatch[1], 10);\n continue;\n }\n\n if (line.startsWith('+') && !line.startsWith('+++')) {\n changedLines.add(currentLine);\n currentLine++;\n } else if (line.startsWith('-') && !line.startsWith('---')) {\n // Deletions don't advance the new-file line counter.\n } else {\n currentLine++;\n }\n }\n\n return changedLines;\n}\n\n/**\n * Method names whose signature line is a `+` addition in the diff — the basis of \"NEW\" methods.\n */\nexport function findNewMethodSignaturesInDiff(diffContent: string): Set<string> {\n const newMethods = new Set<string>();\n const lines = diffContent.split('\\n');\n\n const patterns = [\n /^\\+\\s*(?:export\\s+)?(?:async\\s+)?function\\s+(\\w+)\\s*\\(/,\n /^\\+\\s*(?:export\\s+)?(?:const|let)\\s+(\\w+)\\s*=\\s*(?:async\\s*)?\\(/,\n /^\\+\\s*(?:export\\s+)?(?:const|let)\\s+(\\w+)\\s*=\\s*(?:async\\s+)?function/,\n /^\\+\\s*(?:(?:public|private|protected)\\s+)?(?:static\\s+)?(?:async\\s+)?(\\w+)\\s*\\(/,\n ];\n\n for (const line of lines) {\n if (line.startsWith('+') && !line.startsWith('+++')) {\n for (const pattern of patterns) {\n const match = line.match(pattern);\n if (match) {\n const methodName = match[1];\n if (methodName && !['if', 'for', 'while', 'switch', 'catch', 'constructor'].includes(methodName)) {\n newMethods.add(methodName);\n }\n break;\n }\n }\n }\n }\n\n return newMethods;\n}\n\n/**\n * True if any line in [startLine, endLine] is in the changedLines set.\n */\nexport function hasChangesInRange(startLine: number, endLine: number, changedLines: Set<number>): boolean {\n for (let line = startLine; line <= endLine; line++) {\n if (changedLines.has(line)) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * True if a node (method/function) is newly added or has any changed line in its range.\n */\nexport function isNewOrModified(\n name: string,\n startLine: number,\n endLine: number,\n changedLines: Set<number>,\n newMethodNames: Set<string>,\n): boolean {\n if (newMethodNames.has(name)) return true;\n return hasChangesInRange(startLine, endLine, changedLines);\n}\n"]}
package/src/index.d.ts CHANGED
@@ -13,12 +13,13 @@ export { FieldDef } from './field-def';
13
13
  export type { SchemaShape } from './field-def';
14
14
  export { shouldSkipRule, getCurrentBranch } from './skip-rule';
15
15
  export type { SkipRuleResult } from './skip-rule';
16
+ export { detectBase, resolveBase, getChangedFiles, getFileDiff, getChangedLineNumbers, findNewMethodSignaturesInDiff, hasChangesInRange, isNewOrModified, } from './diff-scope';
16
17
  export { AbstractRule } from './abstract-rule';
17
18
  export { WEBPIECES_DISABLE, RULE_NAMES, hasDisable, WEBPIECES_TMP_DIR, MERGE_DIR_PREFIX, MERGE_IN_PROGRESS_FILE, MERGE_EXPLANATION_FILE, } from './constants';
18
19
  export { WebpiecesRulesConfig } from './WebpiecesRulesConfig';
19
- export { MaxMethodLinesConfig, MaxFileLinesConfig, RequireReturnTypeConfig, NoInlineTypeLiteralsConfig, NoAnyUnknownConfig, NoImplicitAnyConfig, PrismaValidateDtosConfig, PrismaConverterConfig, NoDestructureConfig, NoUnmanagedExceptionsConfig, CatchErrorPatternConfig, ThrowCauseRequiredConfig, AngularNoDirectApiInResolverConfig, NoSymbolDiTokensConfig, NoShellSubstitutionConfig, BranchCreationGuardConfig, PrCreationGuardConfig, MergeInProgressGuardConfig, PrMergeCleanupConfig, NoDirectMainUpdateConfig, FeatureBranchGuardConfig, NoFileImportCyclesConfig, RuntimeArchitectureConfig, NoJsFilesConfig, ValidateTsInSrcConfig, BaseRuleConfig, } from './rule-configs';
20
- export { METHOD_LIMIT_MODES, FILE_LIMIT_MODES, RETURN_TYPE_MODES, INLINE_TYPE_MODES, MODIFIED_CODE_MODES, PRISMA_DTOS_MODES, PRISMA_CONVERTER_MODES, DIRECT_API_RESOLVER_MODES, THROW_CAUSE_MODES, ON_OFF_MODES, VALIDATE_TS_MODES, } from './rule-configs';
21
- export type { MethodLimitMode, FileLimitMode, ReturnTypeMode, InlineTypeMode, ModifiedCodeMode, PrismaValidateDtosMode, PrismaConverterMode, DirectApiResolverMode, ThrowCauseMode, OnOffMode, ValidateTsMode, } from './rule-configs';
20
+ export { MaxMethodLinesConfig, MaxFileLinesConfig, RequireReturnTypeConfig, NoInlineTypeLiteralsConfig, NoAnyUnknownConfig, NoImplicitAnyConfig, PrismaValidateDtosConfig, PrismaConverterConfig, NoDestructureConfig, NoUnmanagedExceptionsConfig, CatchErrorPatternConfig, ThrowCauseRequiredConfig, AngularNoDirectApiInResolverConfig, NoSymbolDiTokensConfig, NoShellSubstitutionConfig, BranchCreationGuardConfig, PrCreationGuardConfig, MergeInProgressGuardConfig, PrMergeCleanupConfig, NoDirectMainUpdateConfig, FeatureBranchGuardConfig, NoFileImportCyclesConfig, RuntimeArchitectureConfig, NxWiringConfig, NoJsFilesConfig, ValidateTsInSrcConfig, BaseRuleConfig, } from './rule-configs';
21
+ export { METHOD_LIMIT_MODES, FILE_LIMIT_MODES, RETURN_TYPE_MODES, INLINE_TYPE_MODES, MODIFIED_CODE_MODES, PRISMA_DTOS_MODES, PRISMA_CONVERTER_MODES, DIRECT_API_RESOLVER_MODES, THROW_CAUSE_MODES, ON_OFF_MODES, STRUCTURAL_MODES, VALIDATE_TS_MODES, } from './rule-configs';
22
+ export type { MethodLimitMode, FileLimitMode, ReturnTypeMode, InlineTypeMode, ModifiedCodeMode, PrismaValidateDtosMode, PrismaConverterMode, DirectApiResolverMode, ThrowCauseMode, OnOffMode, StructuralMode, ValidateTsMode, } from './rule-configs';
22
23
  export { GateDefinition, PrGateConfig, defaultGates, defaultPrGateConfig, buildPrGateConfig, } from './pr-gate-config';
23
24
  export { ReviewJson, loadReviewJson, reviewJsonPath, reviewJsonSchemaHint, } from './review-json';
24
25
  export { MainSyncStatus, MainSyncLock, DEFAULT_HANG_TIMEOUT_MINUTES, mainSyncStatusPath, mainSyncLockPath, readMainSyncStatus, writeMainSyncStatus, readMainSyncLock, writeMainSyncLock, isLockStale, isRefreshInProgress, inProcessLock, finishedLock, computeMainSyncStatus, stampCleanMainSyncStatus, squashRecoverySteps, } from './main-sync-status';
package/src/index.js CHANGED
@@ -1,7 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.BranchCreationGuardConfig = exports.NoShellSubstitutionConfig = exports.NoSymbolDiTokensConfig = exports.AngularNoDirectApiInResolverConfig = exports.ThrowCauseRequiredConfig = exports.CatchErrorPatternConfig = exports.NoUnmanagedExceptionsConfig = exports.NoDestructureConfig = exports.PrismaConverterConfig = exports.PrismaValidateDtosConfig = exports.NoImplicitAnyConfig = exports.NoAnyUnknownConfig = exports.NoInlineTypeLiteralsConfig = exports.RequireReturnTypeConfig = exports.MaxFileLinesConfig = exports.MaxMethodLinesConfig = exports.WebpiecesRulesConfig = exports.MERGE_EXPLANATION_FILE = exports.MERGE_IN_PROGRESS_FILE = exports.MERGE_DIR_PREFIX = exports.WEBPIECES_TMP_DIR = exports.hasDisable = exports.RULE_NAMES = exports.WEBPIECES_DISABLE = exports.AbstractRule = exports.getCurrentBranch = exports.shouldSkipRule = exports.FieldDef = exports.sectionForRule = exports.isHookGuard = exports.HOOK_GUARD_NAMES = exports.allRuleNames = exports.validateCommandsSection = exports.validateSectionPlacement = exports.validatePrGateSection = exports.validateWebpiecesConfig = exports.writeTemplate = exports.writeTemplateIfMissing = exports.loadTemplate = exports.defaultRulesDir = exports.defaultRules = exports.isPathExcluded = exports.CONFIG_FILENAME = exports.findConfigFile = exports.LoadedConfig = exports.loadAndValidate = exports.toError = exports.InformAiError = exports.ResolvedRuleConfig = exports.ResolvedConfig = void 0;
4
- exports.DEFAULT_MERGE_COMPLETE_COMMAND = exports.DEFAULT_UPSERT_PR_COMMAND = exports.buildCommandsConfig = exports.CommandsConfig = exports.squashRecoverySteps = exports.stampCleanMainSyncStatus = exports.computeMainSyncStatus = exports.finishedLock = exports.inProcessLock = exports.isRefreshInProgress = exports.isLockStale = exports.writeMainSyncLock = exports.readMainSyncLock = exports.writeMainSyncStatus = exports.readMainSyncStatus = exports.mainSyncLockPath = exports.mainSyncStatusPath = exports.DEFAULT_HANG_TIMEOUT_MINUTES = exports.MainSyncLock = exports.MainSyncStatus = exports.reviewJsonSchemaHint = exports.reviewJsonPath = exports.loadReviewJson = exports.ReviewJson = exports.buildPrGateConfig = exports.defaultPrGateConfig = exports.defaultGates = exports.PrGateConfig = exports.GateDefinition = exports.VALIDATE_TS_MODES = exports.ON_OFF_MODES = exports.THROW_CAUSE_MODES = exports.DIRECT_API_RESOLVER_MODES = exports.PRISMA_CONVERTER_MODES = exports.PRISMA_DTOS_MODES = exports.MODIFIED_CODE_MODES = exports.INLINE_TYPE_MODES = exports.RETURN_TYPE_MODES = exports.FILE_LIMIT_MODES = exports.METHOD_LIMIT_MODES = exports.BaseRuleConfig = exports.ValidateTsInSrcConfig = exports.NoJsFilesConfig = exports.RuntimeArchitectureConfig = exports.NoFileImportCyclesConfig = exports.FeatureBranchGuardConfig = exports.NoDirectMainUpdateConfig = exports.PrMergeCleanupConfig = exports.MergeInProgressGuardConfig = exports.PrCreationGuardConfig = void 0;
3
+ exports.PrismaConverterConfig = exports.PrismaValidateDtosConfig = exports.NoImplicitAnyConfig = exports.NoAnyUnknownConfig = exports.NoInlineTypeLiteralsConfig = exports.RequireReturnTypeConfig = exports.MaxFileLinesConfig = exports.MaxMethodLinesConfig = exports.WebpiecesRulesConfig = exports.MERGE_EXPLANATION_FILE = exports.MERGE_IN_PROGRESS_FILE = exports.MERGE_DIR_PREFIX = exports.WEBPIECES_TMP_DIR = exports.hasDisable = exports.RULE_NAMES = exports.WEBPIECES_DISABLE = exports.AbstractRule = exports.isNewOrModified = exports.hasChangesInRange = exports.findNewMethodSignaturesInDiff = exports.getChangedLineNumbers = exports.getFileDiff = exports.getChangedFiles = exports.resolveBase = exports.detectBase = exports.getCurrentBranch = exports.shouldSkipRule = exports.FieldDef = exports.sectionForRule = exports.isHookGuard = exports.HOOK_GUARD_NAMES = exports.allRuleNames = exports.validateCommandsSection = exports.validateSectionPlacement = exports.validatePrGateSection = exports.validateWebpiecesConfig = exports.writeTemplate = exports.writeTemplateIfMissing = exports.loadTemplate = exports.defaultRulesDir = exports.defaultRules = exports.isPathExcluded = exports.CONFIG_FILENAME = exports.findConfigFile = exports.LoadedConfig = exports.loadAndValidate = exports.toError = exports.InformAiError = exports.ResolvedRuleConfig = exports.ResolvedConfig = void 0;
4
+ exports.isLockStale = exports.writeMainSyncLock = exports.readMainSyncLock = exports.writeMainSyncStatus = exports.readMainSyncStatus = exports.mainSyncLockPath = exports.mainSyncStatusPath = exports.DEFAULT_HANG_TIMEOUT_MINUTES = exports.MainSyncLock = exports.MainSyncStatus = exports.reviewJsonSchemaHint = exports.reviewJsonPath = exports.loadReviewJson = exports.ReviewJson = exports.buildPrGateConfig = exports.defaultPrGateConfig = exports.defaultGates = exports.PrGateConfig = exports.GateDefinition = exports.VALIDATE_TS_MODES = exports.STRUCTURAL_MODES = exports.ON_OFF_MODES = exports.THROW_CAUSE_MODES = exports.DIRECT_API_RESOLVER_MODES = exports.PRISMA_CONVERTER_MODES = exports.PRISMA_DTOS_MODES = exports.MODIFIED_CODE_MODES = exports.INLINE_TYPE_MODES = exports.RETURN_TYPE_MODES = exports.FILE_LIMIT_MODES = exports.METHOD_LIMIT_MODES = exports.BaseRuleConfig = exports.ValidateTsInSrcConfig = exports.NoJsFilesConfig = exports.NxWiringConfig = exports.RuntimeArchitectureConfig = exports.NoFileImportCyclesConfig = exports.FeatureBranchGuardConfig = exports.NoDirectMainUpdateConfig = exports.PrMergeCleanupConfig = exports.MergeInProgressGuardConfig = exports.PrCreationGuardConfig = exports.BranchCreationGuardConfig = exports.NoShellSubstitutionConfig = exports.NoSymbolDiTokensConfig = exports.AngularNoDirectApiInResolverConfig = exports.ThrowCauseRequiredConfig = exports.CatchErrorPatternConfig = exports.NoUnmanagedExceptionsConfig = exports.NoDestructureConfig = void 0;
5
+ exports.DEFAULT_MERGE_COMPLETE_COMMAND = exports.DEFAULT_UPSERT_PR_COMMAND = exports.buildCommandsConfig = exports.CommandsConfig = exports.squashRecoverySteps = exports.stampCleanMainSyncStatus = exports.computeMainSyncStatus = exports.finishedLock = exports.inProcessLock = exports.isRefreshInProgress = void 0;
5
6
  var types_1 = require("./types");
6
7
  Object.defineProperty(exports, "ResolvedConfig", { enumerable: true, get: function () { return types_1.ResolvedConfig; } });
7
8
  Object.defineProperty(exports, "ResolvedRuleConfig", { enumerable: true, get: function () { return types_1.ResolvedRuleConfig; } });
@@ -39,6 +40,15 @@ Object.defineProperty(exports, "FieldDef", { enumerable: true, get: function ()
39
40
  var skip_rule_1 = require("./skip-rule");
40
41
  Object.defineProperty(exports, "shouldSkipRule", { enumerable: true, get: function () { return skip_rule_1.shouldSkipRule; } });
41
42
  Object.defineProperty(exports, "getCurrentBranch", { enumerable: true, get: function () { return skip_rule_1.getCurrentBranch; } });
43
+ var diff_scope_1 = require("./diff-scope");
44
+ Object.defineProperty(exports, "detectBase", { enumerable: true, get: function () { return diff_scope_1.detectBase; } });
45
+ Object.defineProperty(exports, "resolveBase", { enumerable: true, get: function () { return diff_scope_1.resolveBase; } });
46
+ Object.defineProperty(exports, "getChangedFiles", { enumerable: true, get: function () { return diff_scope_1.getChangedFiles; } });
47
+ Object.defineProperty(exports, "getFileDiff", { enumerable: true, get: function () { return diff_scope_1.getFileDiff; } });
48
+ Object.defineProperty(exports, "getChangedLineNumbers", { enumerable: true, get: function () { return diff_scope_1.getChangedLineNumbers; } });
49
+ Object.defineProperty(exports, "findNewMethodSignaturesInDiff", { enumerable: true, get: function () { return diff_scope_1.findNewMethodSignaturesInDiff; } });
50
+ Object.defineProperty(exports, "hasChangesInRange", { enumerable: true, get: function () { return diff_scope_1.hasChangesInRange; } });
51
+ Object.defineProperty(exports, "isNewOrModified", { enumerable: true, get: function () { return diff_scope_1.isNewOrModified; } });
42
52
  var abstract_rule_1 = require("./abstract-rule");
43
53
  Object.defineProperty(exports, "AbstractRule", { enumerable: true, get: function () { return abstract_rule_1.AbstractRule; } });
44
54
  var constants_1 = require("./constants");
@@ -75,6 +85,7 @@ Object.defineProperty(exports, "NoDirectMainUpdateConfig", { enumerable: true, g
75
85
  Object.defineProperty(exports, "FeatureBranchGuardConfig", { enumerable: true, get: function () { return rule_configs_1.FeatureBranchGuardConfig; } });
76
86
  Object.defineProperty(exports, "NoFileImportCyclesConfig", { enumerable: true, get: function () { return rule_configs_1.NoFileImportCyclesConfig; } });
77
87
  Object.defineProperty(exports, "RuntimeArchitectureConfig", { enumerable: true, get: function () { return rule_configs_1.RuntimeArchitectureConfig; } });
88
+ Object.defineProperty(exports, "NxWiringConfig", { enumerable: true, get: function () { return rule_configs_1.NxWiringConfig; } });
78
89
  Object.defineProperty(exports, "NoJsFilesConfig", { enumerable: true, get: function () { return rule_configs_1.NoJsFilesConfig; } });
79
90
  Object.defineProperty(exports, "ValidateTsInSrcConfig", { enumerable: true, get: function () { return rule_configs_1.ValidateTsInSrcConfig; } });
80
91
  Object.defineProperty(exports, "BaseRuleConfig", { enumerable: true, get: function () { return rule_configs_1.BaseRuleConfig; } });
@@ -90,6 +101,7 @@ Object.defineProperty(exports, "PRISMA_CONVERTER_MODES", { enumerable: true, get
90
101
  Object.defineProperty(exports, "DIRECT_API_RESOLVER_MODES", { enumerable: true, get: function () { return rule_configs_2.DIRECT_API_RESOLVER_MODES; } });
91
102
  Object.defineProperty(exports, "THROW_CAUSE_MODES", { enumerable: true, get: function () { return rule_configs_2.THROW_CAUSE_MODES; } });
92
103
  Object.defineProperty(exports, "ON_OFF_MODES", { enumerable: true, get: function () { return rule_configs_2.ON_OFF_MODES; } });
104
+ Object.defineProperty(exports, "STRUCTURAL_MODES", { enumerable: true, get: function () { return rule_configs_2.STRUCTURAL_MODES; } });
93
105
  Object.defineProperty(exports, "VALIDATE_TS_MODES", { enumerable: true, get: function () { return rule_configs_2.VALIDATE_TS_MODES; } });
94
106
  var pr_gate_config_1 = require("./pr-gate-config");
95
107
  Object.defineProperty(exports, "GateDefinition", { enumerable: true, get: function () { return pr_gate_config_1.GateDefinition; } });
package/src/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../packages/tooling/rules-config/src/index.ts"],"names":[],"mappings":"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","sourcesContent":["export { ResolvedConfig, ResolvedRuleConfig, RuleOptions } from './types';\nexport { InformAiError } from './inform-ai-error';\nexport { toError } from './to-error';\nexport { loadAndValidate, LoadedConfig } from './load-config';\nexport { findConfigFile, CONFIG_FILENAME } from './config-file';\nexport { isPathExcluded } from './exclude-paths';\nexport { defaultRules, defaultRulesDir } from './default-rules';\nexport { loadTemplate, writeTemplateIfMissing, writeTemplate } from './load-template';\nexport { validateWebpiecesConfig, validatePrGateSection, validateSectionPlacement, validateCommandsSection, allRuleNames } from './validate-config';\nexport type { ConfigSection } from './sections';\nexport { HOOK_GUARD_NAMES, isHookGuard, sectionForRule } from './sections';\nexport { FieldDef } from './field-def';\nexport type { SchemaShape } from './field-def';\nexport { shouldSkipRule, getCurrentBranch } from './skip-rule';\nexport type { SkipRuleResult } from './skip-rule';\nexport { AbstractRule } from './abstract-rule';\nexport {\n WEBPIECES_DISABLE,\n RULE_NAMES,\n hasDisable,\n WEBPIECES_TMP_DIR,\n MERGE_DIR_PREFIX,\n MERGE_IN_PROGRESS_FILE,\n MERGE_EXPLANATION_FILE,\n} from './constants';\nexport { WebpiecesRulesConfig } from './WebpiecesRulesConfig';\nexport {\n MaxMethodLinesConfig,\n MaxFileLinesConfig,\n RequireReturnTypeConfig,\n NoInlineTypeLiteralsConfig,\n NoAnyUnknownConfig,\n NoImplicitAnyConfig,\n PrismaValidateDtosConfig,\n PrismaConverterConfig,\n NoDestructureConfig,\n NoUnmanagedExceptionsConfig,\n CatchErrorPatternConfig,\n ThrowCauseRequiredConfig,\n AngularNoDirectApiInResolverConfig,\n NoSymbolDiTokensConfig,\n NoShellSubstitutionConfig,\n BranchCreationGuardConfig,\n PrCreationGuardConfig,\n MergeInProgressGuardConfig,\n PrMergeCleanupConfig,\n NoDirectMainUpdateConfig,\n FeatureBranchGuardConfig,\n NoFileImportCyclesConfig,\n RuntimeArchitectureConfig,\n NoJsFilesConfig,\n ValidateTsInSrcConfig,\n BaseRuleConfig,\n} from './rule-configs';\n// Mode unions + their value arrays — the single source of truth shared with code-rules.\nexport {\n METHOD_LIMIT_MODES,\n FILE_LIMIT_MODES,\n RETURN_TYPE_MODES,\n INLINE_TYPE_MODES,\n MODIFIED_CODE_MODES,\n PRISMA_DTOS_MODES,\n PRISMA_CONVERTER_MODES,\n DIRECT_API_RESOLVER_MODES,\n THROW_CAUSE_MODES,\n ON_OFF_MODES,\n VALIDATE_TS_MODES,\n} from './rule-configs';\nexport type {\n MethodLimitMode,\n FileLimitMode,\n ReturnTypeMode,\n InlineTypeMode,\n ModifiedCodeMode,\n PrismaValidateDtosMode,\n PrismaConverterMode,\n DirectApiResolverMode,\n ThrowCauseMode,\n OnOffMode,\n ValidateTsMode,\n} from './rule-configs';\nexport {\n GateDefinition,\n PrGateConfig,\n defaultGates,\n defaultPrGateConfig,\n buildPrGateConfig,\n} from './pr-gate-config';\nexport {\n ReviewJson,\n loadReviewJson,\n reviewJsonPath,\n reviewJsonSchemaHint,\n} from './review-json';\nexport {\n MainSyncStatus,\n MainSyncLock,\n DEFAULT_HANG_TIMEOUT_MINUTES,\n mainSyncStatusPath,\n mainSyncLockPath,\n readMainSyncStatus,\n writeMainSyncStatus,\n readMainSyncLock,\n writeMainSyncLock,\n isLockStale,\n isRefreshInProgress,\n inProcessLock,\n finishedLock,\n computeMainSyncStatus,\n stampCleanMainSyncStatus,\n squashRecoverySteps,\n} from './main-sync-status';\nexport {\n CommandsConfig,\n buildCommandsConfig,\n DEFAULT_UPSERT_PR_COMMAND,\n DEFAULT_MERGE_COMPLETE_COMMAND,\n} from './commands-config';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../packages/tooling/rules-config/src/index.ts"],"names":[],"mappings":"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","sourcesContent":["export { ResolvedConfig, ResolvedRuleConfig, RuleOptions } from './types';\nexport { InformAiError } from './inform-ai-error';\nexport { toError } from './to-error';\nexport { loadAndValidate, LoadedConfig } from './load-config';\nexport { findConfigFile, CONFIG_FILENAME } from './config-file';\nexport { isPathExcluded } from './exclude-paths';\nexport { defaultRules, defaultRulesDir } from './default-rules';\nexport { loadTemplate, writeTemplateIfMissing, writeTemplate } from './load-template';\nexport { validateWebpiecesConfig, validatePrGateSection, validateSectionPlacement, validateCommandsSection, allRuleNames } from './validate-config';\nexport type { ConfigSection } from './sections';\nexport { HOOK_GUARD_NAMES, isHookGuard, sectionForRule } from './sections';\nexport { FieldDef } from './field-def';\nexport type { SchemaShape } from './field-def';\nexport { shouldSkipRule, getCurrentBranch } from './skip-rule';\nexport type { SkipRuleResult } from './skip-rule';\nexport {\n detectBase,\n resolveBase,\n getChangedFiles,\n getFileDiff,\n getChangedLineNumbers,\n findNewMethodSignaturesInDiff,\n hasChangesInRange,\n isNewOrModified,\n} from './diff-scope';\nexport { AbstractRule } from './abstract-rule';\nexport {\n WEBPIECES_DISABLE,\n RULE_NAMES,\n hasDisable,\n WEBPIECES_TMP_DIR,\n MERGE_DIR_PREFIX,\n MERGE_IN_PROGRESS_FILE,\n MERGE_EXPLANATION_FILE,\n} from './constants';\nexport { WebpiecesRulesConfig } from './WebpiecesRulesConfig';\nexport {\n MaxMethodLinesConfig,\n MaxFileLinesConfig,\n RequireReturnTypeConfig,\n NoInlineTypeLiteralsConfig,\n NoAnyUnknownConfig,\n NoImplicitAnyConfig,\n PrismaValidateDtosConfig,\n PrismaConverterConfig,\n NoDestructureConfig,\n NoUnmanagedExceptionsConfig,\n CatchErrorPatternConfig,\n ThrowCauseRequiredConfig,\n AngularNoDirectApiInResolverConfig,\n NoSymbolDiTokensConfig,\n NoShellSubstitutionConfig,\n BranchCreationGuardConfig,\n PrCreationGuardConfig,\n MergeInProgressGuardConfig,\n PrMergeCleanupConfig,\n NoDirectMainUpdateConfig,\n FeatureBranchGuardConfig,\n NoFileImportCyclesConfig,\n RuntimeArchitectureConfig,\n NxWiringConfig,\n NoJsFilesConfig,\n ValidateTsInSrcConfig,\n BaseRuleConfig,\n} from './rule-configs';\n// Mode unions + their value arrays — the single source of truth shared with code-rules.\nexport {\n METHOD_LIMIT_MODES,\n FILE_LIMIT_MODES,\n RETURN_TYPE_MODES,\n INLINE_TYPE_MODES,\n MODIFIED_CODE_MODES,\n PRISMA_DTOS_MODES,\n PRISMA_CONVERTER_MODES,\n DIRECT_API_RESOLVER_MODES,\n THROW_CAUSE_MODES,\n ON_OFF_MODES,\n STRUCTURAL_MODES,\n VALIDATE_TS_MODES,\n} from './rule-configs';\nexport type {\n MethodLimitMode,\n FileLimitMode,\n ReturnTypeMode,\n InlineTypeMode,\n ModifiedCodeMode,\n PrismaValidateDtosMode,\n PrismaConverterMode,\n DirectApiResolverMode,\n ThrowCauseMode,\n OnOffMode,\n StructuralMode,\n ValidateTsMode,\n} from './rule-configs';\nexport {\n GateDefinition,\n PrGateConfig,\n defaultGates,\n defaultPrGateConfig,\n buildPrGateConfig,\n} from './pr-gate-config';\nexport {\n ReviewJson,\n loadReviewJson,\n reviewJsonPath,\n reviewJsonSchemaHint,\n} from './review-json';\nexport {\n MainSyncStatus,\n MainSyncLock,\n DEFAULT_HANG_TIMEOUT_MINUTES,\n mainSyncStatusPath,\n mainSyncLockPath,\n readMainSyncStatus,\n writeMainSyncStatus,\n readMainSyncLock,\n writeMainSyncLock,\n isLockStale,\n isRefreshInProgress,\n inProcessLock,\n finishedLock,\n computeMainSyncStatus,\n stampCleanMainSyncStatus,\n squashRecoverySteps,\n} from './main-sync-status';\nexport {\n CommandsConfig,\n buildCommandsConfig,\n DEFAULT_UPSERT_PR_COMMAND,\n DEFAULT_MERGE_COMPLETE_COMMAND,\n} from './commands-config';\n"]}
@@ -1,19 +1,19 @@
1
1
  import { FieldDef, SchemaShape } from './field-def';
2
- export declare const METHOD_LIMIT_MODES: readonly ["OFF", "NEW_METHODS", "NEW_AND_MODIFIED_METHODS", "MODIFIED_FILES"];
2
+ export declare const METHOD_LIMIT_MODES: readonly ["OFF", "NEW_METHODS", "NEW_AND_MODIFIED_METHODS", "NEW_AND_MODIFIED_FILES"];
3
3
  export type MethodLimitMode = typeof METHOD_LIMIT_MODES[number];
4
- export declare const FILE_LIMIT_MODES: readonly ["OFF", "MODIFIED_FILES"];
4
+ export declare const FILE_LIMIT_MODES: readonly ["OFF", "NEW_AND_MODIFIED_FILES"];
5
5
  export type FileLimitMode = typeof FILE_LIMIT_MODES[number];
6
- export declare const RETURN_TYPE_MODES: readonly ["OFF", "NEW_METHODS", "NEW_AND_MODIFIED_METHODS", "MODIFIED_FILES"];
6
+ export declare const RETURN_TYPE_MODES: readonly ["OFF", "NEW_METHODS", "NEW_AND_MODIFIED_METHODS", "NEW_AND_MODIFIED_FILES"];
7
7
  export type ReturnTypeMode = typeof RETURN_TYPE_MODES[number];
8
- export declare const INLINE_TYPE_MODES: readonly ["OFF", "NEW_METHODS", "NEW_AND_MODIFIED_METHODS", "MODIFIED_FILES"];
8
+ export declare const INLINE_TYPE_MODES: readonly ["OFF", "NEW_METHODS", "NEW_AND_MODIFIED_METHODS", "NEW_AND_MODIFIED_FILES"];
9
9
  export type InlineTypeMode = typeof INLINE_TYPE_MODES[number];
10
- export declare const MODIFIED_CODE_MODES: readonly ["OFF", "MODIFIED_CODE", "MODIFIED_FILES"];
10
+ export declare const MODIFIED_CODE_MODES: readonly ["OFF", "MODIFIED_CODE", "NEW_AND_MODIFIED_FILES"];
11
11
  export type ModifiedCodeMode = typeof MODIFIED_CODE_MODES[number];
12
- export declare const PRISMA_DTOS_MODES: readonly ["OFF", "MODIFIED_CLASS", "MODIFIED_FILES"];
12
+ export declare const PRISMA_DTOS_MODES: readonly ["OFF", "MODIFIED_CLASS", "NEW_AND_MODIFIED_FILES"];
13
13
  export type PrismaValidateDtosMode = typeof PRISMA_DTOS_MODES[number];
14
- export declare const PRISMA_CONVERTER_MODES: readonly ["OFF", "NEW_AND_MODIFIED_METHODS", "MODIFIED_FILES"];
14
+ export declare const PRISMA_CONVERTER_MODES: readonly ["OFF", "NEW_AND_MODIFIED_METHODS", "NEW_AND_MODIFIED_FILES"];
15
15
  export type PrismaConverterMode = typeof PRISMA_CONVERTER_MODES[number];
16
- export declare const DIRECT_API_RESOLVER_MODES: readonly ["OFF", "MODIFIED_CODE", "NEW_AND_MODIFIED_METHODS", "MODIFIED_FILES"];
16
+ export declare const DIRECT_API_RESOLVER_MODES: readonly ["OFF", "MODIFIED_CODE", "NEW_AND_MODIFIED_METHODS", "NEW_AND_MODIFIED_FILES"];
17
17
  export type DirectApiResolverMode = typeof DIRECT_API_RESOLVER_MODES[number];
18
18
  export declare const THROW_CAUSE_MODES: readonly ["OFF", "MODIFIED_CODE"];
19
19
  export type ThrowCauseMode = typeof THROW_CAUSE_MODES[number];
@@ -21,8 +21,10 @@ export declare const ON_OFF_MODES: readonly ["ON", "OFF"];
21
21
  export type OnOffMode = typeof ON_OFF_MODES[number];
22
22
  export declare const BRANCH_GUARD_MODES: readonly ["ON", "OFF", "ON_NO_SUBBRANCHES"];
23
23
  export type BranchGuardMode = typeof BRANCH_GUARD_MODES[number];
24
- export declare const VALIDATE_TS_MODES: readonly ["OFF", "MODIFIED_FILES"];
24
+ export declare const VALIDATE_TS_MODES: readonly ["OFF", "NEW_AND_MODIFIED_FILES"];
25
25
  export type ValidateTsMode = typeof VALIDATE_TS_MODES[number];
26
+ export declare const STRUCTURAL_MODES: readonly ["OFF", "RUN_EVERY_TIME"];
27
+ export type StructuralMode = typeof STRUCTURAL_MODES[number];
26
28
  export declare abstract class BaseRuleConfig {
27
29
  mode?: string;
28
30
  ignoreModifiedUntilEpoch?: number;
@@ -147,20 +149,24 @@ export declare class FeatureBranchGuardConfig extends BaseRuleConfig {
147
149
  static readonly SCHEMA: SchemaShape<FeatureBranchGuardConfig>;
148
150
  }
149
151
  export declare class NoFileImportCyclesConfig extends BaseRuleConfig {
150
- mode?: OnOffMode;
152
+ mode?: StructuralMode;
151
153
  ignoreTypeOnly?: boolean;
152
154
  excludePackages?: string[];
153
155
  static readonly SCHEMA: SchemaShape<NoFileImportCyclesConfig>;
154
156
  }
155
157
  export declare class RuntimeArchitectureConfig extends BaseRuleConfig {
156
- mode?: OnOffMode;
158
+ mode?: StructuralMode;
157
159
  servicePaths?: string[];
158
160
  apiProjectPaths?: string[];
159
161
  allowedCycles?: string[];
160
162
  static readonly SCHEMA: SchemaShape<RuntimeArchitectureConfig>;
161
163
  }
164
+ export declare class NxWiringConfig extends BaseRuleConfig {
165
+ mode?: StructuralMode;
166
+ static readonly SCHEMA: SchemaShape<NxWiringConfig>;
167
+ }
162
168
  export declare class NoJsFilesConfig extends BaseRuleConfig {
163
- mode?: OnOffMode;
169
+ mode?: FileLimitMode;
164
170
  allowedPaths?: string[];
165
171
  static readonly SCHEMA: SchemaShape<NoJsFilesConfig>;
166
172
  }
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ValidateTsInSrcConfig = exports.NoJsFilesConfig = exports.RuntimeArchitectureConfig = exports.NoFileImportCyclesConfig = exports.FeatureBranchGuardConfig = exports.NoDirectMainUpdateConfig = exports.PrMergeCleanupConfig = exports.MergeInProgressGuardConfig = exports.PrCreationGuardConfig = exports.BranchCreationGuardConfig = exports.NoShellSubstitutionConfig = exports.NoSymbolDiTokensConfig = exports.AngularNoDirectApiInResolverConfig = exports.ThrowCauseRequiredConfig = exports.CatchErrorPatternConfig = exports.NoUnmanagedExceptionsConfig = exports.NoDestructureConfig = exports.PrismaConverterConfig = exports.PrismaValidateDtosConfig = exports.NoImplicitAnyConfig = exports.NoAnyUnknownConfig = exports.NoInlineTypeLiteralsConfig = exports.RequireReturnTypeConfig = exports.MaxFileLinesConfig = exports.MaxMethodLinesConfig = exports.BASE_RULE_SCHEMA = exports.BaseRuleConfig = exports.VALIDATE_TS_MODES = exports.BRANCH_GUARD_MODES = exports.ON_OFF_MODES = exports.THROW_CAUSE_MODES = exports.DIRECT_API_RESOLVER_MODES = exports.PRISMA_CONVERTER_MODES = exports.PRISMA_DTOS_MODES = exports.MODIFIED_CODE_MODES = exports.INLINE_TYPE_MODES = exports.RETURN_TYPE_MODES = exports.FILE_LIMIT_MODES = exports.METHOD_LIMIT_MODES = void 0;
3
+ exports.ValidateTsInSrcConfig = exports.NoJsFilesConfig = exports.NxWiringConfig = exports.RuntimeArchitectureConfig = exports.NoFileImportCyclesConfig = exports.FeatureBranchGuardConfig = exports.NoDirectMainUpdateConfig = exports.PrMergeCleanupConfig = exports.MergeInProgressGuardConfig = exports.PrCreationGuardConfig = exports.BranchCreationGuardConfig = exports.NoShellSubstitutionConfig = exports.NoSymbolDiTokensConfig = exports.AngularNoDirectApiInResolverConfig = exports.ThrowCauseRequiredConfig = exports.CatchErrorPatternConfig = exports.NoUnmanagedExceptionsConfig = exports.NoDestructureConfig = exports.PrismaConverterConfig = exports.PrismaValidateDtosConfig = exports.NoImplicitAnyConfig = exports.NoAnyUnknownConfig = exports.NoInlineTypeLiteralsConfig = exports.RequireReturnTypeConfig = exports.MaxFileLinesConfig = exports.MaxMethodLinesConfig = exports.BASE_RULE_SCHEMA = exports.BaseRuleConfig = exports.STRUCTURAL_MODES = exports.VALIDATE_TS_MODES = exports.BRANCH_GUARD_MODES = exports.ON_OFF_MODES = exports.THROW_CAUSE_MODES = exports.DIRECT_API_RESOLVER_MODES = exports.PRISMA_CONVERTER_MODES = exports.PRISMA_DTOS_MODES = exports.MODIFIED_CODE_MODES = exports.INLINE_TYPE_MODES = exports.RETURN_TYPE_MODES = exports.FILE_LIMIT_MODES = exports.METHOD_LIMIT_MODES = void 0;
4
4
  const field_def_1 = require("./field-def");
5
5
  // Mode const arrays — TypeScript union types derived from them, and FieldDef enum
6
6
  // values reference the same array. Impossible for the type and runtime check to diverge.
@@ -8,14 +8,14 @@ const field_def_1 = require("./field-def");
8
8
  // consumer) imports these instead of re-declaring the same unions — a rename here ripples
9
9
  // everywhere at compile time. The FieldDef SCHEMA below references the same arrays, so the
10
10
  // type and the runtime validation can never diverge.
11
- exports.METHOD_LIMIT_MODES = ['OFF', 'NEW_METHODS', 'NEW_AND_MODIFIED_METHODS', 'MODIFIED_FILES'];
12
- exports.FILE_LIMIT_MODES = ['OFF', 'MODIFIED_FILES'];
13
- exports.RETURN_TYPE_MODES = ['OFF', 'NEW_METHODS', 'NEW_AND_MODIFIED_METHODS', 'MODIFIED_FILES'];
14
- exports.INLINE_TYPE_MODES = ['OFF', 'NEW_METHODS', 'NEW_AND_MODIFIED_METHODS', 'MODIFIED_FILES'];
15
- exports.MODIFIED_CODE_MODES = ['OFF', 'MODIFIED_CODE', 'MODIFIED_FILES'];
16
- exports.PRISMA_DTOS_MODES = ['OFF', 'MODIFIED_CLASS', 'MODIFIED_FILES'];
17
- exports.PRISMA_CONVERTER_MODES = ['OFF', 'NEW_AND_MODIFIED_METHODS', 'MODIFIED_FILES'];
18
- exports.DIRECT_API_RESOLVER_MODES = ['OFF', 'MODIFIED_CODE', 'NEW_AND_MODIFIED_METHODS', 'MODIFIED_FILES'];
11
+ exports.METHOD_LIMIT_MODES = ['OFF', 'NEW_METHODS', 'NEW_AND_MODIFIED_METHODS', 'NEW_AND_MODIFIED_FILES'];
12
+ exports.FILE_LIMIT_MODES = ['OFF', 'NEW_AND_MODIFIED_FILES'];
13
+ exports.RETURN_TYPE_MODES = ['OFF', 'NEW_METHODS', 'NEW_AND_MODIFIED_METHODS', 'NEW_AND_MODIFIED_FILES'];
14
+ exports.INLINE_TYPE_MODES = ['OFF', 'NEW_METHODS', 'NEW_AND_MODIFIED_METHODS', 'NEW_AND_MODIFIED_FILES'];
15
+ exports.MODIFIED_CODE_MODES = ['OFF', 'MODIFIED_CODE', 'NEW_AND_MODIFIED_FILES'];
16
+ exports.PRISMA_DTOS_MODES = ['OFF', 'MODIFIED_CLASS', 'NEW_AND_MODIFIED_FILES'];
17
+ exports.PRISMA_CONVERTER_MODES = ['OFF', 'NEW_AND_MODIFIED_METHODS', 'NEW_AND_MODIFIED_FILES'];
18
+ exports.DIRECT_API_RESOLVER_MODES = ['OFF', 'MODIFIED_CODE', 'NEW_AND_MODIFIED_METHODS', 'NEW_AND_MODIFIED_FILES'];
19
19
  exports.THROW_CAUSE_MODES = ['OFF', 'MODIFIED_CODE'];
20
20
  exports.ON_OFF_MODES = ['ON', 'OFF'];
21
21
  // branch-creation-guard modes. ON_NO_SUBBRANCHES is the strict variant: it hard-blocks
@@ -23,7 +23,12 @@ exports.ON_OFF_MODES = ['ON', 'OFF'];
23
23
  // back to `git checkout main && git pull && git checkout -b <branch>`. Temporarily overridable
24
24
  // via the universal ignoreModifiedUntilEpoch escape hatch.
25
25
  exports.BRANCH_GUARD_MODES = ['ON', 'OFF', 'ON_NO_SUBBRANCHES'];
26
- exports.VALIDATE_TS_MODES = ['OFF', 'MODIFIED_FILES'];
26
+ exports.VALIDATE_TS_MODES = ['OFF', 'NEW_AND_MODIFIED_FILES'];
27
+ // Structural / whole-graph rules (import-cycle, runtime-architecture, nx-wiring). They can't be
28
+ // scoped to changed lines/files — a cycle or wiring break can route through a project that wasn't
29
+ // itself edited — so when active they run the FULL check every time (nx-affected already limits
30
+ // them to affected projects externally). RUN_EVERY_TIME replaces the old, vaguer "ON".
31
+ exports.STRUCTURAL_MODES = ['OFF', 'RUN_EVERY_TIME'];
27
32
  // ---------------------------------------------------------------------------
28
33
  // Universal escape hatches — EVERY rule supports temporarily disabling itself
29
34
  // either while on a named git branch (ignoreRuleWhileOnBranch) or until an
@@ -278,7 +283,7 @@ class NoFileImportCyclesConfig extends BaseRuleConfig {
278
283
  ignoreTypeOnly;
279
284
  excludePackages;
280
285
  static SCHEMA = {
281
- mode: new field_def_1.FieldDef('string', exports.ON_OFF_MODES),
286
+ mode: new field_def_1.FieldDef('string', exports.STRUCTURAL_MODES),
282
287
  ignoreTypeOnly: field_def_1.FieldDef.optional('boolean'),
283
288
  excludePackages: field_def_1.FieldDef.optional('string[]'),
284
289
  ...exports.BASE_RULE_SCHEMA,
@@ -290,7 +295,7 @@ class RuntimeArchitectureConfig extends BaseRuleConfig {
290
295
  apiProjectPaths;
291
296
  allowedCycles;
292
297
  static SCHEMA = {
293
- mode: new field_def_1.FieldDef('string', exports.ON_OFF_MODES),
298
+ mode: new field_def_1.FieldDef('string', exports.STRUCTURAL_MODES),
294
299
  servicePaths: field_def_1.FieldDef.optional('string[]'),
295
300
  apiProjectPaths: field_def_1.FieldDef.optional('string[]'),
296
301
  allowedCycles: field_def_1.FieldDef.optional('string[]'),
@@ -298,10 +303,17 @@ class RuntimeArchitectureConfig extends BaseRuleConfig {
298
303
  };
299
304
  }
300
305
  exports.RuntimeArchitectureConfig = RuntimeArchitectureConfig;
306
+ class NxWiringConfig extends BaseRuleConfig {
307
+ static SCHEMA = {
308
+ mode: new field_def_1.FieldDef('string', exports.STRUCTURAL_MODES),
309
+ ...exports.BASE_RULE_SCHEMA,
310
+ };
311
+ }
312
+ exports.NxWiringConfig = NxWiringConfig;
301
313
  class NoJsFilesConfig extends BaseRuleConfig {
302
314
  allowedPaths;
303
315
  static SCHEMA = {
304
- mode: new field_def_1.FieldDef('string', exports.ON_OFF_MODES),
316
+ mode: new field_def_1.FieldDef('string', exports.FILE_LIMIT_MODES),
305
317
  allowedPaths: field_def_1.FieldDef.optional('string[]'),
306
318
  ...exports.BASE_RULE_SCHEMA,
307
319
  };
@@ -1 +1 @@
1
- {"version":3,"file":"rule-configs.js","sourceRoot":"","sources":["../../../../../packages/tooling/rules-config/src/rule-configs.ts"],"names":[],"mappings":"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","sourcesContent":["import { FieldDef, SchemaShape } from './field-def';\n\n// Mode const arrays — TypeScript union types derived from them, and FieldDef enum\n// values reference the same array. Impossible for the type and runtime check to diverge.\n\n// Single source of truth for rule \"mode\" values. Exported so code-rules (and any other\n// consumer) imports these instead of re-declaring the same unions — a rename here ripples\n// everywhere at compile time. The FieldDef SCHEMA below references the same arrays, so the\n// type and the runtime validation can never diverge.\nexport const METHOD_LIMIT_MODES = ['OFF', 'NEW_METHODS', 'NEW_AND_MODIFIED_METHODS', 'MODIFIED_FILES'] as const;\nexport type MethodLimitMode = typeof METHOD_LIMIT_MODES[number];\n\nexport const FILE_LIMIT_MODES = ['OFF', 'MODIFIED_FILES'] as const;\nexport type FileLimitMode = typeof FILE_LIMIT_MODES[number];\n\nexport const RETURN_TYPE_MODES = ['OFF', 'NEW_METHODS', 'NEW_AND_MODIFIED_METHODS', 'MODIFIED_FILES'] as const;\nexport type ReturnTypeMode = typeof RETURN_TYPE_MODES[number];\n\nexport const INLINE_TYPE_MODES = ['OFF', 'NEW_METHODS', 'NEW_AND_MODIFIED_METHODS', 'MODIFIED_FILES'] as const;\nexport type InlineTypeMode = typeof INLINE_TYPE_MODES[number];\n\nexport const MODIFIED_CODE_MODES = ['OFF', 'MODIFIED_CODE', 'MODIFIED_FILES'] as const;\nexport type ModifiedCodeMode = typeof MODIFIED_CODE_MODES[number];\n\nexport const PRISMA_DTOS_MODES = ['OFF', 'MODIFIED_CLASS', 'MODIFIED_FILES'] as const;\nexport type PrismaValidateDtosMode = typeof PRISMA_DTOS_MODES[number];\n\nexport const PRISMA_CONVERTER_MODES = ['OFF', 'NEW_AND_MODIFIED_METHODS', 'MODIFIED_FILES'] as const;\nexport type PrismaConverterMode = typeof PRISMA_CONVERTER_MODES[number];\n\nexport const DIRECT_API_RESOLVER_MODES = ['OFF', 'MODIFIED_CODE', 'NEW_AND_MODIFIED_METHODS', 'MODIFIED_FILES'] as const;\nexport type DirectApiResolverMode = typeof DIRECT_API_RESOLVER_MODES[number];\n\nexport const THROW_CAUSE_MODES = ['OFF', 'MODIFIED_CODE'] as const;\nexport type ThrowCauseMode = typeof THROW_CAUSE_MODES[number];\n\nexport const ON_OFF_MODES = ['ON', 'OFF'] as const;\nexport type OnOffMode = typeof ON_OFF_MODES[number];\n\n// branch-creation-guard modes. ON_NO_SUBBRANCHES is the strict variant: it hard-blocks\n// creating a branch off any non-main branch (no sub-branch affordance), pointing the agent\n// back to `git checkout main && git pull && git checkout -b <branch>`. Temporarily overridable\n// via the universal ignoreModifiedUntilEpoch escape hatch.\nexport const BRANCH_GUARD_MODES = ['ON', 'OFF', 'ON_NO_SUBBRANCHES'] as const;\nexport type BranchGuardMode = typeof BRANCH_GUARD_MODES[number];\n\nexport const VALIDATE_TS_MODES = ['OFF', 'MODIFIED_FILES'] as const;\nexport type ValidateTsMode = typeof VALIDATE_TS_MODES[number];\n\n// ---------------------------------------------------------------------------\n// Universal escape hatches — EVERY rule supports temporarily disabling itself\n// either while on a named git branch (ignoreRuleWhileOnBranch) or until an\n// epoch passes (ignoreModifiedUntilEpoch). They live on a shared base class so\n// the two fields (and their schema entries) are declared once instead of\n// repeated per rule. `mode` stays per-rule because its allowed values vary\n// (ON/OFF vs MODIFIED_CODE vs NEW_AND_MODIFIED_METHODS, etc).\n//\n// `ignoreModifiedUntilEpoch` is REQUIRED on every rule so the time-box escape\n// hatch is always present and a rule can be turned off with a one-value edit.\n// Convention: 0 = rule active (epoch is in the past, never skipped); a future\n// unix epoch IN SECONDS = rule temporarily disabled until that moment.\n// `ignoreRuleWhileOnBranch` stays optional.\n// ---------------------------------------------------------------------------\nexport abstract class BaseRuleConfig {\n // `mode` is declared here (loosely typed) so the shared AbstractRule base can read it for\n // on/off. Each concrete *Config narrows it to its own union (e.g. `mode?: ModifiedCodeMode`),\n // which is an assignable (covariant) override.\n mode?: string;\n // TS-optional, but schema-REQUIRED (see BASE_RULE_SCHEMA) — same split as `mode`.\n ignoreModifiedUntilEpoch?: number;\n ignoreRuleWhileOnBranch?: string;\n}\n\nexport const BASE_RULE_SCHEMA = {\n ignoreModifiedUntilEpoch: new FieldDef('number'),\n ignoreRuleWhileOnBranch: FieldDef.optional('string'),\n};\n\nexport class MaxMethodLinesConfig extends BaseRuleConfig {\n declare mode?: MethodLimitMode;\n limit?: number;\n disableAllowed?: boolean;\n\n static readonly SCHEMA: SchemaShape<MaxMethodLinesConfig> = {\n mode: new FieldDef('string', METHOD_LIMIT_MODES),\n limit: FieldDef.optional('number'),\n disableAllowed: FieldDef.optional('boolean'),\n ...BASE_RULE_SCHEMA,\n };\n}\n\nexport class MaxFileLinesConfig extends BaseRuleConfig {\n declare mode?: FileLimitMode;\n limit?: number;\n disableAllowed?: boolean;\n\n static readonly SCHEMA: SchemaShape<MaxFileLinesConfig> = {\n mode: new FieldDef('string', FILE_LIMIT_MODES),\n limit: FieldDef.optional('number'),\n disableAllowed: FieldDef.optional('boolean'),\n ...BASE_RULE_SCHEMA,\n };\n}\n\nexport class RequireReturnTypeConfig extends BaseRuleConfig {\n declare mode?: ReturnTypeMode;\n disableAllowed?: boolean;\n\n static readonly SCHEMA: SchemaShape<RequireReturnTypeConfig> = {\n mode: new FieldDef('string', RETURN_TYPE_MODES),\n disableAllowed: FieldDef.optional('boolean'),\n ...BASE_RULE_SCHEMA,\n };\n}\n\nexport class NoInlineTypeLiteralsConfig extends BaseRuleConfig {\n declare mode?: InlineTypeMode;\n disableAllowed?: boolean;\n\n static readonly SCHEMA: SchemaShape<NoInlineTypeLiteralsConfig> = {\n mode: new FieldDef('string', INLINE_TYPE_MODES),\n disableAllowed: FieldDef.optional('boolean'),\n ...BASE_RULE_SCHEMA,\n };\n}\n\nexport class NoAnyUnknownConfig extends BaseRuleConfig {\n declare mode?: ModifiedCodeMode;\n disableAllowed?: boolean;\n\n static readonly SCHEMA: SchemaShape<NoAnyUnknownConfig> = {\n mode: new FieldDef('string', MODIFIED_CODE_MODES),\n disableAllowed: FieldDef.optional('boolean'),\n ...BASE_RULE_SCHEMA,\n };\n}\n\nexport class NoImplicitAnyConfig extends BaseRuleConfig {\n declare mode?: ModifiedCodeMode;\n disableAllowed?: boolean;\n\n static readonly SCHEMA: SchemaShape<NoImplicitAnyConfig> = {\n mode: new FieldDef('string', MODIFIED_CODE_MODES),\n disableAllowed: FieldDef.optional('boolean'),\n ...BASE_RULE_SCHEMA,\n };\n}\n\nexport class PrismaValidateDtosConfig extends BaseRuleConfig {\n declare mode?: PrismaValidateDtosMode;\n disableAllowed?: boolean;\n prismaSchemaPath?: string;\n dtoSourcePaths?: string[];\n\n static readonly SCHEMA: SchemaShape<PrismaValidateDtosConfig> = {\n mode: new FieldDef('string', PRISMA_DTOS_MODES),\n disableAllowed: FieldDef.optional('boolean'),\n prismaSchemaPath: FieldDef.optional('string'),\n dtoSourcePaths: FieldDef.optional('string[]'),\n ...BASE_RULE_SCHEMA,\n };\n}\n\nexport class PrismaConverterConfig extends BaseRuleConfig {\n declare mode?: PrismaConverterMode;\n disableAllowed?: boolean;\n schemaPath?: string;\n convertersPaths?: string[];\n enforcePaths?: string[];\n\n static readonly SCHEMA: SchemaShape<PrismaConverterConfig> = {\n mode: new FieldDef('string', PRISMA_CONVERTER_MODES),\n disableAllowed: FieldDef.optional('boolean'),\n schemaPath: FieldDef.optional('string'),\n convertersPaths: FieldDef.optional('string[]'),\n enforcePaths: FieldDef.optional('string[]'),\n ...BASE_RULE_SCHEMA,\n };\n}\n\nexport class NoDestructureConfig extends BaseRuleConfig {\n declare mode?: ModifiedCodeMode;\n allowTopLevel?: boolean;\n disableAllowed?: boolean;\n\n static readonly SCHEMA: SchemaShape<NoDestructureConfig> = {\n mode: new FieldDef('string', MODIFIED_CODE_MODES),\n allowTopLevel: FieldDef.optional('boolean'),\n disableAllowed: FieldDef.optional('boolean'),\n ...BASE_RULE_SCHEMA,\n };\n}\n\nexport class NoUnmanagedExceptionsConfig extends BaseRuleConfig {\n declare mode?: ModifiedCodeMode;\n disableAllowed?: boolean;\n\n static readonly SCHEMA: SchemaShape<NoUnmanagedExceptionsConfig> = {\n mode: new FieldDef('string', MODIFIED_CODE_MODES),\n disableAllowed: FieldDef.optional('boolean'),\n ...BASE_RULE_SCHEMA,\n };\n}\n\nexport class CatchErrorPatternConfig extends BaseRuleConfig {\n declare mode?: ModifiedCodeMode;\n disableAllowed?: boolean;\n\n static readonly SCHEMA: SchemaShape<CatchErrorPatternConfig> = {\n mode: new FieldDef('string', MODIFIED_CODE_MODES),\n disableAllowed: FieldDef.optional('boolean'),\n ...BASE_RULE_SCHEMA,\n };\n}\n\nexport class ThrowCauseRequiredConfig extends BaseRuleConfig {\n declare mode?: ThrowCauseMode;\n disableAllowed?: boolean;\n\n static readonly SCHEMA: SchemaShape<ThrowCauseRequiredConfig> = {\n mode: new FieldDef('string', THROW_CAUSE_MODES),\n disableAllowed: FieldDef.optional('boolean'),\n ...BASE_RULE_SCHEMA,\n };\n}\n\nexport class AngularNoDirectApiInResolverConfig extends BaseRuleConfig {\n declare mode?: DirectApiResolverMode;\n disableAllowed?: boolean;\n enforcePaths?: string[];\n\n static readonly SCHEMA: SchemaShape<AngularNoDirectApiInResolverConfig> = {\n mode: new FieldDef('string', DIRECT_API_RESOLVER_MODES),\n disableAllowed: FieldDef.optional('boolean'),\n enforcePaths: FieldDef.optional('string[]'),\n ...BASE_RULE_SCHEMA,\n };\n}\n\nexport class NoSymbolDiTokensConfig extends BaseRuleConfig {\n declare mode?: ModifiedCodeMode;\n disableAllowed?: boolean;\n allowedPaths?: string[];\n\n static readonly SCHEMA: SchemaShape<NoSymbolDiTokensConfig> = {\n mode: new FieldDef('string', MODIFIED_CODE_MODES),\n disableAllowed: FieldDef.optional('boolean'),\n allowedPaths: FieldDef.optional('string[]'),\n ...BASE_RULE_SCHEMA,\n };\n}\n\nexport class NoShellSubstitutionConfig extends BaseRuleConfig {\n declare mode?: OnOffMode;\n\n static readonly SCHEMA: SchemaShape<NoShellSubstitutionConfig> = {\n mode: new FieldDef('string', ON_OFF_MODES),\n ...BASE_RULE_SCHEMA,\n };\n}\n\nexport class BranchCreationGuardConfig extends BaseRuleConfig {\n declare mode?: BranchGuardMode;\n // Naming pattern for stacked SUB-branches only (branches created off another feature branch,\n // which require human approval). Never applied to branches created off main.\n subBranchNaming?: string;\n // Human-sentence instruction telling the AI how to name a NEW branch off main. Surfaced back\n // to the agent in the guard's fix hints. May mirror no-edit-on-main.branchNamingConvention.\n branchFormat?: string;\n\n static readonly SCHEMA: SchemaShape<BranchCreationGuardConfig> = {\n mode: new FieldDef('string', BRANCH_GUARD_MODES),\n subBranchNaming: FieldDef.optional('string'),\n branchFormat: FieldDef.optional('string'),\n ...BASE_RULE_SCHEMA,\n };\n}\n\nexport class PrCreationGuardConfig extends BaseRuleConfig {\n declare mode?: OnOffMode;\n // The gated command the guard points agents to instead of direct PR creation. Per-project\n // override; defaults to `pnpm wp-start-upsert-pr` at the point of use.\n upsertPrCommand?: string;\n\n static readonly SCHEMA: SchemaShape<PrCreationGuardConfig> = {\n mode: new FieldDef('string', ON_OFF_MODES),\n upsertPrCommand: FieldDef.optional('string'),\n ...BASE_RULE_SCHEMA,\n };\n}\n\nexport class MergeInProgressGuardConfig extends BaseRuleConfig {\n declare mode?: OnOffMode;\n // The gated command the guard points agents to in order to finish a 3-point merge. Per-project\n // override; defaults to `commands.mergeComplete` (pnpm wp-git-merge-complete) at load time.\n mergeCompleteCommand?: string;\n\n static readonly SCHEMA: SchemaShape<MergeInProgressGuardConfig> = {\n mode: new FieldDef('string', ON_OFF_MODES),\n mergeCompleteCommand: FieldDef.optional('string'),\n ...BASE_RULE_SCHEMA,\n };\n}\n\nexport class PrMergeCleanupConfig extends BaseRuleConfig {\n declare mode?: OnOffMode;\n\n static readonly SCHEMA: SchemaShape<PrMergeCleanupConfig> = {\n mode: new FieldDef('string', ON_OFF_MODES),\n ...BASE_RULE_SCHEMA,\n };\n}\n\nexport class NoDirectMainUpdateConfig extends BaseRuleConfig {\n declare mode?: OnOffMode;\n\n static readonly SCHEMA: SchemaShape<NoDirectMainUpdateConfig> = {\n mode: new FieldDef('string', ON_OFF_MODES),\n ...BASE_RULE_SCHEMA,\n };\n}\n\n// Comprehensive \"are you on a proper feature branch?\" guard. Replaces the old no-edit-on-main:\n// - on main (synchronous check) → block, create a feature branch\n// - branch already merged into main (merged PR) → block, branch off fresh main\n// - no fork point with origin/main → block, squash onto a new branch\n// - origin/main moved & touches your files → block, merge main first\n// branchNamingConvention is surfaced in the on-main message; hangTimeoutMinutes tunes the detached\n// refresher's stale-lock reclaim window.\nexport class FeatureBranchGuardConfig extends BaseRuleConfig {\n declare mode?: OnOffMode;\n branchNamingConvention?: string;\n hangTimeoutMinutes?: number;\n\n static readonly SCHEMA: SchemaShape<FeatureBranchGuardConfig> = {\n mode: new FieldDef('string', ON_OFF_MODES),\n branchNamingConvention: FieldDef.optional('string'),\n hangTimeoutMinutes: FieldDef.optional('number'),\n ...BASE_RULE_SCHEMA,\n };\n}\n\nexport class NoFileImportCyclesConfig extends BaseRuleConfig {\n declare mode?: OnOffMode;\n ignoreTypeOnly?: boolean;\n excludePackages?: string[];\n\n static readonly SCHEMA: SchemaShape<NoFileImportCyclesConfig> = {\n mode: new FieldDef('string', ON_OFF_MODES),\n ignoreTypeOnly: FieldDef.optional('boolean'),\n excludePackages: FieldDef.optional('string[]'),\n ...BASE_RULE_SCHEMA,\n };\n}\n\nexport class RuntimeArchitectureConfig extends BaseRuleConfig {\n declare mode?: OnOffMode;\n servicePaths?: string[];\n apiProjectPaths?: string[];\n allowedCycles?: string[];\n\n static readonly SCHEMA: SchemaShape<RuntimeArchitectureConfig> = {\n mode: new FieldDef('string', ON_OFF_MODES),\n servicePaths: FieldDef.optional('string[]'),\n apiProjectPaths: FieldDef.optional('string[]'),\n allowedCycles: FieldDef.optional('string[]'),\n ...BASE_RULE_SCHEMA,\n };\n}\n\nexport class NoJsFilesConfig extends BaseRuleConfig {\n declare mode?: OnOffMode;\n allowedPaths?: string[];\n\n static readonly SCHEMA: SchemaShape<NoJsFilesConfig> = {\n mode: new FieldDef('string', ON_OFF_MODES),\n allowedPaths: FieldDef.optional('string[]'),\n ...BASE_RULE_SCHEMA,\n };\n}\n\nexport class ValidateTsInSrcConfig extends BaseRuleConfig {\n declare mode?: ValidateTsMode;\n allowedRootFiles?: string[];\n excludePaths?: string[];\n\n static readonly SCHEMA: SchemaShape<ValidateTsInSrcConfig> = {\n mode: new FieldDef('string', VALIDATE_TS_MODES),\n allowedRootFiles: FieldDef.optional('string[]'),\n excludePaths: FieldDef.optional('string[]'),\n ...BASE_RULE_SCHEMA,\n };\n}\n"]}
1
+ {"version":3,"file":"rule-configs.js","sourceRoot":"","sources":["../../../../../packages/tooling/rules-config/src/rule-configs.ts"],"names":[],"mappings":";;;AAAA,2CAAoD;AAEpD,kFAAkF;AAClF,yFAAyF;AAEzF,uFAAuF;AACvF,0FAA0F;AAC1F,2FAA2F;AAC3F,qDAAqD;AACxC,QAAA,kBAAkB,GAAG,CAAC,KAAK,EAAE,aAAa,EAAE,0BAA0B,EAAE,wBAAwB,CAAU,CAAC;AAG3G,QAAA,gBAAgB,GAAG,CAAC,KAAK,EAAE,wBAAwB,CAAU,CAAC;AAG9D,QAAA,iBAAiB,GAAG,CAAC,KAAK,EAAE,aAAa,EAAE,0BAA0B,EAAE,wBAAwB,CAAU,CAAC;AAG1G,QAAA,iBAAiB,GAAG,CAAC,KAAK,EAAE,aAAa,EAAE,0BAA0B,EAAE,wBAAwB,CAAU,CAAC;AAG1G,QAAA,mBAAmB,GAAG,CAAC,KAAK,EAAE,eAAe,EAAE,wBAAwB,CAAU,CAAC;AAGlF,QAAA,iBAAiB,GAAG,CAAC,KAAK,EAAE,gBAAgB,EAAE,wBAAwB,CAAU,CAAC;AAGjF,QAAA,sBAAsB,GAAG,CAAC,KAAK,EAAE,0BAA0B,EAAE,wBAAwB,CAAU,CAAC;AAGhG,QAAA,yBAAyB,GAAG,CAAC,KAAK,EAAE,eAAe,EAAE,0BAA0B,EAAE,wBAAwB,CAAU,CAAC;AAGpH,QAAA,iBAAiB,GAAG,CAAC,KAAK,EAAE,eAAe,CAAU,CAAC;AAGtD,QAAA,YAAY,GAAG,CAAC,IAAI,EAAE,KAAK,CAAU,CAAC;AAGnD,uFAAuF;AACvF,2FAA2F;AAC3F,+FAA+F;AAC/F,2DAA2D;AAC9C,QAAA,kBAAkB,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,mBAAmB,CAAU,CAAC;AAGjE,QAAA,iBAAiB,GAAG,CAAC,KAAK,EAAE,wBAAwB,CAAU,CAAC;AAG5E,gGAAgG;AAChG,kGAAkG;AAClG,gGAAgG;AAChG,uFAAuF;AAC1E,QAAA,gBAAgB,GAAG,CAAC,KAAK,EAAE,gBAAgB,CAAU,CAAC;AAGnE,8EAA8E;AAC9E,8EAA8E;AAC9E,2EAA2E;AAC3E,+EAA+E;AAC/E,yEAAyE;AACzE,2EAA2E;AAC3E,8DAA8D;AAC9D,EAAE;AACF,8EAA8E;AAC9E,8EAA8E;AAC9E,8EAA8E;AAC9E,uEAAuE;AACvE,4CAA4C;AAC5C,8EAA8E;AAC9E,MAAsB,cAAc;IAChC,0FAA0F;IAC1F,8FAA8F;IAC9F,+CAA+C;IAC/C,IAAI,CAAU;IACd,kFAAkF;IAClF,wBAAwB,CAAU;IAClC,uBAAuB,CAAU;CACpC;AARD,wCAQC;AAEY,QAAA,gBAAgB,GAAG;IAC5B,wBAAwB,EAAE,IAAI,oBAAQ,CAAC,QAAQ,CAAC;IAChD,uBAAuB,EAAE,oBAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC;CACvD,CAAC;AAEF,MAAa,oBAAqB,SAAQ,cAAc;IAEpD,KAAK,CAAU;IACf,cAAc,CAAW;IAEzB,MAAM,CAAU,MAAM,GAAsC;QACxD,IAAI,EAAE,IAAI,oBAAQ,CAAC,QAAQ,EAAE,0BAAkB,CAAC;QAChD,KAAK,EAAE,oBAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAClC,cAAc,EAAE,oBAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC;QAC5C,GAAG,wBAAgB;KACtB,CAAC;;AAVN,oDAWC;AAED,MAAa,kBAAmB,SAAQ,cAAc;IAElD,KAAK,CAAU;IACf,cAAc,CAAW;IAEzB,MAAM,CAAU,MAAM,GAAoC;QACtD,IAAI,EAAE,IAAI,oBAAQ,CAAC,QAAQ,EAAE,wBAAgB,CAAC;QAC9C,KAAK,EAAE,oBAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAClC,cAAc,EAAE,oBAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC;QAC5C,GAAG,wBAAgB;KACtB,CAAC;;AAVN,gDAWC;AAED,MAAa,uBAAwB,SAAQ,cAAc;IAEvD,cAAc,CAAW;IAEzB,MAAM,CAAU,MAAM,GAAyC;QAC3D,IAAI,EAAE,IAAI,oBAAQ,CAAC,QAAQ,EAAE,yBAAiB,CAAC;QAC/C,cAAc,EAAE,oBAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC;QAC5C,GAAG,wBAAgB;KACtB,CAAC;;AARN,0DASC;AAED,MAAa,0BAA2B,SAAQ,cAAc;IAE1D,cAAc,CAAW;IAEzB,MAAM,CAAU,MAAM,GAA4C;QAC9D,IAAI,EAAE,IAAI,oBAAQ,CAAC,QAAQ,EAAE,yBAAiB,CAAC;QAC/C,cAAc,EAAE,oBAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC;QAC5C,GAAG,wBAAgB;KACtB,CAAC;;AARN,gEASC;AAED,MAAa,kBAAmB,SAAQ,cAAc;IAElD,cAAc,CAAW;IAEzB,MAAM,CAAU,MAAM,GAAoC;QACtD,IAAI,EAAE,IAAI,oBAAQ,CAAC,QAAQ,EAAE,2BAAmB,CAAC;QACjD,cAAc,EAAE,oBAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC;QAC5C,GAAG,wBAAgB;KACtB,CAAC;;AARN,gDASC;AAED,MAAa,mBAAoB,SAAQ,cAAc;IAEnD,cAAc,CAAW;IAEzB,MAAM,CAAU,MAAM,GAAqC;QACvD,IAAI,EAAE,IAAI,oBAAQ,CAAC,QAAQ,EAAE,2BAAmB,CAAC;QACjD,cAAc,EAAE,oBAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC;QAC5C,GAAG,wBAAgB;KACtB,CAAC;;AARN,kDASC;AAED,MAAa,wBAAyB,SAAQ,cAAc;IAExD,cAAc,CAAW;IACzB,gBAAgB,CAAU;IAC1B,cAAc,CAAY;IAE1B,MAAM,CAAU,MAAM,GAA0C;QAC5D,IAAI,EAAE,IAAI,oBAAQ,CAAC,QAAQ,EAAE,yBAAiB,CAAC;QAC/C,cAAc,EAAE,oBAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC;QAC5C,gBAAgB,EAAE,oBAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAC7C,cAAc,EAAE,oBAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC;QAC7C,GAAG,wBAAgB;KACtB,CAAC;;AAZN,4DAaC;AAED,MAAa,qBAAsB,SAAQ,cAAc;IAErD,cAAc,CAAW;IACzB,UAAU,CAAU;IACpB,eAAe,CAAY;IAC3B,YAAY,CAAY;IAExB,MAAM,CAAU,MAAM,GAAuC;QACzD,IAAI,EAAE,IAAI,oBAAQ,CAAC,QAAQ,EAAE,8BAAsB,CAAC;QACpD,cAAc,EAAE,oBAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC;QAC5C,UAAU,EAAE,oBAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC;QACvC,eAAe,EAAE,oBAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC;QAC9C,YAAY,EAAE,oBAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC;QAC3C,GAAG,wBAAgB;KACtB,CAAC;;AAdN,sDAeC;AAED,MAAa,mBAAoB,SAAQ,cAAc;IAEnD,aAAa,CAAW;IACxB,cAAc,CAAW;IAEzB,MAAM,CAAU,MAAM,GAAqC;QACvD,IAAI,EAAE,IAAI,oBAAQ,CAAC,QAAQ,EAAE,2BAAmB,CAAC;QACjD,aAAa,EAAE,oBAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC;QAC3C,cAAc,EAAE,oBAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC;QAC5C,GAAG,wBAAgB;KACtB,CAAC;;AAVN,kDAWC;AAED,MAAa,2BAA4B,SAAQ,cAAc;IAE3D,cAAc,CAAW;IAEzB,MAAM,CAAU,MAAM,GAA6C;QAC/D,IAAI,EAAE,IAAI,oBAAQ,CAAC,QAAQ,EAAE,2BAAmB,CAAC;QACjD,cAAc,EAAE,oBAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC;QAC5C,GAAG,wBAAgB;KACtB,CAAC;;AARN,kEASC;AAED,MAAa,uBAAwB,SAAQ,cAAc;IAEvD,cAAc,CAAW;IAEzB,MAAM,CAAU,MAAM,GAAyC;QAC3D,IAAI,EAAE,IAAI,oBAAQ,CAAC,QAAQ,EAAE,2BAAmB,CAAC;QACjD,cAAc,EAAE,oBAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC;QAC5C,GAAG,wBAAgB;KACtB,CAAC;;AARN,0DASC;AAED,MAAa,wBAAyB,SAAQ,cAAc;IAExD,cAAc,CAAW;IAEzB,MAAM,CAAU,MAAM,GAA0C;QAC5D,IAAI,EAAE,IAAI,oBAAQ,CAAC,QAAQ,EAAE,yBAAiB,CAAC;QAC/C,cAAc,EAAE,oBAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC;QAC5C,GAAG,wBAAgB;KACtB,CAAC;;AARN,4DASC;AAED,MAAa,kCAAmC,SAAQ,cAAc;IAElE,cAAc,CAAW;IACzB,YAAY,CAAY;IAExB,MAAM,CAAU,MAAM,GAAoD;QACtE,IAAI,EAAE,IAAI,oBAAQ,CAAC,QAAQ,EAAE,iCAAyB,CAAC;QACvD,cAAc,EAAE,oBAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC;QAC5C,YAAY,EAAE,oBAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC;QAC3C,GAAG,wBAAgB;KACtB,CAAC;;AAVN,gFAWC;AAED,MAAa,sBAAuB,SAAQ,cAAc;IAEtD,cAAc,CAAW;IACzB,YAAY,CAAY;IAExB,MAAM,CAAU,MAAM,GAAwC;QAC1D,IAAI,EAAE,IAAI,oBAAQ,CAAC,QAAQ,EAAE,2BAAmB,CAAC;QACjD,cAAc,EAAE,oBAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC;QAC5C,YAAY,EAAE,oBAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC;QAC3C,GAAG,wBAAgB;KACtB,CAAC;;AAVN,wDAWC;AAED,MAAa,yBAA0B,SAAQ,cAAc;IAGzD,MAAM,CAAU,MAAM,GAA2C;QAC7D,IAAI,EAAE,IAAI,oBAAQ,CAAC,QAAQ,EAAE,oBAAY,CAAC;QAC1C,GAAG,wBAAgB;KACtB,CAAC;;AANN,8DAOC;AAED,MAAa,yBAA0B,SAAQ,cAAc;IAEzD,6FAA6F;IAC7F,6EAA6E;IAC7E,eAAe,CAAU;IACzB,6FAA6F;IAC7F,4FAA4F;IAC5F,YAAY,CAAU;IAEtB,MAAM,CAAU,MAAM,GAA2C;QAC7D,IAAI,EAAE,IAAI,oBAAQ,CAAC,QAAQ,EAAE,0BAAkB,CAAC;QAChD,eAAe,EAAE,oBAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAC5C,YAAY,EAAE,oBAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC;QACzC,GAAG,wBAAgB;KACtB,CAAC;;AAdN,8DAeC;AAED,MAAa,qBAAsB,SAAQ,cAAc;IAErD,0FAA0F;IAC1F,uEAAuE;IACvE,eAAe,CAAU;IAEzB,MAAM,CAAU,MAAM,GAAuC;QACzD,IAAI,EAAE,IAAI,oBAAQ,CAAC,QAAQ,EAAE,oBAAY,CAAC;QAC1C,eAAe,EAAE,oBAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAC5C,GAAG,wBAAgB;KACtB,CAAC;;AAVN,sDAWC;AAED,MAAa,0BAA2B,SAAQ,cAAc;IAE1D,+FAA+F;IAC/F,4FAA4F;IAC5F,oBAAoB,CAAU;IAE9B,MAAM,CAAU,MAAM,GAA4C;QAC9D,IAAI,EAAE,IAAI,oBAAQ,CAAC,QAAQ,EAAE,oBAAY,CAAC;QAC1C,oBAAoB,EAAE,oBAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC;QACjD,GAAG,wBAAgB;KACtB,CAAC;;AAVN,gEAWC;AAED,MAAa,oBAAqB,SAAQ,cAAc;IAGpD,MAAM,CAAU,MAAM,GAAsC;QACxD,IAAI,EAAE,IAAI,oBAAQ,CAAC,QAAQ,EAAE,oBAAY,CAAC;QAC1C,GAAG,wBAAgB;KACtB,CAAC;;AANN,oDAOC;AAED,MAAa,wBAAyB,SAAQ,cAAc;IAGxD,MAAM,CAAU,MAAM,GAA0C;QAC5D,IAAI,EAAE,IAAI,oBAAQ,CAAC,QAAQ,EAAE,oBAAY,CAAC;QAC1C,GAAG,wBAAgB;KACtB,CAAC;;AANN,4DAOC;AAED,+FAA+F;AAC/F,mFAAmF;AACnF,iFAAiF;AACjF,oFAAoF;AACpF,4EAA4E;AAC5E,mGAAmG;AACnG,yCAAyC;AACzC,MAAa,wBAAyB,SAAQ,cAAc;IAExD,sBAAsB,CAAU;IAChC,kBAAkB,CAAU;IAE5B,MAAM,CAAU,MAAM,GAA0C;QAC5D,IAAI,EAAE,IAAI,oBAAQ,CAAC,QAAQ,EAAE,oBAAY,CAAC;QAC1C,sBAAsB,EAAE,oBAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC;QACnD,kBAAkB,EAAE,oBAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAC/C,GAAG,wBAAgB;KACtB,CAAC;;AAVN,4DAWC;AAED,MAAa,wBAAyB,SAAQ,cAAc;IAExD,cAAc,CAAW;IACzB,eAAe,CAAY;IAE3B,MAAM,CAAU,MAAM,GAA0C;QAC5D,IAAI,EAAE,IAAI,oBAAQ,CAAC,QAAQ,EAAE,wBAAgB,CAAC;QAC9C,cAAc,EAAE,oBAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC;QAC5C,eAAe,EAAE,oBAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC;QAC9C,GAAG,wBAAgB;KACtB,CAAC;;AAVN,4DAWC;AAED,MAAa,yBAA0B,SAAQ,cAAc;IAEzD,YAAY,CAAY;IACxB,eAAe,CAAY;IAC3B,aAAa,CAAY;IAEzB,MAAM,CAAU,MAAM,GAA2C;QAC7D,IAAI,EAAE,IAAI,oBAAQ,CAAC,QAAQ,EAAE,wBAAgB,CAAC;QAC9C,YAAY,EAAE,oBAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC;QAC3C,eAAe,EAAE,oBAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC;QAC9C,aAAa,EAAE,oBAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC;QAC5C,GAAG,wBAAgB;KACtB,CAAC;;AAZN,8DAaC;AAED,MAAa,cAAe,SAAQ,cAAc;IAG9C,MAAM,CAAU,MAAM,GAAgC;QAClD,IAAI,EAAE,IAAI,oBAAQ,CAAC,QAAQ,EAAE,wBAAgB,CAAC;QAC9C,GAAG,wBAAgB;KACtB,CAAC;;AANN,wCAOC;AAED,MAAa,eAAgB,SAAQ,cAAc;IAI/C,YAAY,CAAY;IAExB,MAAM,CAAU,MAAM,GAAiC;QACnD,IAAI,EAAE,IAAI,oBAAQ,CAAC,QAAQ,EAAE,wBAAgB,CAAC;QAC9C,YAAY,EAAE,oBAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC;QAC3C,GAAG,wBAAgB;KACtB,CAAC;;AAVN,0CAWC;AAED,MAAa,qBAAsB,SAAQ,cAAc;IAErD,gBAAgB,CAAY;IAC5B,YAAY,CAAY;IAExB,MAAM,CAAU,MAAM,GAAuC;QACzD,IAAI,EAAE,IAAI,oBAAQ,CAAC,QAAQ,EAAE,yBAAiB,CAAC;QAC/C,gBAAgB,EAAE,oBAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC;QAC/C,YAAY,EAAE,oBAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC;QAC3C,GAAG,wBAAgB;KACtB,CAAC;;AAVN,sDAWC","sourcesContent":["import { FieldDef, SchemaShape } from './field-def';\n\n// Mode const arrays — TypeScript union types derived from them, and FieldDef enum\n// values reference the same array. Impossible for the type and runtime check to diverge.\n\n// Single source of truth for rule \"mode\" values. Exported so code-rules (and any other\n// consumer) imports these instead of re-declaring the same unions — a rename here ripples\n// everywhere at compile time. The FieldDef SCHEMA below references the same arrays, so the\n// type and the runtime validation can never diverge.\nexport const METHOD_LIMIT_MODES = ['OFF', 'NEW_METHODS', 'NEW_AND_MODIFIED_METHODS', 'NEW_AND_MODIFIED_FILES'] as const;\nexport type MethodLimitMode = typeof METHOD_LIMIT_MODES[number];\n\nexport const FILE_LIMIT_MODES = ['OFF', 'NEW_AND_MODIFIED_FILES'] as const;\nexport type FileLimitMode = typeof FILE_LIMIT_MODES[number];\n\nexport const RETURN_TYPE_MODES = ['OFF', 'NEW_METHODS', 'NEW_AND_MODIFIED_METHODS', 'NEW_AND_MODIFIED_FILES'] as const;\nexport type ReturnTypeMode = typeof RETURN_TYPE_MODES[number];\n\nexport const INLINE_TYPE_MODES = ['OFF', 'NEW_METHODS', 'NEW_AND_MODIFIED_METHODS', 'NEW_AND_MODIFIED_FILES'] as const;\nexport type InlineTypeMode = typeof INLINE_TYPE_MODES[number];\n\nexport const MODIFIED_CODE_MODES = ['OFF', 'MODIFIED_CODE', 'NEW_AND_MODIFIED_FILES'] as const;\nexport type ModifiedCodeMode = typeof MODIFIED_CODE_MODES[number];\n\nexport const PRISMA_DTOS_MODES = ['OFF', 'MODIFIED_CLASS', 'NEW_AND_MODIFIED_FILES'] as const;\nexport type PrismaValidateDtosMode = typeof PRISMA_DTOS_MODES[number];\n\nexport const PRISMA_CONVERTER_MODES = ['OFF', 'NEW_AND_MODIFIED_METHODS', 'NEW_AND_MODIFIED_FILES'] as const;\nexport type PrismaConverterMode = typeof PRISMA_CONVERTER_MODES[number];\n\nexport const DIRECT_API_RESOLVER_MODES = ['OFF', 'MODIFIED_CODE', 'NEW_AND_MODIFIED_METHODS', 'NEW_AND_MODIFIED_FILES'] as const;\nexport type DirectApiResolverMode = typeof DIRECT_API_RESOLVER_MODES[number];\n\nexport const THROW_CAUSE_MODES = ['OFF', 'MODIFIED_CODE'] as const;\nexport type ThrowCauseMode = typeof THROW_CAUSE_MODES[number];\n\nexport const ON_OFF_MODES = ['ON', 'OFF'] as const;\nexport type OnOffMode = typeof ON_OFF_MODES[number];\n\n// branch-creation-guard modes. ON_NO_SUBBRANCHES is the strict variant: it hard-blocks\n// creating a branch off any non-main branch (no sub-branch affordance), pointing the agent\n// back to `git checkout main && git pull && git checkout -b <branch>`. Temporarily overridable\n// via the universal ignoreModifiedUntilEpoch escape hatch.\nexport const BRANCH_GUARD_MODES = ['ON', 'OFF', 'ON_NO_SUBBRANCHES'] as const;\nexport type BranchGuardMode = typeof BRANCH_GUARD_MODES[number];\n\nexport const VALIDATE_TS_MODES = ['OFF', 'NEW_AND_MODIFIED_FILES'] as const;\nexport type ValidateTsMode = typeof VALIDATE_TS_MODES[number];\n\n// Structural / whole-graph rules (import-cycle, runtime-architecture, nx-wiring). They can't be\n// scoped to changed lines/files — a cycle or wiring break can route through a project that wasn't\n// itself edited — so when active they run the FULL check every time (nx-affected already limits\n// them to affected projects externally). RUN_EVERY_TIME replaces the old, vaguer \"ON\".\nexport const STRUCTURAL_MODES = ['OFF', 'RUN_EVERY_TIME'] as const;\nexport type StructuralMode = typeof STRUCTURAL_MODES[number];\n\n// ---------------------------------------------------------------------------\n// Universal escape hatches — EVERY rule supports temporarily disabling itself\n// either while on a named git branch (ignoreRuleWhileOnBranch) or until an\n// epoch passes (ignoreModifiedUntilEpoch). They live on a shared base class so\n// the two fields (and their schema entries) are declared once instead of\n// repeated per rule. `mode` stays per-rule because its allowed values vary\n// (ON/OFF vs MODIFIED_CODE vs NEW_AND_MODIFIED_METHODS, etc).\n//\n// `ignoreModifiedUntilEpoch` is REQUIRED on every rule so the time-box escape\n// hatch is always present and a rule can be turned off with a one-value edit.\n// Convention: 0 = rule active (epoch is in the past, never skipped); a future\n// unix epoch IN SECONDS = rule temporarily disabled until that moment.\n// `ignoreRuleWhileOnBranch` stays optional.\n// ---------------------------------------------------------------------------\nexport abstract class BaseRuleConfig {\n // `mode` is declared here (loosely typed) so the shared AbstractRule base can read it for\n // on/off. Each concrete *Config narrows it to its own union (e.g. `mode?: ModifiedCodeMode`),\n // which is an assignable (covariant) override.\n mode?: string;\n // TS-optional, but schema-REQUIRED (see BASE_RULE_SCHEMA) — same split as `mode`.\n ignoreModifiedUntilEpoch?: number;\n ignoreRuleWhileOnBranch?: string;\n}\n\nexport const BASE_RULE_SCHEMA = {\n ignoreModifiedUntilEpoch: new FieldDef('number'),\n ignoreRuleWhileOnBranch: FieldDef.optional('string'),\n};\n\nexport class MaxMethodLinesConfig extends BaseRuleConfig {\n declare mode?: MethodLimitMode;\n limit?: number;\n disableAllowed?: boolean;\n\n static readonly SCHEMA: SchemaShape<MaxMethodLinesConfig> = {\n mode: new FieldDef('string', METHOD_LIMIT_MODES),\n limit: FieldDef.optional('number'),\n disableAllowed: FieldDef.optional('boolean'),\n ...BASE_RULE_SCHEMA,\n };\n}\n\nexport class MaxFileLinesConfig extends BaseRuleConfig {\n declare mode?: FileLimitMode;\n limit?: number;\n disableAllowed?: boolean;\n\n static readonly SCHEMA: SchemaShape<MaxFileLinesConfig> = {\n mode: new FieldDef('string', FILE_LIMIT_MODES),\n limit: FieldDef.optional('number'),\n disableAllowed: FieldDef.optional('boolean'),\n ...BASE_RULE_SCHEMA,\n };\n}\n\nexport class RequireReturnTypeConfig extends BaseRuleConfig {\n declare mode?: ReturnTypeMode;\n disableAllowed?: boolean;\n\n static readonly SCHEMA: SchemaShape<RequireReturnTypeConfig> = {\n mode: new FieldDef('string', RETURN_TYPE_MODES),\n disableAllowed: FieldDef.optional('boolean'),\n ...BASE_RULE_SCHEMA,\n };\n}\n\nexport class NoInlineTypeLiteralsConfig extends BaseRuleConfig {\n declare mode?: InlineTypeMode;\n disableAllowed?: boolean;\n\n static readonly SCHEMA: SchemaShape<NoInlineTypeLiteralsConfig> = {\n mode: new FieldDef('string', INLINE_TYPE_MODES),\n disableAllowed: FieldDef.optional('boolean'),\n ...BASE_RULE_SCHEMA,\n };\n}\n\nexport class NoAnyUnknownConfig extends BaseRuleConfig {\n declare mode?: ModifiedCodeMode;\n disableAllowed?: boolean;\n\n static readonly SCHEMA: SchemaShape<NoAnyUnknownConfig> = {\n mode: new FieldDef('string', MODIFIED_CODE_MODES),\n disableAllowed: FieldDef.optional('boolean'),\n ...BASE_RULE_SCHEMA,\n };\n}\n\nexport class NoImplicitAnyConfig extends BaseRuleConfig {\n declare mode?: ModifiedCodeMode;\n disableAllowed?: boolean;\n\n static readonly SCHEMA: SchemaShape<NoImplicitAnyConfig> = {\n mode: new FieldDef('string', MODIFIED_CODE_MODES),\n disableAllowed: FieldDef.optional('boolean'),\n ...BASE_RULE_SCHEMA,\n };\n}\n\nexport class PrismaValidateDtosConfig extends BaseRuleConfig {\n declare mode?: PrismaValidateDtosMode;\n disableAllowed?: boolean;\n prismaSchemaPath?: string;\n dtoSourcePaths?: string[];\n\n static readonly SCHEMA: SchemaShape<PrismaValidateDtosConfig> = {\n mode: new FieldDef('string', PRISMA_DTOS_MODES),\n disableAllowed: FieldDef.optional('boolean'),\n prismaSchemaPath: FieldDef.optional('string'),\n dtoSourcePaths: FieldDef.optional('string[]'),\n ...BASE_RULE_SCHEMA,\n };\n}\n\nexport class PrismaConverterConfig extends BaseRuleConfig {\n declare mode?: PrismaConverterMode;\n disableAllowed?: boolean;\n schemaPath?: string;\n convertersPaths?: string[];\n enforcePaths?: string[];\n\n static readonly SCHEMA: SchemaShape<PrismaConverterConfig> = {\n mode: new FieldDef('string', PRISMA_CONVERTER_MODES),\n disableAllowed: FieldDef.optional('boolean'),\n schemaPath: FieldDef.optional('string'),\n convertersPaths: FieldDef.optional('string[]'),\n enforcePaths: FieldDef.optional('string[]'),\n ...BASE_RULE_SCHEMA,\n };\n}\n\nexport class NoDestructureConfig extends BaseRuleConfig {\n declare mode?: ModifiedCodeMode;\n allowTopLevel?: boolean;\n disableAllowed?: boolean;\n\n static readonly SCHEMA: SchemaShape<NoDestructureConfig> = {\n mode: new FieldDef('string', MODIFIED_CODE_MODES),\n allowTopLevel: FieldDef.optional('boolean'),\n disableAllowed: FieldDef.optional('boolean'),\n ...BASE_RULE_SCHEMA,\n };\n}\n\nexport class NoUnmanagedExceptionsConfig extends BaseRuleConfig {\n declare mode?: ModifiedCodeMode;\n disableAllowed?: boolean;\n\n static readonly SCHEMA: SchemaShape<NoUnmanagedExceptionsConfig> = {\n mode: new FieldDef('string', MODIFIED_CODE_MODES),\n disableAllowed: FieldDef.optional('boolean'),\n ...BASE_RULE_SCHEMA,\n };\n}\n\nexport class CatchErrorPatternConfig extends BaseRuleConfig {\n declare mode?: ModifiedCodeMode;\n disableAllowed?: boolean;\n\n static readonly SCHEMA: SchemaShape<CatchErrorPatternConfig> = {\n mode: new FieldDef('string', MODIFIED_CODE_MODES),\n disableAllowed: FieldDef.optional('boolean'),\n ...BASE_RULE_SCHEMA,\n };\n}\n\nexport class ThrowCauseRequiredConfig extends BaseRuleConfig {\n declare mode?: ThrowCauseMode;\n disableAllowed?: boolean;\n\n static readonly SCHEMA: SchemaShape<ThrowCauseRequiredConfig> = {\n mode: new FieldDef('string', THROW_CAUSE_MODES),\n disableAllowed: FieldDef.optional('boolean'),\n ...BASE_RULE_SCHEMA,\n };\n}\n\nexport class AngularNoDirectApiInResolverConfig extends BaseRuleConfig {\n declare mode?: DirectApiResolverMode;\n disableAllowed?: boolean;\n enforcePaths?: string[];\n\n static readonly SCHEMA: SchemaShape<AngularNoDirectApiInResolverConfig> = {\n mode: new FieldDef('string', DIRECT_API_RESOLVER_MODES),\n disableAllowed: FieldDef.optional('boolean'),\n enforcePaths: FieldDef.optional('string[]'),\n ...BASE_RULE_SCHEMA,\n };\n}\n\nexport class NoSymbolDiTokensConfig extends BaseRuleConfig {\n declare mode?: ModifiedCodeMode;\n disableAllowed?: boolean;\n allowedPaths?: string[];\n\n static readonly SCHEMA: SchemaShape<NoSymbolDiTokensConfig> = {\n mode: new FieldDef('string', MODIFIED_CODE_MODES),\n disableAllowed: FieldDef.optional('boolean'),\n allowedPaths: FieldDef.optional('string[]'),\n ...BASE_RULE_SCHEMA,\n };\n}\n\nexport class NoShellSubstitutionConfig extends BaseRuleConfig {\n declare mode?: OnOffMode;\n\n static readonly SCHEMA: SchemaShape<NoShellSubstitutionConfig> = {\n mode: new FieldDef('string', ON_OFF_MODES),\n ...BASE_RULE_SCHEMA,\n };\n}\n\nexport class BranchCreationGuardConfig extends BaseRuleConfig {\n declare mode?: BranchGuardMode;\n // Naming pattern for stacked SUB-branches only (branches created off another feature branch,\n // which require human approval). Never applied to branches created off main.\n subBranchNaming?: string;\n // Human-sentence instruction telling the AI how to name a NEW branch off main. Surfaced back\n // to the agent in the guard's fix hints. May mirror no-edit-on-main.branchNamingConvention.\n branchFormat?: string;\n\n static readonly SCHEMA: SchemaShape<BranchCreationGuardConfig> = {\n mode: new FieldDef('string', BRANCH_GUARD_MODES),\n subBranchNaming: FieldDef.optional('string'),\n branchFormat: FieldDef.optional('string'),\n ...BASE_RULE_SCHEMA,\n };\n}\n\nexport class PrCreationGuardConfig extends BaseRuleConfig {\n declare mode?: OnOffMode;\n // The gated command the guard points agents to instead of direct PR creation. Per-project\n // override; defaults to `pnpm wp-start-upsert-pr` at the point of use.\n upsertPrCommand?: string;\n\n static readonly SCHEMA: SchemaShape<PrCreationGuardConfig> = {\n mode: new FieldDef('string', ON_OFF_MODES),\n upsertPrCommand: FieldDef.optional('string'),\n ...BASE_RULE_SCHEMA,\n };\n}\n\nexport class MergeInProgressGuardConfig extends BaseRuleConfig {\n declare mode?: OnOffMode;\n // The gated command the guard points agents to in order to finish a 3-point merge. Per-project\n // override; defaults to `commands.mergeComplete` (pnpm wp-git-merge-complete) at load time.\n mergeCompleteCommand?: string;\n\n static readonly SCHEMA: SchemaShape<MergeInProgressGuardConfig> = {\n mode: new FieldDef('string', ON_OFF_MODES),\n mergeCompleteCommand: FieldDef.optional('string'),\n ...BASE_RULE_SCHEMA,\n };\n}\n\nexport class PrMergeCleanupConfig extends BaseRuleConfig {\n declare mode?: OnOffMode;\n\n static readonly SCHEMA: SchemaShape<PrMergeCleanupConfig> = {\n mode: new FieldDef('string', ON_OFF_MODES),\n ...BASE_RULE_SCHEMA,\n };\n}\n\nexport class NoDirectMainUpdateConfig extends BaseRuleConfig {\n declare mode?: OnOffMode;\n\n static readonly SCHEMA: SchemaShape<NoDirectMainUpdateConfig> = {\n mode: new FieldDef('string', ON_OFF_MODES),\n ...BASE_RULE_SCHEMA,\n };\n}\n\n// Comprehensive \"are you on a proper feature branch?\" guard. Replaces the old no-edit-on-main:\n// - on main (synchronous check) → block, create a feature branch\n// - branch already merged into main (merged PR) → block, branch off fresh main\n// - no fork point with origin/main → block, squash onto a new branch\n// - origin/main moved & touches your files → block, merge main first\n// branchNamingConvention is surfaced in the on-main message; hangTimeoutMinutes tunes the detached\n// refresher's stale-lock reclaim window.\nexport class FeatureBranchGuardConfig extends BaseRuleConfig {\n declare mode?: OnOffMode;\n branchNamingConvention?: string;\n hangTimeoutMinutes?: number;\n\n static readonly SCHEMA: SchemaShape<FeatureBranchGuardConfig> = {\n mode: new FieldDef('string', ON_OFF_MODES),\n branchNamingConvention: FieldDef.optional('string'),\n hangTimeoutMinutes: FieldDef.optional('number'),\n ...BASE_RULE_SCHEMA,\n };\n}\n\nexport class NoFileImportCyclesConfig extends BaseRuleConfig {\n declare mode?: StructuralMode;\n ignoreTypeOnly?: boolean;\n excludePackages?: string[];\n\n static readonly SCHEMA: SchemaShape<NoFileImportCyclesConfig> = {\n mode: new FieldDef('string', STRUCTURAL_MODES),\n ignoreTypeOnly: FieldDef.optional('boolean'),\n excludePackages: FieldDef.optional('string[]'),\n ...BASE_RULE_SCHEMA,\n };\n}\n\nexport class RuntimeArchitectureConfig extends BaseRuleConfig {\n declare mode?: StructuralMode;\n servicePaths?: string[];\n apiProjectPaths?: string[];\n allowedCycles?: string[];\n\n static readonly SCHEMA: SchemaShape<RuntimeArchitectureConfig> = {\n mode: new FieldDef('string', STRUCTURAL_MODES),\n servicePaths: FieldDef.optional('string[]'),\n apiProjectPaths: FieldDef.optional('string[]'),\n allowedCycles: FieldDef.optional('string[]'),\n ...BASE_RULE_SCHEMA,\n };\n}\n\nexport class NxWiringConfig extends BaseRuleConfig {\n declare mode?: StructuralMode;\n\n static readonly SCHEMA: SchemaShape<NxWiringConfig> = {\n mode: new FieldDef('string', STRUCTURAL_MODES),\n ...BASE_RULE_SCHEMA,\n };\n}\n\nexport class NoJsFilesConfig extends BaseRuleConfig {\n // File-tier: NEW_AND_MODIFIED_FILES (active) intercepts a .js/.jsx Write — the file being\n // written is inherently a new/modified file, so it's already diff-scoped in practice.\n declare mode?: FileLimitMode;\n allowedPaths?: string[];\n\n static readonly SCHEMA: SchemaShape<NoJsFilesConfig> = {\n mode: new FieldDef('string', FILE_LIMIT_MODES),\n allowedPaths: FieldDef.optional('string[]'),\n ...BASE_RULE_SCHEMA,\n };\n}\n\nexport class ValidateTsInSrcConfig extends BaseRuleConfig {\n declare mode?: ValidateTsMode;\n allowedRootFiles?: string[];\n excludePaths?: string[];\n\n static readonly SCHEMA: SchemaShape<ValidateTsInSrcConfig> = {\n mode: new FieldDef('string', VALIDATE_TS_MODES),\n allowedRootFiles: FieldDef.optional('string[]'),\n excludePaths: FieldDef.optional('string[]'),\n ...BASE_RULE_SCHEMA,\n };\n}\n"]}
@@ -33,6 +33,7 @@ const RULE_SCHEMAS = {
33
33
  'feature-branch-guard': rule_configs_1.FeatureBranchGuardConfig.SCHEMA,
34
34
  'no-file-import-cycles': rule_configs_1.NoFileImportCyclesConfig.SCHEMA,
35
35
  'runtime-architecture': rule_configs_1.RuntimeArchitectureConfig.SCHEMA,
36
+ 'nx-wiring': rule_configs_1.NxWiringConfig.SCHEMA,
36
37
  'no-js-files': rule_configs_1.NoJsFilesConfig.SCHEMA,
37
38
  'validate-ts-in-src': rule_configs_1.ValidateTsInSrcConfig.SCHEMA,
38
39
  };
@@ -1 +1 @@
1
- {"version":3,"file":"validate-config.js","sourceRoot":"","sources":["../../../../../packages/tooling/rules-config/src/validate-config.ts"],"names":[],"mappings":"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","sourcesContent":["import { FieldDef } from './field-def';\nimport { sectionForRule, isHookGuard } from './sections';\nimport {\n MaxMethodLinesConfig,\n MaxFileLinesConfig,\n RequireReturnTypeConfig,\n NoInlineTypeLiteralsConfig,\n NoAnyUnknownConfig,\n NoImplicitAnyConfig,\n PrismaValidateDtosConfig,\n PrismaConverterConfig,\n NoDestructureConfig,\n NoUnmanagedExceptionsConfig,\n CatchErrorPatternConfig,\n ThrowCauseRequiredConfig,\n AngularNoDirectApiInResolverConfig,\n NoSymbolDiTokensConfig,\n NoShellSubstitutionConfig,\n BranchCreationGuardConfig,\n PrCreationGuardConfig,\n MergeInProgressGuardConfig,\n PrMergeCleanupConfig,\n NoDirectMainUpdateConfig,\n FeatureBranchGuardConfig,\n NoFileImportCyclesConfig,\n RuntimeArchitectureConfig,\n NoJsFilesConfig,\n ValidateTsInSrcConfig,\n} from './rule-configs';\n\n// Thin lookup table — each entry delegates to the class's own SCHEMA.\n// No field lists here; all schemas live with their config class.\nconst RULE_SCHEMAS: Record<string, Record<string, FieldDef>> = {\n 'max-method-lines': MaxMethodLinesConfig.SCHEMA,\n 'max-file-lines': MaxFileLinesConfig.SCHEMA,\n 'require-return-type': RequireReturnTypeConfig.SCHEMA,\n 'no-inline-type-literals': NoInlineTypeLiteralsConfig.SCHEMA,\n 'no-any-unknown': NoAnyUnknownConfig.SCHEMA,\n 'no-implicit-any': NoImplicitAnyConfig.SCHEMA,\n 'prisma-validate-dtos': PrismaValidateDtosConfig.SCHEMA,\n 'prisma-converter': PrismaConverterConfig.SCHEMA,\n 'no-destructure': NoDestructureConfig.SCHEMA,\n 'no-unmanaged-exceptions': NoUnmanagedExceptionsConfig.SCHEMA,\n 'catch-error-pattern': CatchErrorPatternConfig.SCHEMA,\n 'throw-cause-required': ThrowCauseRequiredConfig.SCHEMA,\n 'angular-no-direct-api-in-resolver': AngularNoDirectApiInResolverConfig.SCHEMA,\n 'no-symbol-di-tokens': NoSymbolDiTokensConfig.SCHEMA,\n 'no-shell-substitution': NoShellSubstitutionConfig.SCHEMA,\n 'branch-creation-guard': BranchCreationGuardConfig.SCHEMA,\n 'pr-creation-guard': PrCreationGuardConfig.SCHEMA,\n 'merge-in-progress-guard': MergeInProgressGuardConfig.SCHEMA,\n 'pr-merge-cleanup': PrMergeCleanupConfig.SCHEMA,\n 'no-direct-main-update': NoDirectMainUpdateConfig.SCHEMA,\n 'feature-branch-guard': FeatureBranchGuardConfig.SCHEMA,\n 'no-file-import-cycles': NoFileImportCyclesConfig.SCHEMA,\n 'runtime-architecture': RuntimeArchitectureConfig.SCHEMA,\n 'no-js-files': NoJsFilesConfig.SCHEMA,\n 'validate-ts-in-src': ValidateTsInSrcConfig.SCHEMA,\n};\n\n// Every built-in rule name that has a typed schema (code rules + bash guards). The installer uses\n// this (with sectionForRule) to seed a fresh webpieces.config.json with every rule in its section.\nexport function allRuleNames(): readonly string[] {\n return Object.keys(RULE_SCHEMAS);\n}\n\nfunction valueHint(def: FieldDef, key?: string): string {\n // ignoreModifiedUntilEpoch is required on every rule; 0 keeps the rule active (epoch in the\n // past), a future unix epoch (seconds) temporarily disables it. Spell that out for the AI.\n if (key === 'ignoreModifiedUntilEpoch') return '0 (0 = active; future unix-epoch seconds = temporarily off)';\n return def.enumValues\n ? `\"${def.enumValues.join(' | ')}\"`\n : def.type === 'string[]' ? '[\"<string>\", ...]'\n : def.type === 'number' ? '<number>'\n : def.type === 'boolean' ? '<boolean>'\n : '\"<string>\"';\n}\n\nfunction missingRuleSnippet(ruleName: string, schema: Record<string, FieldDef>): string {\n // Only required fields go in the copy-paste entry. Optional fields (e.g. the\n // universal escape hatches ignoreRuleWhileOnBranch / ignoreModifiedUntilEpoch)\n // are listed separately so the snippet doesn't over-state what's mandatory.\n const fields = Object.keys(schema);\n const required = fields.filter(f => !schema[f].optional);\n const optional = fields.filter(f => schema[f].optional);\n\n const requiredLines = required.map(f => ` \"${f}\": ${valueHint(schema[f], f)}`);\n const section = sectionForRule(ruleName);\n let out =\n `[${ruleName}] Not configured in webpieces.config.json. Add this entry to the \"${section}\" section\\n` +\n `(choose values appropriate for your project):\\n\\n` +\n ` \"${ruleName}\": {\\n${requiredLines.join(',\\n')}\\n }`;\n\n if (optional.length > 0) {\n const optionalLines = optional.map(f => ` \"${f}\": ${valueHint(schema[f], f)}`);\n out +=\n `\\n\\nOptional fields you may add to this rule (omit if not needed):\\n` +\n `${optionalLines.join(',\\n')}`;\n }\n return out;\n}\n\n// webpieces-disable no-any-unknown -- rawRules values are opaque JSON; each field is validated individually\nexport function validateWebpiecesConfig(\n rawRules: Record<string, Record<string, unknown>>,\n): string[] {\n const errors: string[] = [];\n\n // Check field-level correctness for rules that are present\n for (const [ruleName, entry] of Object.entries(rawRules)) {\n const schema = RULE_SCHEMAS[ruleName];\n if (!schema) continue; // custom/unknown rule — no schema to validate against\n for (const [key, value] of Object.entries(entry)) {\n const fieldDef = schema[key];\n if (!fieldDef) {\n errors.push(`[${ruleName}] Unknown field \"${key}\". Valid fields: [${Object.keys(schema).join(', ')}]`);\n continue;\n }\n if (fieldDef.type === 'string[]') {\n if (!Array.isArray(value) || !value.every(v => typeof v === 'string'))\n errors.push(`[${ruleName}] \"${key}\" must be string[], got ${typeof value}.`);\n } else if (typeof value !== fieldDef.type) {\n errors.push(`[${ruleName}] \"${key}\" must be ${fieldDef.type}, got ${typeof value}.`);\n } else if (fieldDef.enumValues && !fieldDef.enumValues.includes(value as string)) {\n errors.push(`[${ruleName}] \"${key}\" = \"${value}\" is not valid. Must be one of: ${fieldDef.enumValues.join(', ')}.`);\n }\n }\n // Required fields must actually be present. Until now the loop above only checked\n // fields that WERE present, so an entry like `{}` (or one missing `mode` /\n // `ignoreModifiedUntilEpoch`) slipped through. Every non-optional schema field is mandatory.\n for (const [key, fieldDef] of Object.entries(schema)) {\n if (!fieldDef.optional && !(key in entry)) {\n errors.push(`[${ruleName}] Missing required field \"${key}\". Add ${key}: ${valueHint(fieldDef, key)}.`);\n }\n }\n }\n\n // Every built-in rule must be explicitly configured — no silent defaults.\n // When a new rule is added to the framework, this check surfaces it immediately\n // with a ready-to-copy snippet so AI can configure it in one pass.\n for (const [ruleName, schema] of Object.entries(RULE_SCHEMAS)) {\n if (!(ruleName in rawRules)) {\n errors.push(missingRuleSnippet(ruleName, schema));\n }\n }\n\n return errors;\n}\n\nconst PR_GATE_MODES = ['ON', 'OFF'] as const;\n\n// Copy-paste example for the top-level `pr-gate` block (sibling of `rules`). Kept inline rather\n// than imported from pr-gate-config.ts to avoid a load-config ↔ pr-gate-config import cycle.\nfunction prGateExample(): string {\n return (\n ` \"pr-gate\": {\\n` +\n ` \"mode\": \"ON\",\\n` +\n ` \"buildCommand\": \"<command CI runs to validate a PR, e.g. pnpm nx affected --target=ci --base=$(git merge-base origin/main HEAD)>\",\\n` +\n ` \"gates\": [\\n` +\n ` { \"name\": \"API Changed\", \"patterns\": [\"libraries/apis/**\", \"**/*Api.ts\"], \"warningColor\": \"yellow\" }\\n` +\n ` ]\\n` +\n ` }`\n );\n}\n\n// webpieces-disable no-any-unknown -- one gate entry from opaque consumer JSON, validated field-by-field\nfunction validateGate(gate: unknown, index: number): string[] {\n if (typeof gate !== 'object' || gate === null) {\n return [`[pr-gate] gates[${index}] must be an object { name, patterns, warningColor, disabled? }.`];\n }\n // webpieces-disable no-any-unknown -- narrowing one opaque gate object from consumer JSON\n const g = gate as Record<string, unknown>;\n const errors: string[] = [];\n if (typeof g['name'] !== 'string') errors.push(`[pr-gate] gates[${index}].name must be a string.`);\n if (!Array.isArray(g['patterns']) || !g['patterns'].every(p => typeof p === 'string'))\n errors.push(`[pr-gate] gates[${index}].patterns must be string[].`);\n if (g['warningColor'] === undefined)\n errors.push(`[pr-gate] gates[${index}].warningColor is required — set it to \"yellow\" or \"red\" (green is implicit when nothing matches).`);\n else if (g['warningColor'] !== 'yellow' && g['warningColor'] !== 'red')\n errors.push(`[pr-gate] gates[${index}].warningColor must be \"yellow\" or \"red\" (green is implicit when nothing matches).`);\n if (g['disabled'] !== undefined && typeof g['disabled'] !== 'boolean')\n errors.push(`[pr-gate] gates[${index}].disabled must be a boolean (example/inactive gate kept in the file).`);\n return errors;\n}\n\n/**\n * Validate the top-level `pr-gate` section. It is REQUIRED (a client that opts out sets mode \"OFF\").\n * `buildCommand` is required unless mode is \"OFF\". Returns human-readable, copy-paste-friendly errors\n * — never throws. The pr-gate block lives outside the FieldDef-driven `rules` schema because its\n * nested `gates` array can't be expressed there, so it gets its own structural validation here.\n */\n// webpieces-disable no-any-unknown -- `section` is opaque consumer JSON until narrowed below\nexport function validatePrGateSection(section: unknown): string[] {\n if (section === undefined || section === null) {\n return [\n `[pr-gate] Not configured in webpieces.config.json. Add this block under the \"commands\" ` +\n `section (set \"mode\": \"OFF\" to opt out):\\n\\n${prGateExample()}`,\n ];\n }\n if (typeof section !== 'object' || Array.isArray(section)) {\n return [`[pr-gate] Must be an object. Example:\\n\\n${prGateExample()}`];\n }\n // webpieces-disable no-any-unknown -- narrowing the opaque pr-gate section from consumer JSON\n const s = section as Record<string, unknown>;\n const errors: string[] = [];\n\n if (!('mode' in s)) {\n errors.push(`[pr-gate] Missing required field \"mode\". Must be one of: ${PR_GATE_MODES.join(', ')}.`);\n } else if (typeof s['mode'] !== 'string' || !PR_GATE_MODES.includes(s['mode'] as typeof PR_GATE_MODES[number])) {\n errors.push(`[pr-gate] \"mode\" = \"${String(s['mode'])}\" is not valid. Must be one of: ${PR_GATE_MODES.join(', ')}.`);\n }\n\n // buildCommand is required whenever the gate is active (mode !== OFF).\n if (s['mode'] !== 'OFF') {\n const cmd = s['buildCommand'];\n if (typeof cmd !== 'string' || cmd.trim() === '') {\n errors.push(\n `[pr-gate] Missing required field \"buildCommand\" — the command CI runs to validate a PR. ` +\n `Add e.g. \"buildCommand\": \"pnpm nx affected --target=ci --base=$(git merge-base origin/main HEAD)\".`,\n );\n }\n }\n\n if ('gates' in s) {\n const gates = s['gates'];\n if (!Array.isArray(gates)) {\n errors.push(`[pr-gate] \"gates\" must be an array of { name, patterns, warningColor, disabled? }.`);\n } else {\n for (let i = 0; i < gates.length; i += 1) {\n errors.push(...validateGate(gates[i], i));\n }\n }\n }\n\n return errors;\n}\n\n/**\n * Enforce that each built-in lives in its correct section: code rules under `rules`, bash guards\n * under `hookGuards`. A guard left in `rules` (or a rule placed in `hookGuards`) is reported with a\n * \"move it\" message so the split stays clean. Unknown/custom names are ignored (they may be custom\n * rules from rulesDir). Presence (\"every built-in must be configured\") is checked separately by\n * validateWebpiecesConfig against the merged map.\n */\n// webpieces-disable no-any-unknown -- section maps are opaque consumer JSON\nexport function validateSectionPlacement(\n rulesSection: Record<string, Record<string, unknown>>,\n hookGuardsSection: Record<string, Record<string, unknown>>,\n): string[] {\n const errors: string[] = [];\n for (const name of Object.keys(rulesSection)) {\n if (isHookGuard(name)) {\n errors.push(\n `[${name}] is a hook guard and belongs in the \"hookGuards\" section, not \"rules\". ` +\n `Move it (or run \\`wp-setup-ai-hooks --sync\\` to migrate automatically).`,\n );\n }\n }\n for (const name of Object.keys(hookGuardsSection)) {\n // Only flag KNOWN code rules misplaced into hookGuards; unknown names may be custom rules.\n if (!isHookGuard(name) && RULE_SCHEMAS[name]) {\n errors.push(\n `[${name}] is a code rule and belongs in the \"rules\" section, not \"hookGuards\". ` +\n `Move it (or run \\`wp-setup-ai-hooks --sync\\` to migrate automatically).`,\n );\n }\n }\n return errors;\n}\n\n/**\n * Validate the `commands` section: its `pr-gate` block (delegated to validatePrGateSection) plus the\n * optional command-string fields. Also surfaces a migration error if a DEPRECATED top-level `pr-gate`\n * block is still present, telling the consumer to move it under `commands`.\n */\n// webpieces-disable no-any-unknown -- `commands`/`legacyPrGate` are opaque consumer JSON\nexport function validateCommandsSection(commands: unknown, legacyPrGate: unknown): string[] {\n const errors: string[] = [];\n\n if (legacyPrGate !== undefined) {\n errors.push(\n `[pr-gate] The top-level \"pr-gate\" block is deprecated. Move it under the \"commands\" ` +\n `section as commands[\"pr-gate\"] (run \\`wp-setup-ai-hooks --sync\\` to migrate automatically).`,\n );\n }\n\n if (commands !== undefined && (typeof commands !== 'object' || commands === null || Array.isArray(commands))) {\n errors.push(`[commands] Must be an object { \"pr-gate\": {...}, \"upsertPr\": \"...\", \"mergeComplete\": \"...\" }.`);\n return errors;\n }\n\n // webpieces-disable no-any-unknown -- narrowing the opaque commands section from consumer JSON\n const c = (commands ?? {}) as Record<string, unknown>;\n\n // pr-gate is required (set mode OFF to opt out). Prefer commands[\"pr-gate\"]; fall back to the\n // legacy top-level block so an un-migrated file still validates its gate config.\n errors.push(...validatePrGateSection(c['pr-gate'] ?? legacyPrGate));\n\n for (const field of ['upsertPr', 'mergeComplete']) {\n if (field in c && typeof c[field] !== 'string') {\n errors.push(`[commands] \"${field}\" must be a string (the gated command to run).`);\n }\n }\n\n return errors;\n}\n"]}
1
+ {"version":3,"file":"validate-config.js","sourceRoot":"","sources":["../../../../../packages/tooling/rules-config/src/validate-config.ts"],"names":[],"mappings":"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","sourcesContent":["import { FieldDef } from './field-def';\nimport { sectionForRule, isHookGuard } from './sections';\nimport {\n MaxMethodLinesConfig,\n MaxFileLinesConfig,\n RequireReturnTypeConfig,\n NoInlineTypeLiteralsConfig,\n NoAnyUnknownConfig,\n NoImplicitAnyConfig,\n PrismaValidateDtosConfig,\n PrismaConverterConfig,\n NoDestructureConfig,\n NoUnmanagedExceptionsConfig,\n CatchErrorPatternConfig,\n ThrowCauseRequiredConfig,\n AngularNoDirectApiInResolverConfig,\n NoSymbolDiTokensConfig,\n NoShellSubstitutionConfig,\n BranchCreationGuardConfig,\n PrCreationGuardConfig,\n MergeInProgressGuardConfig,\n PrMergeCleanupConfig,\n NoDirectMainUpdateConfig,\n FeatureBranchGuardConfig,\n NoFileImportCyclesConfig,\n RuntimeArchitectureConfig,\n NxWiringConfig,\n NoJsFilesConfig,\n ValidateTsInSrcConfig,\n} from './rule-configs';\n\n// Thin lookup table — each entry delegates to the class's own SCHEMA.\n// No field lists here; all schemas live with their config class.\nconst RULE_SCHEMAS: Record<string, Record<string, FieldDef>> = {\n 'max-method-lines': MaxMethodLinesConfig.SCHEMA,\n 'max-file-lines': MaxFileLinesConfig.SCHEMA,\n 'require-return-type': RequireReturnTypeConfig.SCHEMA,\n 'no-inline-type-literals': NoInlineTypeLiteralsConfig.SCHEMA,\n 'no-any-unknown': NoAnyUnknownConfig.SCHEMA,\n 'no-implicit-any': NoImplicitAnyConfig.SCHEMA,\n 'prisma-validate-dtos': PrismaValidateDtosConfig.SCHEMA,\n 'prisma-converter': PrismaConverterConfig.SCHEMA,\n 'no-destructure': NoDestructureConfig.SCHEMA,\n 'no-unmanaged-exceptions': NoUnmanagedExceptionsConfig.SCHEMA,\n 'catch-error-pattern': CatchErrorPatternConfig.SCHEMA,\n 'throw-cause-required': ThrowCauseRequiredConfig.SCHEMA,\n 'angular-no-direct-api-in-resolver': AngularNoDirectApiInResolverConfig.SCHEMA,\n 'no-symbol-di-tokens': NoSymbolDiTokensConfig.SCHEMA,\n 'no-shell-substitution': NoShellSubstitutionConfig.SCHEMA,\n 'branch-creation-guard': BranchCreationGuardConfig.SCHEMA,\n 'pr-creation-guard': PrCreationGuardConfig.SCHEMA,\n 'merge-in-progress-guard': MergeInProgressGuardConfig.SCHEMA,\n 'pr-merge-cleanup': PrMergeCleanupConfig.SCHEMA,\n 'no-direct-main-update': NoDirectMainUpdateConfig.SCHEMA,\n 'feature-branch-guard': FeatureBranchGuardConfig.SCHEMA,\n 'no-file-import-cycles': NoFileImportCyclesConfig.SCHEMA,\n 'runtime-architecture': RuntimeArchitectureConfig.SCHEMA,\n 'nx-wiring': NxWiringConfig.SCHEMA,\n 'no-js-files': NoJsFilesConfig.SCHEMA,\n 'validate-ts-in-src': ValidateTsInSrcConfig.SCHEMA,\n};\n\n// Every built-in rule name that has a typed schema (code rules + bash guards). The installer uses\n// this (with sectionForRule) to seed a fresh webpieces.config.json with every rule in its section.\nexport function allRuleNames(): readonly string[] {\n return Object.keys(RULE_SCHEMAS);\n}\n\nfunction valueHint(def: FieldDef, key?: string): string {\n // ignoreModifiedUntilEpoch is required on every rule; 0 keeps the rule active (epoch in the\n // past), a future unix epoch (seconds) temporarily disables it. Spell that out for the AI.\n if (key === 'ignoreModifiedUntilEpoch') return '0 (0 = active; future unix-epoch seconds = temporarily off)';\n return def.enumValues\n ? `\"${def.enumValues.join(' | ')}\"`\n : def.type === 'string[]' ? '[\"<string>\", ...]'\n : def.type === 'number' ? '<number>'\n : def.type === 'boolean' ? '<boolean>'\n : '\"<string>\"';\n}\n\nfunction missingRuleSnippet(ruleName: string, schema: Record<string, FieldDef>): string {\n // Only required fields go in the copy-paste entry. Optional fields (e.g. the\n // universal escape hatches ignoreRuleWhileOnBranch / ignoreModifiedUntilEpoch)\n // are listed separately so the snippet doesn't over-state what's mandatory.\n const fields = Object.keys(schema);\n const required = fields.filter(f => !schema[f].optional);\n const optional = fields.filter(f => schema[f].optional);\n\n const requiredLines = required.map(f => ` \"${f}\": ${valueHint(schema[f], f)}`);\n const section = sectionForRule(ruleName);\n let out =\n `[${ruleName}] Not configured in webpieces.config.json. Add this entry to the \"${section}\" section\\n` +\n `(choose values appropriate for your project):\\n\\n` +\n ` \"${ruleName}\": {\\n${requiredLines.join(',\\n')}\\n }`;\n\n if (optional.length > 0) {\n const optionalLines = optional.map(f => ` \"${f}\": ${valueHint(schema[f], f)}`);\n out +=\n `\\n\\nOptional fields you may add to this rule (omit if not needed):\\n` +\n `${optionalLines.join(',\\n')}`;\n }\n return out;\n}\n\n// webpieces-disable no-any-unknown -- rawRules values are opaque JSON; each field is validated individually\nexport function validateWebpiecesConfig(\n rawRules: Record<string, Record<string, unknown>>,\n): string[] {\n const errors: string[] = [];\n\n // Check field-level correctness for rules that are present\n for (const [ruleName, entry] of Object.entries(rawRules)) {\n const schema = RULE_SCHEMAS[ruleName];\n if (!schema) continue; // custom/unknown rule — no schema to validate against\n for (const [key, value] of Object.entries(entry)) {\n const fieldDef = schema[key];\n if (!fieldDef) {\n errors.push(`[${ruleName}] Unknown field \"${key}\". Valid fields: [${Object.keys(schema).join(', ')}]`);\n continue;\n }\n if (fieldDef.type === 'string[]') {\n if (!Array.isArray(value) || !value.every(v => typeof v === 'string'))\n errors.push(`[${ruleName}] \"${key}\" must be string[], got ${typeof value}.`);\n } else if (typeof value !== fieldDef.type) {\n errors.push(`[${ruleName}] \"${key}\" must be ${fieldDef.type}, got ${typeof value}.`);\n } else if (fieldDef.enumValues && !fieldDef.enumValues.includes(value as string)) {\n errors.push(`[${ruleName}] \"${key}\" = \"${value}\" is not valid. Must be one of: ${fieldDef.enumValues.join(', ')}.`);\n }\n }\n // Required fields must actually be present. Until now the loop above only checked\n // fields that WERE present, so an entry like `{}` (or one missing `mode` /\n // `ignoreModifiedUntilEpoch`) slipped through. Every non-optional schema field is mandatory.\n for (const [key, fieldDef] of Object.entries(schema)) {\n if (!fieldDef.optional && !(key in entry)) {\n errors.push(`[${ruleName}] Missing required field \"${key}\". Add ${key}: ${valueHint(fieldDef, key)}.`);\n }\n }\n }\n\n // Every built-in rule must be explicitly configured — no silent defaults.\n // When a new rule is added to the framework, this check surfaces it immediately\n // with a ready-to-copy snippet so AI can configure it in one pass.\n for (const [ruleName, schema] of Object.entries(RULE_SCHEMAS)) {\n if (!(ruleName in rawRules)) {\n errors.push(missingRuleSnippet(ruleName, schema));\n }\n }\n\n return errors;\n}\n\nconst PR_GATE_MODES = ['ON', 'OFF'] as const;\n\n// Copy-paste example for the top-level `pr-gate` block (sibling of `rules`). Kept inline rather\n// than imported from pr-gate-config.ts to avoid a load-config ↔ pr-gate-config import cycle.\nfunction prGateExample(): string {\n return (\n ` \"pr-gate\": {\\n` +\n ` \"mode\": \"ON\",\\n` +\n ` \"buildCommand\": \"<command CI runs to validate a PR, e.g. pnpm nx affected --target=ci --base=$(git merge-base origin/main HEAD)>\",\\n` +\n ` \"gates\": [\\n` +\n ` { \"name\": \"API Changed\", \"patterns\": [\"libraries/apis/**\", \"**/*Api.ts\"], \"warningColor\": \"yellow\" }\\n` +\n ` ]\\n` +\n ` }`\n );\n}\n\n// webpieces-disable no-any-unknown -- one gate entry from opaque consumer JSON, validated field-by-field\nfunction validateGate(gate: unknown, index: number): string[] {\n if (typeof gate !== 'object' || gate === null) {\n return [`[pr-gate] gates[${index}] must be an object { name, patterns, warningColor, disabled? }.`];\n }\n // webpieces-disable no-any-unknown -- narrowing one opaque gate object from consumer JSON\n const g = gate as Record<string, unknown>;\n const errors: string[] = [];\n if (typeof g['name'] !== 'string') errors.push(`[pr-gate] gates[${index}].name must be a string.`);\n if (!Array.isArray(g['patterns']) || !g['patterns'].every(p => typeof p === 'string'))\n errors.push(`[pr-gate] gates[${index}].patterns must be string[].`);\n if (g['warningColor'] === undefined)\n errors.push(`[pr-gate] gates[${index}].warningColor is required — set it to \"yellow\" or \"red\" (green is implicit when nothing matches).`);\n else if (g['warningColor'] !== 'yellow' && g['warningColor'] !== 'red')\n errors.push(`[pr-gate] gates[${index}].warningColor must be \"yellow\" or \"red\" (green is implicit when nothing matches).`);\n if (g['disabled'] !== undefined && typeof g['disabled'] !== 'boolean')\n errors.push(`[pr-gate] gates[${index}].disabled must be a boolean (example/inactive gate kept in the file).`);\n return errors;\n}\n\n/**\n * Validate the top-level `pr-gate` section. It is REQUIRED (a client that opts out sets mode \"OFF\").\n * `buildCommand` is required unless mode is \"OFF\". Returns human-readable, copy-paste-friendly errors\n * — never throws. The pr-gate block lives outside the FieldDef-driven `rules` schema because its\n * nested `gates` array can't be expressed there, so it gets its own structural validation here.\n */\n// webpieces-disable no-any-unknown -- `section` is opaque consumer JSON until narrowed below\nexport function validatePrGateSection(section: unknown): string[] {\n if (section === undefined || section === null) {\n return [\n `[pr-gate] Not configured in webpieces.config.json. Add this block under the \"commands\" ` +\n `section (set \"mode\": \"OFF\" to opt out):\\n\\n${prGateExample()}`,\n ];\n }\n if (typeof section !== 'object' || Array.isArray(section)) {\n return [`[pr-gate] Must be an object. Example:\\n\\n${prGateExample()}`];\n }\n // webpieces-disable no-any-unknown -- narrowing the opaque pr-gate section from consumer JSON\n const s = section as Record<string, unknown>;\n const errors: string[] = [];\n\n if (!('mode' in s)) {\n errors.push(`[pr-gate] Missing required field \"mode\". Must be one of: ${PR_GATE_MODES.join(', ')}.`);\n } else if (typeof s['mode'] !== 'string' || !PR_GATE_MODES.includes(s['mode'] as typeof PR_GATE_MODES[number])) {\n errors.push(`[pr-gate] \"mode\" = \"${String(s['mode'])}\" is not valid. Must be one of: ${PR_GATE_MODES.join(', ')}.`);\n }\n\n // buildCommand is required whenever the gate is active (mode !== OFF).\n if (s['mode'] !== 'OFF') {\n const cmd = s['buildCommand'];\n if (typeof cmd !== 'string' || cmd.trim() === '') {\n errors.push(\n `[pr-gate] Missing required field \"buildCommand\" — the command CI runs to validate a PR. ` +\n `Add e.g. \"buildCommand\": \"pnpm nx affected --target=ci --base=$(git merge-base origin/main HEAD)\".`,\n );\n }\n }\n\n if ('gates' in s) {\n const gates = s['gates'];\n if (!Array.isArray(gates)) {\n errors.push(`[pr-gate] \"gates\" must be an array of { name, patterns, warningColor, disabled? }.`);\n } else {\n for (let i = 0; i < gates.length; i += 1) {\n errors.push(...validateGate(gates[i], i));\n }\n }\n }\n\n return errors;\n}\n\n/**\n * Enforce that each built-in lives in its correct section: code rules under `rules`, bash guards\n * under `hookGuards`. A guard left in `rules` (or a rule placed in `hookGuards`) is reported with a\n * \"move it\" message so the split stays clean. Unknown/custom names are ignored (they may be custom\n * rules from rulesDir). Presence (\"every built-in must be configured\") is checked separately by\n * validateWebpiecesConfig against the merged map.\n */\n// webpieces-disable no-any-unknown -- section maps are opaque consumer JSON\nexport function validateSectionPlacement(\n rulesSection: Record<string, Record<string, unknown>>,\n hookGuardsSection: Record<string, Record<string, unknown>>,\n): string[] {\n const errors: string[] = [];\n for (const name of Object.keys(rulesSection)) {\n if (isHookGuard(name)) {\n errors.push(\n `[${name}] is a hook guard and belongs in the \"hookGuards\" section, not \"rules\". ` +\n `Move it (or run \\`wp-setup-ai-hooks --sync\\` to migrate automatically).`,\n );\n }\n }\n for (const name of Object.keys(hookGuardsSection)) {\n // Only flag KNOWN code rules misplaced into hookGuards; unknown names may be custom rules.\n if (!isHookGuard(name) && RULE_SCHEMAS[name]) {\n errors.push(\n `[${name}] is a code rule and belongs in the \"rules\" section, not \"hookGuards\". ` +\n `Move it (or run \\`wp-setup-ai-hooks --sync\\` to migrate automatically).`,\n );\n }\n }\n return errors;\n}\n\n/**\n * Validate the `commands` section: its `pr-gate` block (delegated to validatePrGateSection) plus the\n * optional command-string fields. Also surfaces a migration error if a DEPRECATED top-level `pr-gate`\n * block is still present, telling the consumer to move it under `commands`.\n */\n// webpieces-disable no-any-unknown -- `commands`/`legacyPrGate` are opaque consumer JSON\nexport function validateCommandsSection(commands: unknown, legacyPrGate: unknown): string[] {\n const errors: string[] = [];\n\n if (legacyPrGate !== undefined) {\n errors.push(\n `[pr-gate] The top-level \"pr-gate\" block is deprecated. Move it under the \"commands\" ` +\n `section as commands[\"pr-gate\"] (run \\`wp-setup-ai-hooks --sync\\` to migrate automatically).`,\n );\n }\n\n if (commands !== undefined && (typeof commands !== 'object' || commands === null || Array.isArray(commands))) {\n errors.push(`[commands] Must be an object { \"pr-gate\": {...}, \"upsertPr\": \"...\", \"mergeComplete\": \"...\" }.`);\n return errors;\n }\n\n // webpieces-disable no-any-unknown -- narrowing the opaque commands section from consumer JSON\n const c = (commands ?? {}) as Record<string, unknown>;\n\n // pr-gate is required (set mode OFF to opt out). Prefer commands[\"pr-gate\"]; fall back to the\n // legacy top-level block so an un-migrated file still validates its gate config.\n errors.push(...validatePrGateSection(c['pr-gate'] ?? legacyPrGate));\n\n for (const field of ['upsertPr', 'mergeComplete']) {\n if (field in c && typeof c[field] !== 'string') {\n errors.push(`[commands] \"${field}\" must be a string (the gated command to run).`);\n }\n }\n\n return errors;\n}\n"]}