@gobing-ai/ts-rule-engine 0.4.1 → 0.4.3

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.
@@ -1 +1 @@
1
- {"version":3,"file":"ripgrep-evaluator.d.ts","sourceRoot":"","sources":["../../src/evaluators/ripgrep-evaluator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAClF,OAAO,EACH,KAAK,cAAc,EAEnB,KAAK,WAAW,EAChB,KAAK,oBAAoB,EACzB,KAAK,aAAa,EACrB,MAAM,UAAU,CAAC;AAGlB;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,gBAAiB,YAAW,aAAa;IAClD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkB;gBAE/B,QAAQ,GAAE,eAA2C;IAIjE,oFAAoF;IAC9E,QAAQ,CAAC,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,oBAAoB,CAAC;CA2B5F;AA+ED;;;;;;;;;;;GAWG;AACH,wBAAgB,0BAA0B,CACtC,OAAO,EAAE,MAAM,GAChB;IAAE,UAAU,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,UAAU,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAK/D"}
1
+ {"version":3,"file":"ripgrep-evaluator.d.ts","sourceRoot":"","sources":["../../src/evaluators/ripgrep-evaluator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAClF,OAAO,EACH,KAAK,cAAc,EAEnB,KAAK,WAAW,EAChB,KAAK,oBAAoB,EACzB,KAAK,aAAa,EACrB,MAAM,UAAU,CAAC;AAGlB;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,gBAAiB,YAAW,aAAa;IAClD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkB;gBAE/B,QAAQ,GAAE,eAA2C;IAIjE,oFAAoF;IAC9E,QAAQ,CAAC,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,oBAAoB,CAAC;CA8B5F;AAmFD;;;;;;;;;;;GAWG;AACH,wBAAgB,0BAA0B,CACtC,OAAO,EAAE,MAAM,GAChB;IAAE,UAAU,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,UAAU,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAK/D"}
@@ -44,10 +44,14 @@ export class RipgrepEvaluator {
44
44
  rejectOnError: false,
45
45
  label: 'rg',
46
46
  });
47
- // ripgrep exits 0 with matches, 1 when none, 2 on error. Treat 2 (or any non-0/1
48
- // with stderr) as a hard failure so a broken pattern or missing `rg` fails loud.
47
+ // ripgrep exits 0 with matches, 1 when none, 2 on error. A scoped rule whose
48
+ // positive globs match no files also exits 2 with "No files were searched";
49
+ // that means "this rule is not applicable in this repo", not a broken
50
+ // evaluator. Keep all other exit-2 cases loud.
49
51
  if (result.exitCode !== 0 && result.exitCode !== 1) {
50
52
  const detail = result.stderr.trim();
53
+ if (isNoFilesSearched(detail))
54
+ return { findings: [], fixes: [] };
51
55
  throw new Error(`rg failed (exit ${result.exitCode})${detail.length > 0 ? `: ${detail}` : ''}`);
52
56
  }
53
57
  return mode === 'require'
@@ -55,6 +59,9 @@ export class RipgrepEvaluator {
55
59
  : { findings: forbidFindings(rule, pattern, result.stdout), fixes: [] };
56
60
  }
57
61
  }
62
+ function isNoFilesSearched(stderr) {
63
+ return stderr.includes('No files were searched');
64
+ }
58
65
  /** Build the ripgrep argument list for the given mode and scope. */
59
66
  function buildArgs(pattern, mode, multiline, include, exclude) {
60
67
  const args = [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gobing-ai/ts-rule-engine",
3
- "version": "0.4.1",
3
+ "version": "0.4.3",
4
4
  "description": "@gobing-ai/ts-rule-engine — Constraint rule schemas, loading, evaluation, and result formatting.",
5
5
  "keywords": [
6
6
  "typescript",
@@ -49,10 +49,10 @@
49
49
  "release": "echo 'Manual publish is disabled. Releases go through GitHub Actions via Trusted Publishing — push a tag: git tag @gobing-ai/ts-rule-engine-v<version> && git push --tags' && exit 1"
50
50
  },
51
51
  "dependencies": {
52
- "@gobing-ai/ts-ai-runner": "^0.4.1",
53
- "@gobing-ai/ts-infra": "^0.4.1",
54
- "@gobing-ai/ts-runtime": "^0.4.1",
55
- "@gobing-ai/ts-db": "^0.4.1",
52
+ "@gobing-ai/ts-ai-runner": "^0.4.3",
53
+ "@gobing-ai/ts-infra": "^0.4.3",
54
+ "@gobing-ai/ts-runtime": "^0.4.3",
55
+ "@gobing-ai/ts-db": "^0.4.3",
56
56
  "yaml": "^2.7.0",
57
57
  "zod": "^4.1.0"
58
58
  },
@@ -55,10 +55,13 @@ export class RipgrepEvaluator implements RuleEvaluator {
55
55
  label: 'rg',
56
56
  });
57
57
 
58
- // ripgrep exits 0 with matches, 1 when none, 2 on error. Treat 2 (or any non-0/1
59
- // with stderr) as a hard failure so a broken pattern or missing `rg` fails loud.
58
+ // ripgrep exits 0 with matches, 1 when none, 2 on error. A scoped rule whose
59
+ // positive globs match no files also exits 2 with "No files were searched";
60
+ // that means "this rule is not applicable in this repo", not a broken
61
+ // evaluator. Keep all other exit-2 cases loud.
60
62
  if (result.exitCode !== 0 && result.exitCode !== 1) {
61
63
  const detail = result.stderr.trim();
64
+ if (isNoFilesSearched(detail)) return { findings: [], fixes: [] };
62
65
  throw new Error(`rg failed (exit ${result.exitCode})${detail.length > 0 ? `: ${detail}` : ''}`);
63
66
  }
64
67
 
@@ -68,6 +71,10 @@ export class RipgrepEvaluator implements RuleEvaluator {
68
71
  }
69
72
  }
70
73
 
74
+ function isNoFilesSearched(stderr: string): boolean {
75
+ return stderr.includes('No files were searched');
76
+ }
77
+
71
78
  /** Build the ripgrep argument list for the given mode and scope. */
72
79
  function buildArgs(pattern: string, mode: string, multiline: boolean, include: string[], exclude: string[]): string[] {
73
80
  const args: string[] = [];