@webpieces/ai-hook-rules 0.0.1 → 0.2.114

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.
Files changed (99) hide show
  1. package/package.json +4 -3
  2. package/src/adapters/claude-code-hook.d.ts +1 -0
  3. package/src/adapters/claude-code-hook.js +112 -0
  4. package/src/adapters/claude-code-hook.js.map +1 -0
  5. package/src/adapters/openclaw-plugin.d.ts +14 -0
  6. package/src/adapters/openclaw-plugin.js +73 -0
  7. package/src/adapters/openclaw-plugin.js.map +1 -0
  8. package/src/core/build-context.d.ts +8 -0
  9. package/src/core/build-context.js +62 -0
  10. package/src/core/build-context.js.map +1 -0
  11. package/src/core/configs/default.d.ts +2 -0
  12. package/src/core/configs/{default.ts → default.js} +6 -3
  13. package/src/core/configs/default.js.map +1 -0
  14. package/src/core/disable-directives.d.ts +9 -0
  15. package/src/core/disable-directives.js +92 -0
  16. package/src/core/disable-directives.js.map +1 -0
  17. package/src/core/instruct-ai-writer.d.ts +1 -0
  18. package/src/core/instruct-ai-writer.js +18 -0
  19. package/src/core/instruct-ai-writer.js.map +1 -0
  20. package/src/core/load-config.d.ts +1 -0
  21. package/src/core/load-config.js +10 -0
  22. package/src/core/load-config.js.map +1 -0
  23. package/src/core/load-rules.d.ts +3 -0
  24. package/src/core/{load-rules.ts → load-rules.js} +33 -32
  25. package/src/core/load-rules.js.map +1 -0
  26. package/src/core/rejection-log.d.ts +2 -0
  27. package/src/core/{rejection-log.ts → rejection-log.js} +34 -51
  28. package/src/core/rejection-log.js.map +1 -0
  29. package/src/core/report.d.ts +2 -0
  30. package/src/core/{report.ts → report.js} +7 -8
  31. package/src/core/report.js.map +1 -0
  32. package/src/core/rules/catch-error-pattern.d.ts +3 -0
  33. package/src/core/rules/{catch-error-pattern.ts → catch-error-pattern.js} +25 -54
  34. package/src/core/rules/catch-error-pattern.js.map +1 -0
  35. package/src/core/rules/file-location.d.ts +3 -0
  36. package/src/core/rules/{file-location.ts → file-location.js} +29 -43
  37. package/src/core/rules/file-location.js.map +1 -0
  38. package/src/core/rules/index.d.ts +1 -0
  39. package/src/core/rules/{index.ts → index.js} +5 -1
  40. package/src/core/rules/index.js.map +1 -0
  41. package/src/core/rules/max-file-lines.d.ts +3 -0
  42. package/src/core/rules/{max-file-lines.ts → max-file-lines.js} +17 -23
  43. package/src/core/rules/max-file-lines.js.map +1 -0
  44. package/src/core/rules/no-any-unknown.d.ts +3 -0
  45. package/src/core/rules/no-any-unknown.js +30 -0
  46. package/src/core/rules/no-any-unknown.js.map +1 -0
  47. package/src/core/rules/no-destructure.d.ts +3 -0
  48. package/src/core/rules/{no-destructure.ts → no-destructure.js} +13 -17
  49. package/src/core/rules/no-destructure.js.map +1 -0
  50. package/src/core/rules/no-implicit-any.d.ts +3 -0
  51. package/src/core/rules/{no-implicit-any.ts → no-implicit-any.js} +32 -30
  52. package/src/core/rules/no-implicit-any.js.map +1 -0
  53. package/src/core/rules/no-shell-substitution.d.ts +3 -0
  54. package/src/core/rules/no-shell-substitution.js +54 -0
  55. package/src/core/rules/no-shell-substitution.js.map +1 -0
  56. package/src/core/rules/no-unmanaged-exceptions.d.ts +3 -0
  57. package/src/core/rules/{no-unmanaged-exceptions.ts → no-unmanaged-exceptions.js} +21 -24
  58. package/src/core/rules/no-unmanaged-exceptions.js.map +1 -0
  59. package/src/core/rules/require-return-type.d.ts +3 -0
  60. package/src/core/rules/{require-return-type.ts → require-return-type.js} +21 -28
  61. package/src/core/rules/require-return-type.js.map +1 -0
  62. package/src/core/runner.d.ts +3 -0
  63. package/src/core/runner.js +181 -0
  64. package/src/core/runner.js.map +1 -0
  65. package/src/core/strip-ts-noise.d.ts +1 -0
  66. package/src/core/strip-ts-noise.js +178 -0
  67. package/src/core/strip-ts-noise.js.map +1 -0
  68. package/src/core/to-error.d.ts +5 -0
  69. package/src/core/{to-error.ts → to-error.js} +7 -4
  70. package/src/core/to-error.js.map +1 -0
  71. package/src/core/types.d.ts +93 -0
  72. package/src/core/types.js +93 -0
  73. package/src/core/types.js.map +1 -0
  74. package/src/index.d.ts +5 -0
  75. package/src/index.js +25 -0
  76. package/src/index.js.map +1 -0
  77. package/LICENSE +0 -373
  78. package/src/adapters/claude-code-hook.ts +0 -117
  79. package/src/adapters/openclaw-plugin.ts +0 -88
  80. package/src/core/__tests__/disable-directives.test.ts +0 -114
  81. package/src/core/__tests__/rules/file-location.test.ts +0 -90
  82. package/src/core/__tests__/rules/max-file-lines.test.ts +0 -53
  83. package/src/core/__tests__/rules/no-any.test.ts +0 -68
  84. package/src/core/__tests__/rules/no-destructure.test.ts +0 -50
  85. package/src/core/__tests__/rules/no-shell-substitution.test.ts +0 -118
  86. package/src/core/__tests__/rules/no-unmanaged-exceptions.test.ts +0 -54
  87. package/src/core/__tests__/rules/require-return-type.test.ts +0 -79
  88. package/src/core/__tests__/runner.test.ts +0 -288
  89. package/src/core/__tests__/strip-ts-noise.test.ts +0 -109
  90. package/src/core/build-context.ts +0 -96
  91. package/src/core/disable-directives.ts +0 -90
  92. package/src/core/instruct-ai-writer.ts +0 -15
  93. package/src/core/load-config.ts +0 -3
  94. package/src/core/rules/no-any-unknown.ts +0 -35
  95. package/src/core/rules/no-shell-substitution.ts +0 -71
  96. package/src/core/runner.ts +0 -205
  97. package/src/core/strip-ts-noise.ts +0 -103
  98. package/src/core/types.ts +0 -196
  99. package/src/index.ts +0 -14
