@webpieces/ai-hook-rules 0.3.159 → 0.3.161

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 (43) hide show
  1. package/bin/wp-ai-hook.js +16 -0
  2. package/bin/wp-dev-hook-install.js +16 -0
  3. package/bin/wp-dev-hook-uninstall.js +16 -0
  4. package/bin/wp-setup-ai-hooks.js +1 -1
  5. package/bin/wp-setup-global-ai-hooks.js +16 -0
  6. package/package.json +6 -5
  7. package/src/adapters/claude-code-hook.js +8 -4
  8. package/src/adapters/claude-code-hook.js.map +1 -1
  9. package/src/adapters/global-hook.d.ts +1 -0
  10. package/src/adapters/global-hook.js +76 -0
  11. package/src/adapters/global-hook.js.map +1 -0
  12. package/src/adapters/openclaw-plugin.js +4 -2
  13. package/src/adapters/openclaw-plugin.js.map +1 -1
  14. package/src/bin/{postinstall.d.ts → dev-hook-install.d.ts} +0 -1
  15. package/src/bin/dev-hook-install.js +54 -0
  16. package/src/bin/dev-hook-install.js.map +1 -0
  17. package/src/bin/dev-hook-uninstall.d.ts +1 -0
  18. package/src/bin/dev-hook-uninstall.js +34 -0
  19. package/src/bin/dev-hook-uninstall.js.map +1 -0
  20. package/src/bin/global-setup.d.ts +1 -0
  21. package/src/bin/global-setup.js +60 -0
  22. package/src/bin/global-setup.js.map +1 -0
  23. package/src/bin/setup.d.ts +1 -0
  24. package/src/bin/setup.js +102 -0
  25. package/src/bin/setup.js.map +1 -0
  26. package/src/core/load-rules.js +5 -3
  27. package/src/core/load-rules.js.map +1 -1
  28. package/src/core/rules/index.js +1 -0
  29. package/src/core/rules/index.js.map +1 -1
  30. package/src/core/rules/no-js-files.d.ts +3 -0
  31. package/src/core/rules/no-js-files.js +29 -0
  32. package/src/core/rules/no-js-files.js.map +1 -0
  33. package/src/core/rules/validate-ts-in-src.js +0 -1
  34. package/src/core/rules/validate-ts-in-src.js.map +1 -1
  35. package/src/core/runner.js +40 -50
  36. package/src/core/runner.js.map +1 -1
  37. package/src/core/types.d.ts +1 -1
  38. package/src/core/types.js +2 -1
  39. package/src/core/types.js.map +1 -1
  40. package/templates/claude-settings-hook.json +1 -1
  41. package/bin/postinstall.js +0 -15
  42. package/src/bin/postinstall.js +0 -106
  43. package/src/bin/postinstall.js.map +0 -1
