@webpieces/ai-hooks 0.2.105 → 0.2.107

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/ai-hooks",
3
- "version": "0.2.105",
3
+ "version": "0.2.107",
4
4
  "description": "Pluggable write-time validation framework for AI coding agents. Claude Code PreToolUse + openclaw before_tool_call adapters share one rule engine.",
5
5
  "type": "commonjs",
6
6
  "main": "./src/index.js",
@@ -28,6 +28,9 @@
28
28
  "url": "https://github.com/deanhiller/webpieces-ts.git",
29
29
  "directory": "packages/tooling/ai-hooks"
30
30
  },
31
+ "dependencies": {
32
+ "@webpieces/config": "0.2.107"
33
+ },
31
34
  "publishConfig": {
32
35
  "access": "public"
33
36
  },
@@ -1,3 +1 @@
1
- import { ResolvedConfig } from './types';
2
- export declare function findConfigFile(startDir: string): string | null;
3
- export declare function loadConfig(cwd: string): ResolvedConfig;
1
+ export { loadConfig, findConfigFile, CONFIG_FILENAME } from '@webpieces/config';
@@ -1,81 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.findConfigFile = findConfigFile;
4
- exports.loadConfig = loadConfig;
5
- const tslib_1 = require("tslib");
6
- const fs = tslib_1.__importStar(require("fs"));
7
- const path = tslib_1.__importStar(require("path"));
8
- const types_1 = require("./types");
9
- function findConfigFile(startDir) {
10
- let dir = startDir;
11
- while (true) {
12
- const candidate = path.join(dir, 'webpieces.ai-hooks.json');
13
- if (fs.existsSync(candidate))
14
- return candidate;
15
- const parent = path.dirname(dir);
16
- if (parent === dir)
17
- return null;
18
- dir = parent;
19
- }
20
- }
21
- // webpieces-disable no-any-unknown -- default config returns opaque rule option bags
22
- function loadDefaultConfig() {
23
- const defaultModule = require('./configs/default');
24
- // webpieces-disable no-any-unknown -- opaque rule option bags
25
- return defaultModule.defaultRules;
26
- }
27
- // webpieces-disable no-any-unknown -- merging opaque option bags from config JSON
28
- function mergeRule(
29
- // webpieces-disable no-any-unknown -- opaque option bag
30
- baseRule,
31
- // webpieces-disable no-any-unknown -- opaque option bag
32
- overrideRule) {
33
- if (!baseRule && !overrideRule)
34
- return new types_1.ResolvedRuleConfig(false, {});
35
- if (!baseRule)
36
- return new types_1.ResolvedRuleConfig(true, overrideRule);
37
- if (!overrideRule) {
38
- const enabled = baseRule['enabled'] !== false;
39
- return new types_1.ResolvedRuleConfig(enabled, baseRule);
40
- }
41
- // webpieces-disable no-any-unknown -- building merged option bag
42
- const merged = {};
43
- for (const key of Object.keys(baseRule))
44
- merged[key] = baseRule[key];
45
- for (const key of Object.keys(overrideRule))
46
- merged[key] = overrideRule[key];
47
- const enabled = merged['enabled'] !== false;
48
- return new types_1.ResolvedRuleConfig(enabled, merged);
49
- }
50
- function loadConfig(cwd) {
51
- const configPath = findConfigFile(cwd);
52
- const defaultRules = loadDefaultConfig();
53
- if (!configPath) {
54
- return new types_1.ResolvedConfig(new Map(), [], null);
55
- }
56
- let consumerConfig;
57
- // eslint-disable-next-line @webpieces/no-unmanaged-exceptions
58
- try {
59
- const raw = fs.readFileSync(configPath, 'utf8');
60
- consumerConfig = JSON.parse(raw);
61
- }
62
- catch (err) {
63
- // eslint-disable-next-line @webpieces/catch-error-pattern -- malformed config fails open
64
- void err;
65
- return new types_1.ResolvedConfig(new Map(), [], configPath);
66
- }
67
- const overrideRules = consumerConfig.rules || {};
68
- const mergedRules = new Map();
69
- const allRuleNames = new Set([
70
- ...Object.keys(defaultRules),
71
- ...Object.keys(overrideRules),
72
- ]);
73
- for (const name of allRuleNames) {
74
- mergedRules.set(name, mergeRule(defaultRules[name], overrideRules[name]));
75
- }
76
- const baseDirs = [];
77
- const overrideDirs = consumerConfig.rulesDir || [];
78
- const rulesDir = [...baseDirs, ...overrideDirs];
79
- return new types_1.ResolvedConfig(mergedRules, rulesDir, configPath);
80
- }
3
+ exports.CONFIG_FILENAME = exports.findConfigFile = exports.loadConfig = void 0;
4
+ // Re-export the shared workspace config loader so ai-hooks and the Nx
5
+ // validate-code executor use the same webpieces.config.json.
6
+ var config_1 = require("@webpieces/config");
7
+ Object.defineProperty(exports, "loadConfig", { enumerable: true, get: function () { return config_1.loadConfig; } });
8
+ Object.defineProperty(exports, "findConfigFile", { enumerable: true, get: function () { return config_1.findConfigFile; } });
9
+ Object.defineProperty(exports, "CONFIG_FILENAME", { enumerable: true, get: function () { return config_1.CONFIG_FILENAME; } });
81
10
  //# sourceMappingURL=load-config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"load-config.js","sourceRoot":"","sources":["../../../../../../packages/tooling/ai-hooks/src/core/load-config.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fs from 'fs';\nimport * as path from 'path';\n\nimport { ResolvedConfig, ResolvedRuleConfig, RuleOptions } from './types';\n\n// webpieces-disable no-any-unknown -- consumer JSON config has opaque rule option values\ninterface RawConfigFile {\n extends?: string;\n rules?: Record<string, Record<string, unknown>>;\n rulesDir?: string[];\n}\n\nexport function findConfigFile(startDir: string): string | null {\n let dir = startDir;\n while (true) {\n const candidate = path.join(dir, 'webpieces.ai-hooks.json');\n if (fs.existsSync(candidate)) return candidate;\n const parent = path.dirname(dir);\n if (parent === dir) return null;\n dir = parent;\n }\n}\n\n// webpieces-disable no-any-unknown -- default config returns opaque rule option bags\nfunction loadDefaultConfig(): Record<string, Record<string, unknown>> {\n const defaultModule = require('./configs/default');\n // webpieces-disable no-any-unknown -- opaque rule option bags\n return defaultModule.defaultRules as Record<string, Record<string, unknown>>;\n}\n\n// webpieces-disable no-any-unknown -- merging opaque option bags from config JSON\nfunction mergeRule(\n // webpieces-disable no-any-unknown -- opaque option bag\n baseRule: Record<string, unknown> | undefined,\n // webpieces-disable no-any-unknown -- opaque option bag\n overrideRule: Record<string, unknown> | undefined,\n): ResolvedRuleConfig {\n if (!baseRule && !overrideRule) return new ResolvedRuleConfig(false, {});\n if (!baseRule) return new ResolvedRuleConfig(true, overrideRule as RuleOptions);\n if (!overrideRule) {\n const enabled = baseRule['enabled'] !== false;\n return new ResolvedRuleConfig(enabled, baseRule as RuleOptions);\n }\n // webpieces-disable no-any-unknown -- building merged option bag\n const merged: Record<string, unknown> = {};\n for (const key of Object.keys(baseRule)) merged[key] = baseRule[key];\n for (const key of Object.keys(overrideRule)) merged[key] = overrideRule[key];\n const enabled = merged['enabled'] !== false;\n return new ResolvedRuleConfig(enabled, merged as RuleOptions);\n}\n\nexport function loadConfig(cwd: string): ResolvedConfig {\n const configPath = findConfigFile(cwd);\n const defaultRules = loadDefaultConfig();\n\n if (!configPath) {\n return new ResolvedConfig(new Map(), [], null);\n }\n\n let consumerConfig: RawConfigFile;\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n const raw = fs.readFileSync(configPath, 'utf8');\n consumerConfig = JSON.parse(raw) as RawConfigFile;\n } catch (err: unknown) {\n // eslint-disable-next-line @webpieces/catch-error-pattern -- malformed config fails open\n void err;\n return new ResolvedConfig(new Map(), [], configPath);\n }\n\n const overrideRules = consumerConfig.rules || {};\n const mergedRules = new Map<string, ResolvedRuleConfig>();\n\n const allRuleNames = new Set([\n ...Object.keys(defaultRules),\n ...Object.keys(overrideRules),\n ]);\n for (const name of allRuleNames) {\n mergedRules.set(name, mergeRule(defaultRules[name], overrideRules[name]));\n }\n\n const baseDirs: string[] = [];\n const overrideDirs = consumerConfig.rulesDir || [];\n const rulesDir = [...baseDirs, ...overrideDirs];\n\n return new ResolvedConfig(mergedRules, rulesDir, configPath);\n}\n"]}