@@ -1,23 +1,18 @@
1
- import type { EditRule, EditContext, Violation } from '../types';
2
- import { Violation as V } from '../types';
3
-
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const types_1 = require("../types");
4
4
  // Matches function/method signatures that don't have `: ReturnType` before the `{` body opener.
5
5
  // Pattern: function name(<params>) { — missing `: Type` between `)` and `{`
6
6
  const FUNC_DECL_MISSING = /\bfunction\s+\w+\s*(?:<[^>]*>)?\s*\([^)]*\)\s*\{/;
7
-
8
7
  // Matches class method signatures: indented, optional async, name(<params>) {
9
8
  const METHOD_MISSING = /^\s{2,}(?:async\s+)?\w+\s*(?:<[^>]*>)?\s*\([^)]*\)\s*\{/;
10
-
11
9
  // Arrow function: const name = (async)? (<params>) => — missing `: Type` before `=>`
12
10
  const ARROW_MISSING = /\bconst\s+\w+\s*=\s*(?:async\s+)?(?:<[^>]*>)?\s*\([^)]*\)\s*=>/;
13
-
14
11
  // Lines that have ): ReturnType before { or => — these are COMPLIANT
15
12
  const HAS_RETURN_TYPE = /\)\s*:\s*\S/;
16
-
17
13
  // Skip constructors, getters, setters, and control flow keywords