@@ -1,106 +0,0 @@
1
- #!/usr/bin/env node
2
- "use strict";
3
- Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.main = main;
5
- const tslib_1 = require("tslib");
6
- const fs = tslib_1.__importStar(require("fs"));
7
- const path = tslib_1.__importStar(require("path"));
8
- const BRIDGE_CONTENT = `#!/usr/bin/env node\nrequire('@webpieces/ai-hook-rules/claude-code').main();\n`;
9
- function findProjectRoot() {
10
- // Walk up from this file's location to escape node_modules
11
- // e.g. /project/node_modules/@webpieces/ai-hook-rules/src/bin/postinstall.js -> /project
12
- let dir = __dirname;
13
- while (dir !== path.dirname(dir)) {
14
- dir = path.dirname(dir);
15
- const base = path.basename(dir);
16
- if (base === 'node_modules') {
17
- return path.dirname(dir);
18
- }
19
- }
20
- return null;
21
- }
22
- function createBridgeFile(projectRoot) {
23
- const hooksDir = path.join(projectRoot, '.webpieces', 'ai-hooks');
24
- const bridgePath = path.join(hooksDir, 'claude-code-hook.js');
25
- fs.mkdirSync(hooksDir, { recursive: true });
26
- fs.writeFileSync(bridgePath, BRIDGE_CONTENT);
27
- fs.chmodSync(bridgePath, 0o755);
28
- console.log(' [ai-hook-rules] Created .webpieces/ai-hooks/claude-code-hook.js');
29
- }
30
- function seedConfigIfMissing(projectRoot) {
31
- const configPath = path.join(projectRoot, 'webpieces.config.json');
32
- if (fs.existsSync(configPath))
33
- return;
34
- const templatePath = path.join(__dirname, '..', '..', 'templates', 'webpieces.config.seed.json');
35
- if (!fs.existsSync(templatePath))
36
- return;
37
- fs.copyFileSync(templatePath, configPath);
38
- console.log(' [ai-hook-rules] Created webpieces.config.json (default config)');
39
- }
40
- function settingsAlreadyHasHook(settingsPath) {
41
- if (!fs.existsSync(settingsPath))
42
- return false;
43
- const content = fs.readFileSync(settingsPath, 'utf8');
44
- return content.includes('claude-code-hook.js');
45
- }
46
- function loadTemplate() {
47
- const templatePath = path.join(__dirname, '..', '..', 'templates', 'claude-settings-hook.json');
48
- const raw = fs.readFileSync(templatePath, 'utf8');
49
- return JSON.parse(raw);
50
- }
51
- function mergeHookIntoSettings(settingsPath) {
52
- const template = loadTemplate();
53
- const hookEntry = template.hooks.PreToolUse[0];
54
- let settings = {};
55
- if (fs.existsSync(settingsPath)) {
56
- settings = JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
57
- }
58
- if (!settings.hooks) {
59
- settings.hooks = {};
60
- }
61
- if (!Array.isArray(settings.hooks.PreToolUse)) {
62
- settings.hooks.PreToolUse = [];
63
- }
64
- settings.hooks.PreToolUse.push(hookEntry);
65
- fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 4) + '\n');
66
- }
67
- function backupSettings(settingsPath) {
68
- if (fs.existsSync(settingsPath)) {
69
- const bakPath = settingsPath + '.bak';
70
- fs.copyFileSync(settingsPath, bakPath);
71
- console.log(' [ai-hook-rules] Backed up .claude/settings.json to .claude/settings.json.bak');
72
- }
73
- }
74
- function setupSettings(settingsPath) {
75
- // pnpm hides all postinstall output, so no point prompting or logging.
76
- // The user already consented by running `pnpm approve-builds`.
77
- backupSettings(settingsPath);
78
- mergeHookIntoSettings(settingsPath);
79
- }
80
- function main() {
81
- const projectRoot = findProjectRoot();
82
- if (!projectRoot) {
83
- // Not running from node_modules (maybe local dev / workspace) — skip
84
- return;
85
- }
86
- // 1. Always create the bridge file
87
- createBridgeFile(projectRoot);
88
- // 2. Seed config if missing
89
- seedConfigIfMissing(projectRoot);
90
- // 3. Check if .claude/ exists — if not, skip settings.json
91
- const claudeDir = path.join(projectRoot, '.claude');
92
- if (!fs.existsSync(claudeDir)) {
93
- return;
94
- }
95
- // 4. Check if settings.json already has the hook — if yes, done
96
- const settingsPath = path.join(claudeDir, 'settings.json');
97
- if (settingsAlreadyHasHook(settingsPath)) {
98
- return;
99
- }
100
- // 5. Backup and add the hook (user consented via pnpm approve-builds)
101
- setupSettings(settingsPath);
102
- }
103
- if (require.main === module) {
104
- main();
105
- }
106
- //# sourceMappingURL=postinstall.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"postinstall.js","sourceRoot":"","sources":["../../../../../../packages/tooling/ai-hook-rules/src/bin/postinstall.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\nimport * as fs from 'fs';\nimport * as path from 'path';\n\nconst BRIDGE_CONTENT = `#!/usr/bin/env node\\nrequire('@webpieces/ai-hook-rules/claude-code').main();\\n`;\n\nfunction findProjectRoot(): string | null {\n // Walk up from this file's location to escape node_modules\n // e.g. /project/node_modules/@webpieces/ai-hook-rules/src/bin/postinstall.js -> /project\n let dir = __dirname;\n while (dir !== path.dirname(dir)) {\n dir = path.dirname(dir);\n const base = path.basename(dir);\n if (base === 'node_modules') {\n return path.dirname(dir);\n }\n }\n return null;\n}\n\nfunction createBridgeFile(projectRoot: string): void {\n const hooksDir = path.join(projectRoot, '.webpieces', 'ai-hooks');\n const bridgePath = path.join(hooksDir, 'claude-code-hook.js');\n\n fs.mkdirSync(hooksDir, { recursive: true });\n fs.writeFileSync(bridgePath, BRIDGE_CONTENT);\n fs.chmodSync(bridgePath, 0o755);\n console.log(' [ai-hook-rules] Created .webpieces/ai-hooks/claude-code-hook.js');\n}\n\nfunction seedConfigIfMissing(projectRoot: string): void {\n const configPath = path.join(projectRoot, 'webpieces.config.json');\n if (fs.existsSync(configPath)) return;\n\n const templatePath = path.join(__dirname, '..', '..', 'templates', 'webpieces.config.seed.json');\n if (!fs.existsSync(templatePath)) return;\n\n fs.copyFileSync(templatePath, configPath);\n console.log(' [ai-hook-rules] Created webpieces.config.json (default config)');\n}\n\nfunction settingsAlreadyHasHook(settingsPath: string): boolean {\n if (!fs.existsSync(settingsPath)) return false;\n\n const content = fs.readFileSync(settingsPath, 'utf8');\n return content.includes('claude-code-hook.js');\n}\n\ninterface HookEntry {\n matcher: string;\n hooks: Array<{ type: string; command: string }>;\n}\n\ninterface SettingsTemplate {\n hooks: {\n PreToolUse: HookEntry[];\n };\n}\n\ninterface ClaudeSettings {\n hooks?: {\n PreToolUse?: HookEntry[];\n };\n [key: string]: string | number | boolean | object | null | undefined;\n}\n\nfunction loadTemplate(): SettingsTemplate {\n const templatePath = path.join(__dirname, '..', '..', 'templates', 'claude-settings-hook.json');\n const raw = fs.readFileSync(templatePath, 'utf8');\n return JSON.parse(raw) as SettingsTemplate;\n}\n\nfunction mergeHookIntoSettings(settingsPath: string): void {\n const template = loadTemplate();\n const hookEntry = template.hooks.PreToolUse[0];\n\n let settings: ClaudeSettings = {};\n if (fs.existsSync(settingsPath)) {\n settings = JSON.parse(fs.readFileSync(settingsPath, 'utf8')) as ClaudeSettings;\n }\n\n if (!settings.hooks) {\n settings.hooks = {};\n }\n if (!Array.isArray(settings.hooks.PreToolUse)) {\n settings.hooks.PreToolUse = [];\n }\n\n settings.hooks.PreToolUse.push(hookEntry);\n fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 4) + '\\n');\n}\n\nfunction backupSettings(settingsPath: string): void {\n if (fs.existsSync(settingsPath)) {\n const bakPath = settingsPath + '.bak';\n fs.copyFileSync(settingsPath, bakPath);\n console.log(' [ai-hook-rules] Backed up .claude/settings.json to .claude/settings.json.bak');\n }\n}\n\n\nfunction setupSettings(settingsPath: string): void {\n // pnpm hides all postinstall output, so no point prompting or logging.\n // The user already consented by running `pnpm approve-builds`.\n backupSettings(settingsPath);\n mergeHookIntoSettings(settingsPath);\n}\n\nexport function main(): void {\n const projectRoot = findProjectRoot();\n if (!projectRoot) {\n // Not running from node_modules (maybe local dev / workspace) — skip\n return;\n }\n\n // 1. Always create the bridge file\n createBridgeFile(projectRoot);\n\n // 2. Seed config if missing\n seedConfigIfMissing(projectRoot);\n\n // 3. Check if .claude/ exists — if not, skip settings.json\n const claudeDir = path.join(projectRoot, '.claude');\n if (!fs.existsSync(claudeDir)) {\n return;\n }\n\n // 4. Check if settings.json already has the hook — if yes, done\n const settingsPath = path.join(claudeDir, 'settings.json');\n if (settingsAlreadyHasHook(settingsPath)) {\n return;\n }\n\n // 5. Backup and add the hook (user consented via pnpm approve-builds)\n setupSettings(settingsPath);\n}\n\nif (require.main === module) {\n main();\n}\n"]}