1
+ {"version":3,"file":"load-config.js","sourceRoot":"","sources":["../../../../../../packages/tooling/ai-hooks/src/core/load-config.ts"],"names":[],"mappings":";;;AAAA,sEAAsE;AACtE,6DAA6D;AAC7D,4CAAgF;AAAvE,oGAAA,UAAU,OAAA;AAAE,wGAAA,cAAc,OAAA;AAAE,yGAAA,eAAe,OAAA","sourcesContent":["// Re-export the shared workspace config loader so ai-hooks and the Nx\n// validate-code executor use the same webpieces.config.json.\nexport { loadConfig, findConfigFile, CONFIG_FILENAME } from '@webpieces/config';\n"]}
@@ -1,6 +1,7 @@
1
+ import { RuleOptions } from '@webpieces/config';
2
+ export { ResolvedConfig, ResolvedRuleConfig, RuleOptions } from '@webpieces/config';
1
3
  export type ToolKind = 'Write' | 'Edit' | 'MultiEdit';
2
4
  export type RuleScope = 'edit' | 'file';
3
- export type RuleOptions = Record<string, unknown>;
4
5
  export type IsLineDisabled = (lineNum: number, ruleName: string) => boolean;
5
6
  export declare class Violation {
6
7
  readonly line: number;
@@ -75,15 +76,3 @@ export declare class BlockedResult {
75
76
  readonly report: string;
76
77
  constructor(report: string);
77
78
  }
78
- export declare class ResolvedConfig {
79
- readonly rules: Map<string, ResolvedRuleConfig>;
80
- readonly rulesDir: readonly string[];
81
- readonly configPath: string | null;
82
- constructor(rules: Map<string, ResolvedRuleConfig>, rulesDir: readonly string[], configPath: string | null);
83
- }
84
- export declare class ResolvedRuleConfig {
85
- readonly enabled: boolean;
86
- readonly options: RuleOptions;
87
- constructor(enabled: boolean, options: RuleOptions);
88
- }
89
- export {};
package/src/core/types.js CHANGED
@@ -1,6 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ResolvedRuleConfig = exports.ResolvedConfig = exports.BlockedResult = exports.RuleGroup = exports.FileContext = exports.EditContext = exports.NormalizedToolInput = exports.NormalizedEdit = exports.Violation = void 0;
3
+ exports.BlockedResult = exports.RuleGroup = exports.FileContext = exports.EditContext = exports.NormalizedToolInput = exports.NormalizedEdit = exports.Violation = exports.ResolvedRuleConfig = exports.ResolvedConfig = void 0;
4
+ var config_1 = require("@webpieces/config");
5
+ Object.defineProperty(exports, "ResolvedConfig", { enumerable: true, get: function () { return config_1.ResolvedConfig; } });
6
+ Object.defineProperty(exports, "ResolvedRuleConfig", { enumerable: true, get: function () { return config_1.ResolvedRuleConfig; } });
4
7
  class Violation {
5
8
  constructor(line, snippet, message) {
6
9
  this.line = line;
@@ -72,19 +75,4 @@ class BlockedResult {
72
75
  }
73
76
  }
74
77
  exports.BlockedResult = BlockedResult;
75
- class ResolvedConfig {
76
- constructor(rules, rulesDir, configPath) {
77
- this.rules = rules;
78
- this.rulesDir = rulesDir;
79
- this.configPath = configPath;
80
- }
81
- }
82
- exports.ResolvedConfig = ResolvedConfig;
83
- class ResolvedRuleConfig {
84
- constructor(enabled, options) {
85
- this.enabled = enabled;
86
- this.options = options;
87
- }
88
- }
89
- exports.ResolvedRuleConfig = ResolvedRuleConfig;
90
78
  //# sourceMappingURL=types.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../../../packages/tooling/ai-hooks/src/core/types.ts"],"names":[],"mappings":"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","sourcesContent":["export type ToolKind = 'Write' | 'Edit' | 'MultiEdit';\nexport type RuleScope = 'edit' | 'file';\n// webpieces-disable no-any-unknown -- rule options are opaque at framework level; each rule casts internally\nexport type RuleOptions = Record<string, unknown>;\nexport type IsLineDisabled = (lineNum: number, ruleName: string) => boolean;\n\nexport class Violation {\n readonly line: number;\n readonly snippet: string;\n readonly message: string;\n editIndex: number | undefined;\n editCount: number | undefined;\n\n constructor(line: number, snippet: string, message: string) {\n this.line = line;\n this.snippet = snippet;\n this.message = message;\n this.editIndex = undefined;\n this.editCount = undefined;\n }\n}\n\nexport class NormalizedEdit {\n readonly oldString: string;\n readonly newString: string;\n\n constructor(oldString: string, newString: string) {\n this.oldString = oldString;\n this.newString = newString;\n }\n}\n\nexport class NormalizedToolInput {\n readonly filePath: string;\n readonly edits: readonly NormalizedEdit[];\n\n constructor(filePath: string, edits: readonly NormalizedEdit[]) {\n this.filePath = filePath;\n this.edits = edits;\n }\n}\n\nexport class EditContext {\n readonly tool: ToolKind;\n readonly editIndex: number;\n readonly editCount: number;\n readonly filePath: string;\n readonly relativePath: string;\n readonly workspaceRoot: string;\n readonly addedContent: string;\n readonly strippedContent: string;\n readonly lines: readonly string[];\n readonly strippedLines: readonly string[];\n readonly removedContent: string;\n readonly isLineDisabled: IsLineDisabled;\n options: RuleOptions;\n\n constructor(\n tool: ToolKind,\n editIndex: number,\n editCount: number,\n filePath: string,\n relativePath: string,\n workspaceRoot: string,\n addedContent: string,\n strippedContent: string,\n lines: readonly string[],\n strippedLines: readonly string[],\n removedContent: string,\n isLineDisabled: IsLineDisabled,\n ) {\n this.tool = tool;\n this.editIndex = editIndex;\n this.editCount = editCount;\n this.filePath = filePath;\n this.relativePath = relativePath;\n this.workspaceRoot = workspaceRoot;\n this.addedContent = addedContent;\n this.strippedContent = strippedContent;\n this.lines = lines;\n this.strippedLines = strippedLines;\n this.removedContent = removedContent;\n this.isLineDisabled = isLineDisabled;\n this.options = {};\n }\n}\n\nexport class FileContext {\n readonly tool: ToolKind;\n readonly filePath: string;\n readonly relativePath: string;\n readonly workspaceRoot: string;\n readonly currentFileLines: number;\n readonly linesAdded: number;\n readonly linesRemoved: number;\n readonly projectedFileLines: number;\n options: RuleOptions;\n\n constructor(\n tool: ToolKind,\n filePath: string,\n relativePath: string,\n workspaceRoot: string,\n currentFileLines: number,\n linesAdded: number,\n linesRemoved: number,\n projectedFileLines: number,\n ) {\n this.tool = tool;\n this.filePath = filePath;\n this.relativePath = relativePath;\n this.workspaceRoot = workspaceRoot;\n this.currentFileLines = currentFileLines;\n this.linesAdded = linesAdded;\n this.linesRemoved = linesRemoved;\n this.projectedFileLines = projectedFileLines;\n this.options = {};\n }\n}\n\ninterface RuleBase {\n readonly name: string;\n readonly description: string;\n readonly files: readonly string[];\n readonly defaultOptions: RuleOptions;\n readonly fixHint: readonly string[];\n}\n\nexport interface EditRule extends RuleBase {\n readonly scope: 'edit';\n check(ctx: EditContext): readonly Violation[];\n}\n\nexport interface FileRule extends RuleBase {\n readonly scope: 'file';\n check(ctx: FileContext): readonly Violation[];\n}\n\nexport type Rule = EditRule | FileRule;\n\nexport class RuleGroup {\n readonly ruleName: string;\n readonly ruleDescription: string;\n readonly fixHint: readonly string[];\n readonly violations: readonly Violation[];\n\n constructor(\n ruleName: string,\n ruleDescription: string,\n fixHint: readonly string[],\n violations: readonly Violation[],\n ) {\n this.ruleName = ruleName;\n this.ruleDescription = ruleDescription;\n this.fixHint = fixHint;\n this.violations = violations;\n }\n}\n\nexport class BlockedResult {\n readonly report: string;\n\n constructor(report: string) {\n this.report = report;\n }\n}\n\nexport class ResolvedConfig {\n readonly rules: Map<string, ResolvedRuleConfig>;\n readonly rulesDir: readonly string[];\n readonly configPath: string | null;\n\n constructor(\n rules: Map<string, ResolvedRuleConfig>,\n rulesDir: readonly string[],\n configPath: string | null,\n ) {\n this.rules = rules;\n this.rulesDir = rulesDir;\n this.configPath = configPath;\n }\n}\n\nexport class ResolvedRuleConfig {\n readonly enabled: boolean;\n readonly options: RuleOptions;\n\n constructor(enabled: boolean, options: RuleOptions) {\n this.enabled = enabled;\n this.options = options;\n }\n}\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../../../packages/tooling/ai-hooks/src/core/types.ts"],"names":[],"mappings":"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","sourcesContent":["// ResolvedConfig / ResolvedRuleConfig / RuleOptions now live in @webpieces/config\n// so ai-hooks and the Nx validate-code executor share one loader and one config file.\nimport { RuleOptions } from '@webpieces/config';\nexport { ResolvedConfig, ResolvedRuleConfig, RuleOptions } from '@webpieces/config';\n\nexport type ToolKind = 'Write' | 'Edit' | 'MultiEdit';\nexport type RuleScope = 'edit' | 'file';\nexport type IsLineDisabled = (lineNum: number, ruleName: string) => boolean;\n\nexport class Violation {\n readonly line: number;\n readonly snippet: string;\n readonly message: string;\n editIndex: number | undefined;\n editCount: number | undefined;\n\n constructor(line: number, snippet: string, message: string) {\n this.line = line;\n this.snippet = snippet;\n this.message = message;\n this.editIndex = undefined;\n this.editCount = undefined;\n }\n}\n\nexport class NormalizedEdit {\n readonly oldString: string;\n readonly newString: string;\n\n constructor(oldString: string, newString: string) {\n this.oldString = oldString;\n this.newString = newString;\n }\n}\n\nexport class NormalizedToolInput {\n readonly filePath: string;\n readonly edits: readonly NormalizedEdit[];\n\n constructor(filePath: string, edits: readonly NormalizedEdit[]) {\n this.filePath = filePath;\n this.edits = edits;\n }\n}\n\nexport class EditContext {\n readonly tool: ToolKind;\n readonly editIndex: number;\n readonly editCount: number;\n readonly filePath: string;\n readonly relativePath: string;\n readonly workspaceRoot: string;\n readonly addedContent: string;\n readonly strippedContent: string;\n readonly lines: readonly string[];\n readonly strippedLines: readonly string[];\n readonly removedContent: string;\n readonly isLineDisabled: IsLineDisabled;\n options: RuleOptions;\n\n constructor(\n tool: ToolKind,\n editIndex: number,\n editCount: number,\n filePath: string,\n relativePath: string,\n workspaceRoot: string,\n addedContent: string,\n strippedContent: string,\n lines: readonly string[],\n strippedLines: readonly string[],\n removedContent: string,\n isLineDisabled: IsLineDisabled,\n ) {\n this.tool = tool;\n this.editIndex = editIndex;\n this.editCount = editCount;\n this.filePath = filePath;\n this.relativePath = relativePath;\n this.workspaceRoot = workspaceRoot;\n this.addedContent = addedContent;\n this.strippedContent = strippedContent;\n this.lines = lines;\n this.strippedLines = strippedLines;\n this.removedContent = removedContent;\n this.isLineDisabled = isLineDisabled;\n this.options = {};\n }\n}\n\nexport class FileContext {\n readonly tool: ToolKind;\n readonly filePath: string;\n readonly relativePath: string;\n readonly workspaceRoot: string;\n readonly currentFileLines: number;\n readonly linesAdded: number;\n readonly linesRemoved: number;\n readonly projectedFileLines: number;\n options: RuleOptions;\n\n constructor(\n tool: ToolKind,\n filePath: string,\n relativePath: string,\n workspaceRoot: string,\n currentFileLines: number,\n linesAdded: number,\n linesRemoved: number,\n projectedFileLines: number,\n ) {\n this.tool = tool;\n this.filePath = filePath;\n this.relativePath = relativePath;\n this.workspaceRoot = workspaceRoot;\n this.currentFileLines = currentFileLines;\n this.linesAdded = linesAdded;\n this.linesRemoved = linesRemoved;\n this.projectedFileLines = projectedFileLines;\n this.options = {};\n }\n}\n\ninterface RuleBase {\n readonly name: string;\n readonly description: string;\n readonly files: readonly string[];\n readonly defaultOptions: RuleOptions;\n readonly fixHint: readonly string[];\n}\n\nexport interface EditRule extends RuleBase {\n readonly scope: 'edit';\n check(ctx: EditContext): readonly Violation[];\n}\n\nexport interface FileRule extends RuleBase {\n readonly scope: 'file';\n check(ctx: FileContext): readonly Violation[];\n}\n\nexport type Rule = EditRule | FileRule;\n\nexport class RuleGroup {\n readonly ruleName: string;\n readonly ruleDescription: string;\n readonly fixHint: readonly string[];\n readonly violations: readonly Violation[];\n\n constructor(\n ruleName: string,\n ruleDescription: string,\n fixHint: readonly string[],\n violations: readonly Violation[],\n ) {\n this.ruleName = ruleName;\n this.ruleDescription = ruleDescription;\n this.fixHint = fixHint;\n this.violations = violations;\n }\n}\n\nexport class BlockedResult {\n readonly report: string;\n\n constructor(report: string) {\n this.report = report;\n }\n}\n\n"]}