18
14
  const SKIP_PATTERN = /\b(?:constructor|get\s+\w+|set\s+\w+|if|else|while|for|switch|catch|return)\s*\(/;
19
-
20
- const requireReturnTypeRule: EditRule = {
15
+ const requireReturnTypeRule = {
21
16
  name: 'require-return-type',
22
17
  description: 'Every function and method must declare its return type.',
23
18
  scope: 'edit',
@@ -27,33 +22,31 @@ const requireReturnTypeRule: EditRule = {
27
22
  'Add return type: function foo(x: T): ReturnType { ... }',
28
23
  '// webpieces-disable require-return-type -- <reason>',
29
24
  ],
30
-
31
- check(ctx: EditContext): readonly Violation[] {
32
- const violations: V[] = [];
25
+ check(ctx) {
26
+ const violations = [];
33
27
  for (let i = 0; i < ctx.strippedLines.length; i += 1) {
34
28
  const stripped = ctx.strippedLines[i];
35
- if (!isMissingReturnType(stripped)) continue;
29
+ if (!isMissingReturnType(stripped))
30
+ continue;
36
31
  const lineNum = i + 1;
37
- if (ctx.isLineDisabled(lineNum, 'require-return-type')) continue;
38
- violations.push(new V(
39
- lineNum,
40
- ctx.lines[i].trim(),
41
- 'Missing return type annotation.',
42
- ));
32
+ if (ctx.isLineDisabled(lineNum, 'require-return-type'))
33
+ continue;
34
+ violations.push(new types_1.Violation(lineNum, ctx.lines[i].trim(), 'Missing return type annotation.'));
43
35
  }
44
36
  return violations;
45
37
  },
46
38
  };
47
-
48
- function isMissingReturnType(line: string): boolean {
49
- if (SKIP_PATTERN.test(line)) return false;
50
- const isFuncLike =
51
- FUNC_DECL_MISSING.test(line) ||
39
+ function isMissingReturnType(line) {
40
+ if (SKIP_PATTERN.test(line))
41
+ return false;
42
+ const isFuncLike = FUNC_DECL_MISSING.test(line) ||
52
43
  METHOD_MISSING.test(line) ||
53
44
  ARROW_MISSING.test(line);
54
- if (!isFuncLike) return false;
55
- if (HAS_RETURN_TYPE.test(line)) return false;
45
+ if (!isFuncLike)
46
+ return false;
47
+ if (HAS_RETURN_TYPE.test(line))
48
+ return false;
56
49
  return true;
57
50
  }
58
-
59
- export default requireReturnTypeRule;
51
+ exports.default = requireReturnTypeRule;
52
+ //# sourceMappingURL=require-return-type.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"require-return-type.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/ai-hook-rules/src/core/rules/require-return-type.ts"],"names":[],"mappings":";;AACA,oCAA0C;AAE1C,gGAAgG;AAChG,4EAA4E;AAC5E,MAAM,iBAAiB,GAAG,kDAAkD,CAAC;AAE7E,8EAA8E;AAC9E,MAAM,cAAc,GAAG,yDAAyD,CAAC;AAEjF,qFAAqF;AACrF,MAAM,aAAa,GAAG,gEAAgE,CAAC;AAEvF,qEAAqE;AACrE,MAAM,eAAe,GAAG,aAAa,CAAC;AAEtC,iEAAiE;AACjE,MAAM,YAAY,GAAG,kFAAkF,CAAC;AAExG,MAAM,qBAAqB,GAAa;IACpC,IAAI,EAAE,qBAAqB;IAC3B,WAAW,EAAE,yDAAyD;IACtE,KAAK,EAAE,MAAM;IACb,KAAK,EAAE,CAAC,SAAS,EAAE,UAAU,CAAC;IAC9B,cAAc,EAAE,EAAE;IAClB,OAAO,EAAE;QACL,yDAAyD;QACzD,sDAAsD;KACzD;IAED,KAAK,CAAC,GAAgB;QAClB,MAAM,UAAU,GAAQ,EAAE,CAAC;QAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;YACnD,MAAM,QAAQ,GAAG,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;YACtC,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC;gBAAE,SAAS;YAC7C,MAAM,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC;YACtB,IAAI,GAAG,CAAC,cAAc,CAAC,OAAO,EAAE,qBAAqB,CAAC;gBAAE,SAAS;YACjE,UAAU,CAAC,IAAI,CAAC,IAAI,iBAAC,CACjB,OAAO,EACP,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EACnB,iCAAiC,CACpC,CAAC,CAAC;QACP,CAAC;QACD,OAAO,UAAU,CAAC;IACtB,CAAC;CACJ,CAAC;AAEF,SAAS,mBAAmB,CAAC,IAAY;IACrC,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IAC1C,MAAM,UAAU,GACZ,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC;QAC5B,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC;QACzB,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC7B,IAAI,CAAC,UAAU;QAAE,OAAO,KAAK,CAAC;IAC9B,IAAI,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IAC7C,OAAO,IAAI,CAAC;AAChB,CAAC;AAED,kBAAe,qBAAqB,CAAC","sourcesContent":["import type { EditRule, EditContext, Violation } from '../types';\nimport { Violation as V } from '../types';\n\n// Matches function/method signatures that don't have `: ReturnType` before the `{` body opener.\n// Pattern: function name(<params>) { — missing `: Type` between `)` and `{`\nconst FUNC_DECL_MISSING = /\\bfunction\\s+\\w+\\s*(?:<[^>]*>)?\\s*\\([^)]*\\)\\s*\\{/;\n\n// Matches class method signatures: indented, optional async, name(<params>) {\nconst METHOD_MISSING = /^\\s{2,}(?:async\\s+)?\\w+\\s*(?:<[^>]*>)?\\s*\\([^)]*\\)\\s*\\{/;\n\n// Arrow function: const name = (async)? (<params>) => — missing `: Type` before `=>`\nconst ARROW_MISSING = /\\bconst\\s+\\w+\\s*=\\s*(?:async\\s+)?(?:<[^>]*>)?\\s*\\([^)]*\\)\\s*=>/;\n\n// Lines that have ): ReturnType before { or => — these are COMPLIANT\nconst HAS_RETURN_TYPE = /\\)\\s*:\\s*\\S/;\n\n// Skip constructors, getters, setters, and control flow keywords\nconst SKIP_PATTERN = /\\b(?:constructor|get\\s+\\w+|set\\s+\\w+|if|else|while|for|switch|catch|return)\\s*\\(/;\n\nconst requireReturnTypeRule: EditRule = {\n name: 'require-return-type',\n description: 'Every function and method must declare its return type.',\n scope: 'edit',\n files: ['**/*.ts', '**/*.tsx'],\n defaultOptions: {},\n fixHint: [\n 'Add return type: function foo(x: T): ReturnType { ... }',\n '// webpieces-disable require-return-type -- <reason>',\n ],\n\n check(ctx: EditContext): readonly Violation[] {\n const violations: V[] = [];\n for (let i = 0; i < ctx.strippedLines.length; i += 1) {\n const stripped = ctx.strippedLines[i];\n if (!isMissingReturnType(stripped)) continue;\n const lineNum = i + 1;\n if (ctx.isLineDisabled(lineNum, 'require-return-type')) continue;\n violations.push(new V(\n lineNum,\n ctx.lines[i].trim(),\n 'Missing return type annotation.',\n ));\n }\n return violations;\n },\n};\n\nfunction isMissingReturnType(line: string): boolean {\n if (SKIP_PATTERN.test(line)) return false;\n const isFuncLike =\n FUNC_DECL_MISSING.test(line) ||\n METHOD_MISSING.test(line) ||\n ARROW_MISSING.test(line);\n if (!isFuncLike) return false;\n if (HAS_RETURN_TYPE.test(line)) return false;\n return true;\n}\n\nexport default requireReturnTypeRule;\n"]}
@@ -0,0 +1,3 @@
1
+ import { ToolKind, NormalizedToolInput, BlockedResult } from './types';
2
+ export declare function run(toolKind: ToolKind, input: NormalizedToolInput, cwd: string): BlockedResult | null;
3
+ export declare function runBash(command: string, cwd: string): BlockedResult | null;
@@ -0,0 +1,181 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.run = run;
4
+ exports.runBash = runBash;
5
+ const tslib_1 = require("tslib");
6
+ const path = tslib_1.__importStar(require("path"));
7
+ const build_context_1 = require("./build-context");
8
+ const load_config_1 = require("./load-config");
9
+ const load_rules_1 = require("./load-rules");
10
+ const to_error_1 = require("./to-error");
11
+ const report_1 = require("./report");
12
+ const types_1 = require("./types");
13
+ function run(toolKind, input, cwd) {
14
+ // eslint-disable-next-line @webpieces/no-unmanaged-exceptions
15
+ try {
16
+ return runInternal(toolKind, input, cwd);
17
+ }
18
+ catch (err) {
19
+ const error = (0, to_error_1.toError)(err);
20
+ console.error(`[ai-hooks] runner crashed (failing open): ${error.message}`);
21
+ return null;
22
+ }
23
+ }
24
+ function runInternal(toolKind, input, cwd) {
25
+ const config = (0, load_config_1.loadConfig)(cwd);
26
+ if (!config.configPath)
27
+ return null;
28
+ const workspaceRoot = path.dirname(config.configPath);
29
+ const rules = (0, load_rules_1.loadRules)(config, workspaceRoot);
30
+ if (rules.length === 0)
31
+ return null;
32
+ const contexts = (0, build_context_1.buildContexts)(toolKind, input, workspaceRoot);
33
+ const relativePath = path.relative(workspaceRoot, input.filePath);
34
+ const editGroups = runEditRules(rules, contexts.editContexts, config);
35
+ const fileGroups = runFileRules(rules, contexts.fileContext, config);
36
+ const allGroups = [...editGroups, ...fileGroups];
37
+ if (allGroups.length === 0)
38
+ return null;
39
+ const report = (0, report_1.formatReport)(relativePath, allGroups);
40
+ return new types_1.BlockedResult(report);
41
+ }
42
+ function runBash(command, cwd) {
43
+ // eslint-disable-next-line @webpieces/no-unmanaged-exceptions
44
+ try {
45
+ return runBashInternal(command, cwd);
46
+ }
47
+ catch (err) {
48
+ const error = (0, to_error_1.toError)(err);
49
+ console.error(`[ai-hooks] bash runner crashed (failing open): ${error.message}`);
50
+ return null;
51
+ }
52
+ }
53
+ function runBashInternal(command, cwd) {
54
+ const config = (0, load_config_1.loadConfig)(cwd);
55
+ if (!config.configPath)
56
+ return null;
57
+ const workspaceRoot = path.dirname(config.configPath);
58
+ const rules = (0, load_rules_1.loadRules)(config, workspaceRoot);
59
+ if (rules.length === 0)
60
+ return null;
61
+ const ctx = (0, build_context_1.buildBashContext)(command, workspaceRoot);
62
+ const groups = runBashRules(rules, ctx, config);
63
+ if (groups.length === 0)
64
+ return null;
65
+ const report = (0, report_1.formatReport)('<bash>', groups);
66
+ return new types_1.BlockedResult(report);
67
+ }
68
+ function safeCheckBash(rule, ctx) {
69
+ // eslint-disable-next-line @webpieces/no-unmanaged-exceptions
70
+ try {
71
+ return rule.check(ctx);
72
+ }
73
+ catch (err) {
74
+ const error = (0, to_error_1.toError)(err);
75
+ process.stderr.write(`[ai-hooks] rule ${rule.name} crashed: ${error.message}\n`);
76
+ return [];
77
+ }
78
+ }
79
+ function runBashRules(rules, bashContext, config) {
80
+ const groups = [];
81
+ for (const rule of rules) {
82
+ if (rule.scope !== 'bash')
83
+ continue;
84
+ const ruleConfig = config.rules.get(rule.name);
85
+ if (!ruleConfig || ruleConfig.enabled === false)
86
+ continue;
87
+ bashContext.options = mergeOptions(rule.defaultOptions, ruleConfig);
88
+ const vs = safeCheckBash(rule, bashContext);
89
+ if (vs.length > 0) {
90
+ groups.push(new types_1.RuleGroup(rule.name, rule.description, [...rule.fixHint], [...vs]));
91
+ }
92
+ }
93
+ return groups;
94
+ }
95
+ function ruleMatchesFile(rule, relativePath) {
96
+ for (const pattern of rule.files) {
97
+ if ((0, load_rules_1.globMatches)(pattern, relativePath))
98
+ return true;
99
+ }
100
+ return false;
101
+ }
102
+ function mergeOptions(defaultOptions, ruleConfig) {
103
+ // webpieces-disable no-any-unknown -- building an options bag from opaque RuleOptions
104
+ const out = {};
105
+ for (const key of Object.keys(defaultOptions))
106
+ out[key] = defaultOptions[key];
107
+ for (const key of Object.keys(ruleConfig.options)) {
108
+ if (key === 'enabled')
109
+ continue;
110
+ out[key] = ruleConfig.options[key];
111
+ }
112
+ return out;
113
+ }
114
+ function safeCheckEdit(rule, ctx) {
115
+ // eslint-disable-next-line @webpieces/no-unmanaged-exceptions
116
+ try {
117
+ return rule.check(ctx);
118
+ }
119
+ catch (err) {
120
+ const error = (0, to_error_1.toError)(err);
121
+ process.stderr.write(`[ai-hooks] rule ${rule.name} crashed: ${error.message}\n`);
122
+ return [];
123
+ }
124
+ }
125
+ function safeCheckFile(rule, ctx) {
126
+ // eslint-disable-next-line @webpieces/no-unmanaged-exceptions
127
+ try {
128
+ return rule.check(ctx);
129
+ }
130
+ catch (err) {
131
+ const error = (0, to_error_1.toError)(err);
132
+ process.stderr.write(`[ai-hooks] rule ${rule.name} crashed: ${error.message}\n`);
133
+ return [];
134
+ }
135
+ }
136
+ function runEditRules(rules, editContexts, config) {
137
+ const groups = [];
138
+ for (const rule of rules) {
139
+ if (rule.scope !== 'edit')
140
+ continue;
141
+ const ruleConfig = config.rules.get(rule.name);
142
+ if (!ruleConfig || ruleConfig.enabled === false)
143
+ continue;
144
+ const allViolations = [];
145
+ for (const ctx of editContexts) {
146
+ if (!ruleMatchesFile(rule, ctx.relativePath))
147
+ continue;
148
+ ctx.options = mergeOptions(rule.defaultOptions, ruleConfig);
149
+ const vs = safeCheckEdit(rule, ctx);
150
+ for (const v of vs) {
151
+ const copy = new types_1.Violation(v.line, v.snippet, v.message);
152
+ copy.editIndex = ctx.editIndex;
153
+ copy.editCount = ctx.editCount;
154
+ allViolations.push(copy);
155
+ }
156
+ }
157
+ if (allViolations.length > 0) {
158
+ groups.push(new types_1.RuleGroup(rule.name, rule.description, [...rule.fixHint], allViolations));
159
+ }
160
+ }
161
+ return groups;
162
+ }
163
+ function runFileRules(rules, fileContext, config) {
164
+ const groups = [];
165
+ for (const rule of rules) {
166
+ if (rule.scope !== 'file')
167
+ continue;
168
+ const ruleConfig = config.rules.get(rule.name);
169
+ if (!ruleConfig || ruleConfig.enabled === false)
170
+ continue;
171
+ if (!ruleMatchesFile(rule, fileContext.relativePath))
172
+ continue;
173
+ fileContext.options = mergeOptions(rule.defaultOptions, ruleConfig);
174
+ const vs = safeCheckFile(rule, fileContext);
175
+ if (vs.length > 0) {
176
+ groups.push(new types_1.RuleGroup(rule.name, rule.description, [...rule.fixHint], [...vs]));
177
+ }
178
+ }
179
+ return groups;
180
+ }
181
+ //# sourceMappingURL=runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.js","sourceRoot":"","sources":["../../../../../../packages/tooling/ai-hook-rules/src/core/runner.ts"],"names":[],"mappings":"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","sourcesContent":["import * as path from 'path';\n\nimport { buildContexts, buildBashContext } from './build-context';\nimport { loadConfig } from './load-config';\nimport { loadRules, globMatches } from './load-rules';\nimport { toError } from './to-error';\nimport { formatReport } from './report';\nimport {\n ToolKind, NormalizedToolInput, BlockedResult,\n Rule, EditRule, FileRule, BashRule, Violation, RuleGroup,\n EditContext, FileContext, BashContext,\n ResolvedConfig, ResolvedRuleConfig, RuleOptions,\n} from './types';\n\nexport function run(\n toolKind: ToolKind,\n input: NormalizedToolInput,\n cwd: string,\n): BlockedResult | null {\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n return runInternal(toolKind, input, cwd);\n } catch (err: unknown) {\n const error = toError(err);\n console.error(`[ai-hooks] runner crashed (failing open): ${error.message}`);\n return null;\n }\n}\n\nfunction runInternal(\n toolKind: ToolKind,\n input: NormalizedToolInput,\n cwd: string,\n): BlockedResult | null {\n const config = loadConfig(cwd);\n if (!config.configPath) return null;\n\n const workspaceRoot = path.dirname(config.configPath);\n const rules = loadRules(config, workspaceRoot);\n if (rules.length === 0) return null;\n\n const contexts = buildContexts(toolKind, input, workspaceRoot);\n const relativePath = path.relative(workspaceRoot, input.filePath);\n\n const editGroups = runEditRules(rules, contexts.editContexts, config);\n const fileGroups = runFileRules(rules, contexts.fileContext, config);\n const allGroups = [...editGroups, ...fileGroups];\n\n if (allGroups.length === 0) return null;\n\n const report = formatReport(relativePath, allGroups);\n return new BlockedResult(report);\n}\n\nexport function runBash(command: string, cwd: string): BlockedResult | null {\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n return runBashInternal(command, cwd);\n } catch (err: unknown) {\n const error = toError(err);\n console.error(`[ai-hooks] bash runner crashed (failing open): ${error.message}`);\n return null;\n }\n}\n\nfunction runBashInternal(command: string, cwd: string): BlockedResult | null {\n const config = loadConfig(cwd);\n if (!config.configPath) return null;\n\n const workspaceRoot = path.dirname(config.configPath);\n const rules = loadRules(config, workspaceRoot);\n if (rules.length === 0) return null;\n\n const ctx = buildBashContext(command, workspaceRoot);\n const groups = runBashRules(rules, ctx, config);\n if (groups.length === 0) return null;\n\n const report = formatReport('<bash>', groups);\n return new BlockedResult(report);\n}\n\nfunction safeCheckBash(rule: BashRule, ctx: BashContext): readonly Violation[] {\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n return rule.check(ctx);\n } catch (err: unknown) {\n const error = toError(err);\n process.stderr.write(`[ai-hooks] rule ${rule.name} crashed: ${error.message}\\n`);\n return [];\n }\n}\n\nfunction runBashRules(\n rules: readonly Rule[],\n bashContext: BashContext,\n config: ResolvedConfig,\n): readonly RuleGroup[] {\n const groups: RuleGroup[] = [];\n for (const rule of rules) {\n if (rule.scope !== 'bash') continue;\n const ruleConfig = config.rules.get(rule.name);\n if (!ruleConfig || ruleConfig.enabled === false) continue;\n bashContext.options = mergeOptions(rule.defaultOptions, ruleConfig);\n const vs = safeCheckBash(rule as BashRule, bashContext);\n if (vs.length > 0) {\n groups.push(new RuleGroup(\n rule.name, rule.description, [...rule.fixHint], [...vs],\n ));\n }\n }\n return groups;\n}\n\nfunction ruleMatchesFile(rule: Rule, relativePath: string): boolean {\n for (const pattern of rule.files) {\n if (globMatches(pattern, relativePath)) return true;\n }\n return false;\n}\n\nfunction mergeOptions(defaultOptions: RuleOptions, ruleConfig: ResolvedRuleConfig): RuleOptions {\n // webpieces-disable no-any-unknown -- building an options bag from opaque RuleOptions\n const out: Record<string, unknown> = {};\n for (const key of Object.keys(defaultOptions)) out[key] = defaultOptions[key];\n for (const key of Object.keys(ruleConfig.options)) {\n if (key === 'enabled') continue;\n out[key] = ruleConfig.options[key];\n }\n return out;\n}\n\nfunction safeCheckEdit(rule: EditRule, ctx: EditContext): readonly Violation[] {\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n return rule.check(ctx);\n } catch (err: unknown) {\n const error = toError(err);\n process.stderr.write(`[ai-hooks] rule ${rule.name} crashed: ${error.message}\\n`);\n return [];\n }\n}\n\nfunction safeCheckFile(rule: FileRule, ctx: FileContext): readonly Violation[] {\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n return rule.check(ctx);\n } catch (err: unknown) {\n const error = toError(err);\n process.stderr.write(`[ai-hooks] rule ${rule.name} crashed: ${error.message}\\n`);\n return [];\n }\n}\n\nfunction runEditRules(\n rules: readonly Rule[],\n editContexts: readonly EditContext[],\n config: ResolvedConfig,\n): readonly RuleGroup[] {\n const groups: RuleGroup[] = [];\n for (const rule of rules) {\n if (rule.scope !== 'edit') continue;\n const ruleConfig = config.rules.get(rule.name);\n if (!ruleConfig || ruleConfig.enabled === false) continue;\n const allViolations: Violation[] = [];\n for (const ctx of editContexts) {\n if (!ruleMatchesFile(rule, ctx.relativePath)) continue;\n ctx.options = mergeOptions(rule.defaultOptions, ruleConfig);\n const vs = safeCheckEdit(rule as EditRule, ctx);\n for (const v of vs) {\n const copy = new Violation(v.line, v.snippet, v.message);\n copy.editIndex = ctx.editIndex;\n copy.editCount = ctx.editCount;\n allViolations.push(copy);\n }\n }\n if (allViolations.length > 0) {\n groups.push(new RuleGroup(\n rule.name, rule.description, [...rule.fixHint], allViolations,\n ));\n }\n }\n return groups;\n}\n\nfunction runFileRules(\n rules: readonly Rule[],\n fileContext: FileContext,\n config: ResolvedConfig,\n): readonly RuleGroup[] {\n const groups: RuleGroup[] = [];\n for (const rule of rules) {\n if (rule.scope !== 'file') continue;\n const ruleConfig = config.rules.get(rule.name);\n if (!ruleConfig || ruleConfig.enabled === false) continue;\n if (!ruleMatchesFile(rule, fileContext.relativePath)) continue;\n fileContext.options = mergeOptions(rule.defaultOptions, ruleConfig);\n const vs = safeCheckFile(rule as FileRule, fileContext);\n if (vs.length > 0) {\n groups.push(new RuleGroup(\n rule.name, rule.description, [...rule.fixHint], [...vs],\n ));\n }\n }\n return groups;\n}\n"]}
@@ -0,0 +1 @@
1
+ export declare function stripTsNoise(source: string): string;
@@ -0,0 +1,178 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.stripTsNoise = stripTsNoise;
4
+ class StripState {
5
+ constructor(source) {
6
+ this.source = source;
7
+ this.len = source.length;
8
+ this.out = new Array(source.length);
9
+ this.stack = [];
10
+ this.state = 'code';
11
+ this.braceDepth = 0;
12
+ this.i = 0;
13
+ }
14
+ ch() { return this.source[this.i]; }
15
+ next() { return this.i + 1 < this.len ? this.source[this.i + 1] : ''; }
16
+ emit(idx, ch) { this.out[idx] = ch; }
17
+ blank(idx, ch) { this.out[idx] = ch === '\n' ? '\n' : ' '; }
18
+ pushState(newState) {
19
+ this.stack.push({ state: this.state, braceDepth: this.braceDepth });
20
+ this.state = newState;
21
+ }
22
+ popState() {
23
+ const frame = this.stack.pop();
24
+ this.state = frame.state;
25
+ this.braceDepth = frame.braceDepth;
26
+ }
27
+ }
28
+ function handleCodeOrInterp(s) {
29
+ const ch = s.ch();
30
+ const next = s.next();
31
+ if (s.state === 'templateInterp') {
32
+ if (ch === '{') {
33
+ s.braceDepth += 1;
34
+ s.emit(s.i, ch);
35
+ s.i += 1;
36
+ return;
37
+ }
38
+ if (ch === '}') {
39
+ if (s.braceDepth === 0) {
40
+ s.emit(s.i, ch);
41
+ s.i += 1;
42
+ s.popState();
43
+ return;
44
+ }
45
+ s.braceDepth -= 1;
46
+ s.emit(s.i, ch);
47
+ s.i += 1;
48
+ return;
49
+ }
50
+ }
51
+ if (ch === '/' && next === '/') {
52
+ s.emit(s.i, '/');
53
+ s.emit(s.i + 1, '/');
54
+ s.i += 2;
55
+ s.pushState('lineComment');
56
+ return;
57
+ }
58
+ if (ch === '/' && next === '*') {
59
+ s.emit(s.i, '/');
60
+ s.emit(s.i + 1, '*');
61
+ s.i += 2;
62
+ s.pushState('blockComment');
63
+ return;
64
+ }
65
+ if (ch === '"') {
66
+ s.emit(s.i, '"');
67
+ s.i += 1;
68
+ s.pushState('dquote');
69
+ return;
70
+ }
71
+ if (ch === "'") {
72
+ s.emit(s.i, "'");
73
+ s.i += 1;
74
+ s.pushState('squote');
75
+ return;
76
+ }
77
+ if (ch === '`') {
78
+ s.emit(s.i, '`');
79
+ s.i += 1;
80
+ s.pushState('template');
81
+ return;
82
+ }
83
+ s.emit(s.i, ch);
84
+ s.i += 1;
85
+ }
86
+ function handleLineComment(s) {
87
+ if (s.ch() === '\n') {
88
+ s.emit(s.i, '\n');
89
+ s.i += 1;
90
+ s.popState();
91
+ return;
92
+ }
93
+ s.blank(s.i, s.ch());
94
+ s.i += 1;
95
+ }
96
+ function handleBlockComment(s) {
97
+ if (s.ch() === '*' && s.next() === '/') {
98
+ s.emit(s.i, '*');
99
+ s.emit(s.i + 1, '/');
100
+ s.i += 2;
101
+ s.popState();
102
+ return;
103
+ }
104
+ s.blank(s.i, s.ch());
105
+ s.i += 1;
106
+ }
107
+ function handleStringLiteral(s, quoteChar) {
108
+ const ch = s.ch();
109
+ if (ch === '\\' && s.i + 1 < s.len) {
110
+ s.blank(s.i, ch);
111
+ s.blank(s.i + 1, s.source[s.i + 1]);
112
+ s.i += 2;
113
+ return;
114
+ }
115
+ if (ch === quoteChar) {
116
+ s.emit(s.i, quoteChar);
117
+ s.i += 1;
118
+ s.popState();
119
+ return;
120
+ }
121
+ s.blank(s.i, ch);
122
+ s.i += 1;
123
+ }
124
+ function handleTemplate(s) {
125
+ const ch = s.ch();
126
+ if (ch === '\\' && s.i + 1 < s.len) {
127
+ s.blank(s.i, ch);
128
+ s.blank(s.i + 1, s.source[s.i + 1]);
129
+ s.i += 2;
130
+ return;
131
+ }
132
+ if (ch === '`') {
133
+ s.emit(s.i, '`');
134
+ s.i += 1;
135
+ s.popState();
136
+ return;
137
+ }
138
+ if (ch === '$' && s.next() === '{') {
139
+ s.emit(s.i, '$');
140
+ s.emit(s.i + 1, '{');
141
+ s.i += 2;
142
+ s.stack.push({ state: 'template', braceDepth: 0 });
143
+ s.state = 'templateInterp';
144
+ s.braceDepth = 0;
145
+ return;
146
+ }
147
+ s.blank(s.i, ch);
148
+ s.i += 1;
149
+ }
150
+ function stripTsNoise(source) {
151
+ const s = new StripState(source);
152
+ while (s.i < s.len) {
153
+ if (s.state === 'code' || s.state === 'templateInterp') {
154
+ handleCodeOrInterp(s);
155
+ }
156
+ else if (s.state === 'lineComment') {
157
+ handleLineComment(s);
158
+ }
159
+ else if (s.state === 'blockComment') {
160
+ handleBlockComment(s);
161
+ }
162
+ else if (s.state === 'dquote') {
163
+ handleStringLiteral(s, '"');
164
+ }
165
+ else if (s.state === 'squote') {
166
+ handleStringLiteral(s, "'");
167
+ }
168
+ else if (s.state === 'template') {
169
+ handleTemplate(s);
170
+ }
171
+ else {
172
+ s.emit(s.i, s.ch());
173
+ s.i += 1;
174
+ }
175
+ }
176
+ return s.out.join('');
177
+ }
178
+ //# sourceMappingURL=strip-ts-noise.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"strip-ts-noise.js","sourceRoot":"","sources":["../../../../../../packages/tooling/ai-hook-rules/src/core/strip-ts-noise.ts"],"names":[],"mappings":"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","sourcesContent":["interface StackFrame {\n readonly state: string;\n readonly braceDepth: number;\n}\n\nclass StripState {\n readonly source: string;\n readonly len: number;\n readonly out: string[];\n readonly stack: StackFrame[];\n state: string;\n braceDepth: number;\n i: number;\n\n constructor(source: string) {\n this.source = source;\n this.len = source.length;\n this.out = new Array<string>(source.length);\n this.stack = [];\n this.state = 'code';\n this.braceDepth = 0;\n this.i = 0;\n }\n\n ch(): string { return this.source[this.i]; }\n next(): string { return this.i + 1 < this.len ? this.source[this.i + 1] : ''; }\n emit(idx: number, ch: string): void { this.out[idx] = ch; }\n blank(idx: number, ch: string): void { this.out[idx] = ch === '\\n' ? '\\n' : ' '; }\n\n pushState(newState: string): void {\n this.stack.push({ state: this.state, braceDepth: this.braceDepth });\n this.state = newState;\n }\n\n popState(): void {\n const frame = this.stack.pop()!;\n this.state = frame.state;\n this.braceDepth = frame.braceDepth;\n }\n}\n\nfunction handleCodeOrInterp(s: StripState): void {\n const ch = s.ch();\n const next = s.next();\n\n if (s.state === 'templateInterp') {\n if (ch === '{') { s.braceDepth += 1; s.emit(s.i, ch); s.i += 1; return; }\n if (ch === '}') {\n if (s.braceDepth === 0) { s.emit(s.i, ch); s.i += 1; s.popState(); return; }\n s.braceDepth -= 1; s.emit(s.i, ch); s.i += 1; return;\n }\n }\n if (ch === '/' && next === '/') { s.emit(s.i, '/'); s.emit(s.i + 1, '/'); s.i += 2; s.pushState('lineComment'); return; }\n if (ch === '/' && next === '*') { s.emit(s.i, '/'); s.emit(s.i + 1, '*'); s.i += 2; s.pushState('blockComment'); return; }\n if (ch === '\"') { s.emit(s.i, '\"'); s.i += 1; s.pushState('dquote'); return; }\n if (ch === \"'\") { s.emit(s.i, \"'\"); s.i += 1; s.pushState('squote'); return; }\n if (ch === '`') { s.emit(s.i, '`'); s.i += 1; s.pushState('template'); return; }\n s.emit(s.i, ch); s.i += 1;\n}\n\nfunction handleLineComment(s: StripState): void {\n if (s.ch() === '\\n') { s.emit(s.i, '\\n'); s.i += 1; s.popState(); return; }\n s.blank(s.i, s.ch()); s.i += 1;\n}\n\nfunction handleBlockComment(s: StripState): void {\n if (s.ch() === '*' && s.next() === '/') { s.emit(s.i, '*'); s.emit(s.i + 1, '/'); s.i += 2; s.popState(); return; }\n s.blank(s.i, s.ch()); s.i += 1;\n}\n\nfunction handleStringLiteral(s: StripState, quoteChar: string): void {\n const ch = s.ch();\n if (ch === '\\\\' && s.i + 1 < s.len) { s.blank(s.i, ch); s.blank(s.i + 1, s.source[s.i + 1]); s.i += 2; return; }\n if (ch === quoteChar) { s.emit(s.i, quoteChar); s.i += 1; s.popState(); return; }\n s.blank(s.i, ch); s.i += 1;\n}\n\nfunction handleTemplate(s: StripState): void {\n const ch = s.ch();\n if (ch === '\\\\' && s.i + 1 < s.len) { s.blank(s.i, ch); s.blank(s.i + 1, s.source[s.i + 1]); s.i += 2; return; }\n if (ch === '`') { s.emit(s.i, '`'); s.i += 1; s.popState(); return; }\n if (ch === '$' && s.next() === '{') {\n s.emit(s.i, '$'); s.emit(s.i + 1, '{'); s.i += 2;\n s.stack.push({ state: 'template', braceDepth: 0 });\n s.state = 'templateInterp'; s.braceDepth = 0;\n return;\n }\n s.blank(s.i, ch); s.i += 1;\n}\n\nexport function stripTsNoise(source: string): string {\n const s = new StripState(source);\n while (s.i < s.len) {\n if (s.state === 'code' || s.state === 'templateInterp') { handleCodeOrInterp(s); }\n else if (s.state === 'lineComment') { handleLineComment(s); }\n else if (s.state === 'blockComment') { handleBlockComment(s); }\n else if (s.state === 'dquote') { handleStringLiteral(s, '\"'); }\n else if (s.state === 'squote') { handleStringLiteral(s, \"'\"); }\n else if (s.state === 'template') { handleTemplate(s); }\n else { s.emit(s.i, s.ch()); s.i += 1; }\n }\n return s.out.join('');\n}\n"]}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Lightweight duplicate of @webpieces/core-util toError.
3
+ * ai-hooks is a standalone package and cannot depend on core-util or dev-config.
4
+ */
5
+ export declare function toError(err: unknown): Error;
@@ -1,14 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.toError = toError;
1
4
  // ai-hook-disable-file require-return-type -- toError is a utility copied from dev-config; function return type is on line 6
2
5
  /**
3
6
  * Lightweight duplicate of @webpieces/core-util toError.
4
7
  * ai-hooks is a standalone package and cannot depend on core-util or dev-config.
5
8
  */
6
9
  // webpieces-disable no-any-unknown -- toError intentionally accepts unknown to safely convert any thrown value to Error
7
- export function toError(err: unknown): Error {
10
+ function toError(err) {
8
11
  if (err instanceof Error) {
9
12
  return err;
10
13
  }
11
-
12
14
  if (err && typeof err === 'object') {
13
15
  if ('message' in err) {
14
16
  const error = new Error(String(err.message));
@@ -23,13 +25,14 @@ export function toError(err: unknown): Error {
23
25
  // eslint-disable-next-line @webpieces/no-unmanaged-exceptions
24
26
  try {
25
27
  return new Error(`Non-Error object thrown: ${JSON.stringify(err)}`);
26
- } catch (err: unknown) {
28
+ }
29
+ catch (err) {
27
30
  //const error = toError(err);
28
31
  void err;
29
32
  return new Error('Non-Error object thrown (unable to stringify)');
30
33
  }
31
34
  }
32
-
33
35
  const message = err == null ? 'Null or undefined thrown' : String(err);
34
36
  return new Error(message);
35
37
  }
38
+ //# sourceMappingURL=to-error.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"to-error.js","sourceRoot":"","sources":["../../../../../../packages/tooling/ai-hook-rules/src/core/to-error.ts"],"names":[],"mappings":";;AAMA,0BA4BC;AAlCD,6HAA6H;AAC7H;;;GAGG;AACH,wHAAwH;AACxH,SAAgB,OAAO,CAAC,GAAY;IAChC,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;QACvB,OAAO,GAAG,CAAC;IACf,CAAC;IAED,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QACjC,IAAI,SAAS,IAAI,GAAG,EAAE,CAAC;YACnB,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;YAC7C,IAAI,OAAO,IAAI,GAAG,IAAI,OAAO,GAAG,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;gBAClD,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC;YAC5B,CAAC;YACD,IAAI,MAAM,IAAI,GAAG,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAChD,KAAK,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;YAC1B,CAAC;YACD,OAAO,KAAK,CAAC;QACjB,CAAC;QACD,8DAA8D;QAC9D,IAAI,CAAC;YACD,OAAO,IAAI,KAAK,CAAC,4BAA4B,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACxE,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACpB,6BAA6B;YAC7B,KAAK,GAAG,CAAC;YACT,OAAO,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;QACtE,CAAC;IACL,CAAC;IAED,MAAM,OAAO,GAAG,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACvE,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;AAC9B,CAAC","sourcesContent":["// ai-hook-disable-file require-return-type -- toError is a utility copied from dev-config; function return type is on line 6\n/**\n * Lightweight duplicate of @webpieces/core-util toError.\n * ai-hooks is a standalone package and cannot depend on core-util or dev-config.\n */\n// webpieces-disable no-any-unknown -- toError intentionally accepts unknown to safely convert any thrown value to Error\nexport function toError(err: unknown): Error {\n if (err instanceof Error) {\n return err;\n }\n\n if (err && typeof err === 'object') {\n if ('message' in err) {\n const error = new Error(String(err.message));\n if ('stack' in err && typeof err.stack === 'string') {\n error.stack = err.stack;\n }\n if ('name' in err && typeof err.name === 'string') {\n error.name = err.name;\n }\n return error;\n }\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n return new Error(`Non-Error object thrown: ${JSON.stringify(err)}`);\n } catch (err: unknown) {\n //const error = toError(err);\n void err;\n return new Error('Non-Error object thrown (unable to stringify)');\n }\n }\n\n const message = err == null ? 'Null or undefined thrown' : String(err);\n return new Error(message);\n}\n"]}
@@ -0,0 +1,93 @@
1
+ import { RuleOptions } from '@webpieces/rules-config';
2
+ export { ResolvedConfig, ResolvedRuleConfig, RuleOptions } from '@webpieces/rules-config';
3
+ export type ToolKind = 'Write' | 'Edit' | 'MultiEdit';
4
+ export type RuleScope = 'edit' | 'file' | 'bash';
5
+ export type IsLineDisabled = (lineNum: number, ruleName: string) => boolean;
6
+ export declare class Violation {
7
+ readonly line: number;
8
+ readonly snippet: string;
9
+ readonly message: string;
10
+ editIndex: number | undefined;
11
+ editCount: number | undefined;
12
+ constructor(line: number, snippet: string, message: string);
13
+ }
14
+ export declare class NormalizedEdit {
15
+ readonly oldString: string;
16
+ readonly newString: string;
17
+ constructor(oldString: string, newString: string);
18
+ }
19
+ export declare class NormalizedToolInput {
20
+ readonly filePath: string;
21
+ readonly edits: readonly NormalizedEdit[];
22
+ constructor(filePath: string, edits: readonly NormalizedEdit[]);
23
+ }
24
+ export declare class NormalizedBashInput {
25
+ readonly command: string;
26
+ constructor(command: string);
27
+ }
28
+ export declare class EditContext {
29
+ readonly tool: ToolKind;
30
+ readonly editIndex: number;
31
+ readonly editCount: number;
32
+ readonly filePath: string;
33
+ readonly relativePath: string;
34
+ readonly workspaceRoot: string;
35
+ readonly addedContent: string;
36
+ readonly strippedContent: string;
37
+ readonly lines: readonly string[];
38
+ readonly strippedLines: readonly string[];
39
+ readonly removedContent: string;
40
+ readonly isLineDisabled: IsLineDisabled;
41
+ options: RuleOptions;
42
+ constructor(tool: ToolKind, editIndex: number, editCount: number, filePath: string, relativePath: string, workspaceRoot: string, addedContent: string, strippedContent: string, lines: readonly string[], strippedLines: readonly string[], removedContent: string, isLineDisabled: IsLineDisabled);
43
+ }
44
+ export declare class BashContext {
45
+ readonly tool: 'Bash';
46
+ readonly command: string;
47
+ readonly workspaceRoot: string;
48
+ options: RuleOptions;
49
+ constructor(command: string, workspaceRoot: string);
50
+ }
51
+ export declare class FileContext {
52
+ readonly tool: ToolKind;
53
+ readonly filePath: string;
54
+ readonly relativePath: string;
55
+ readonly workspaceRoot: string;
56
+ readonly currentFileLines: number;
57
+ readonly linesAdded: number;
58
+ readonly linesRemoved: number;
59
+ readonly projectedFileLines: number;
60
+ options: RuleOptions;
61
+ constructor(tool: ToolKind, filePath: string, relativePath: string, workspaceRoot: string, currentFileLines: number, linesAdded: number, linesRemoved: number, projectedFileLines: number);
62
+ }
63
+ interface RuleBase {
64
+ readonly name: string;
65
+ readonly description: string;
66
+ readonly files: readonly string[];
67
+ readonly defaultOptions: RuleOptions;
68
+ readonly fixHint: readonly string[];
69
+ }
70
+ export interface EditRule extends RuleBase {
71
+ readonly scope: 'edit';
72
+ check(ctx: EditContext): readonly Violation[];
73
+ }
74
+ export interface FileRule extends RuleBase {
75
+ readonly scope: 'file';
76
+ check(ctx: FileContext): readonly Violation[];
77
+ }
78
+ export interface BashRule extends RuleBase {
79
+ readonly scope: 'bash';
80
+ check(ctx: BashContext): readonly Violation[];
81
+ }
82
+ export type Rule = EditRule | FileRule | BashRule;
83
+ export declare class RuleGroup {
84
+ readonly ruleName: string;
85
+ readonly ruleDescription: string;
86
+ readonly fixHint: readonly string[];
87
+ readonly violations: readonly Violation[];
88
+ constructor(ruleName: string, ruleDescription: string, fixHint: readonly string[], violations: readonly Violation[]);
89
+ }
90
+ export declare class BlockedResult {
91
+ readonly report: string;
92
+ constructor(report: string);
93
+ }