@webpieces/ai-hook-rules 0.4.710 → 0.4.712

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 (59) hide show
  1. package/package.json +2 -2
  2. package/src/adapters/detect-ai.d.ts +5 -4
  3. package/src/adapters/detect-ai.js +5 -4
  4. package/src/adapters/detect-ai.js.map +1 -1
  5. package/src/adapters/hook-core.js +9 -3
  6. package/src/adapters/hook-core.js.map +1 -1
  7. package/src/bin/codex-guard-presence.d.ts +86 -0
  8. package/src/bin/codex-guard-presence.js +150 -0
  9. package/src/bin/codex-guard-presence.js.map +1 -0
  10. package/src/bin/codex-trust.d.ts +99 -0
  11. package/src/bin/codex-trust.js +199 -0
  12. package/src/bin/codex-trust.js.map +1 -0
  13. package/src/bin/hook-registration.d.ts +200 -43
  14. package/src/bin/hook-registration.js +218 -89
  15. package/src/bin/hook-registration.js.map +1 -1
  16. package/src/bin/l0-allowlist.d.ts +0 -30
  17. package/src/bin/l0-allowlist.js +9 -67
  18. package/src/bin/l0-allowlist.js.map +1 -1
  19. package/src/bin/l0-decide.d.ts +43 -0
  20. package/src/bin/l0-decide.js +90 -0
  21. package/src/bin/l0-decide.js.map +1 -0
  22. package/src/bin/l0-ignored-tools.d.ts +38 -0
  23. package/src/bin/l0-ignored-tools.js +44 -0
  24. package/src/bin/l0-ignored-tools.js.map +1 -0
  25. package/src/bin/setup-config.d.ts +19 -0
  26. package/src/bin/setup-config.js +370 -0
  27. package/src/bin/setup-config.js.map +1 -0
  28. package/src/bin/setup.d.ts +56 -21
  29. package/src/bin/setup.js +125 -370
  30. package/src/bin/setup.js.map +1 -1
  31. package/src/bin/shim-audit-log.js +10 -1
  32. package/src/bin/shim-audit-log.js.map +1 -1
  33. package/src/bin/shim-deny-reason.js +4 -4
  34. package/src/bin/shim-deny-reason.js.map +1 -1
  35. package/src/bin/shim.d.ts +2 -0
  36. package/src/bin/shim.js +21 -1
  37. package/src/bin/shim.js.map +1 -1
  38. package/src/bin/upgrade-shim.d.ts +1 -1
  39. package/src/bin/upgrade-shim.js +12 -8
  40. package/src/bin/upgrade-shim.js.map +1 -1
  41. package/src/core/agent-event.d.ts +16 -0
  42. package/src/core/agent-event.js +17 -1
  43. package/src/core/agent-event.js.map +1 -1
  44. package/src/core/ai-type-context.d.ts +36 -0
  45. package/src/core/ai-type-context.js +45 -0
  46. package/src/core/ai-type-context.js.map +1 -0
  47. package/src/core/decision-log.js +9 -0
  48. package/src/core/decision-log.js.map +1 -1
  49. package/src/core/l0-matrix.js +14 -6
  50. package/src/core/l0-matrix.js.map +1 -1
  51. package/src/core/l0-tooling-doc.d.ts +3 -2
  52. package/src/core/l0-tooling-doc.js +22 -10
  53. package/src/core/l0-tooling-doc.js.map +1 -1
  54. package/src/core/rejection-log.js +5 -1
  55. package/src/core/rejection-log.js.map +1 -1
  56. package/src/index.d.ts +1 -1
  57. package/src/index.js +4 -1
  58. package/src/index.js.map +1 -1
  59. package/templates/ai-hook.sh +15 -1
@@ -1,10 +1,18 @@
1
- import { ClaudeSettings } from './hook-registration';
1
+ import { ClaudeSettings, HarnessRegistration } from './hook-registration';
2
2
  declare class HookSpec {
3
3
  readonly key: string;
4
4
  readonly label: string;
5
- readonly matcher: string;
6
5
  readonly bin: string;
7
- constructor(key: string, label: string, matcher: string, bin: string);
6
+ constructor(key: string, label: string, bin: string);
7
+ /**
8
+ * WHICH TOOL NAMES this hook must see, in the harness the target belongs to.
9
+ *
10
+ * It is a lookup on the target rather than a field on the spec because the answer is not a property
11
+ * of the hook: the rules hook matches `Write|Edit|MultiEdit` under Claude Code and `apply_patch`
12
+ * under Codex, and a single stored matcher is exactly how `.codex/hooks.json` came to be registered
13
+ * against tool names Codex never emits.
14
+ */
15
+ matcherFor(target: InstallTarget): string;
8
16
  commandFor(target: InstallTarget, projectRoot: string): string;
9
17
  }
10
18
  export declare class InstallTarget {
@@ -12,31 +20,58 @@ export declare class InstallTarget {
12
20
  readonly label: string;
13
21
  readonly settingsPath: string;
14
22
  readonly absolute: boolean;
15
- constructor(choice: string, label: string, settingsPath: string, absolute: boolean);
23
+ /**
24
+ * WHICH HARNESS this file arms — it decides the matcher and the shim anchor written into it.
25
+ *
26
+ * REQUIRED, with no default, and the absence of one is the point. A default of
27
+ * CLAUDE_REGISTRATION would make "omit the harness" mean "Claude Code" — a widening that is an
28
+ * ABSENCE rather than a token, so a target built for Codex without it would silently carry
29
+ * `Write|Edit|MultiEdit` and `$CLAUDE_PROJECT_DIR`, which is EXACTLY the silently-unguarded
30
+ * state this class exists to end, and ungreppable besides.
31
+ */
32
+ readonly harness: HarnessRegistration;
33
+ constructor(choice: string, label: string, settingsPath: string, absolute: boolean,
34
+ /**
35
+ * WHICH HARNESS this file arms — it decides the matcher and the shim anchor written into it.
36
+ *
37
+ * REQUIRED, with no default, and the absence of one is the point. A default of
38
+ * CLAUDE_REGISTRATION would make "omit the harness" mean "Claude Code" — a widening that is an
39
+ * ABSENCE rather than a token, so a target built for Codex without it would silently carry
40
+ * `Write|Edit|MultiEdit` and `$CLAUDE_PROJECT_DIR`, which is EXACTLY the silently-unguarded
41
+ * state this class exists to end, and ungreppable besides.
42
+ */
43
+ harness: HarnessRegistration);
16
44
  }
17
45
  export declare const RULES_HOOK: HookSpec;
18
46
  export declare const GUARDS_HOOK: HookSpec;
47
+ /**
48
+ * Every file the installer can write, keyed by the CHOICE a human makes.
49
+ *
50
+ * TWO TARGETS SHARE CHOICE `1`, and that is the design rather than an oversight: "the project, committed,
51
+ * for the team" is ONE intention, and a repo that is worked on by both harnesses needs both files armed
52
+ * to mean it. Splitting it into two questions would let a human answer them differently and end up with a
53
+ * repo where Codex is silently unguarded — which is the state this whole change exists to end. Every
54
+ * caller selects by choice id (`targets.filter(t => t.choice === answer)`), never by index, so adding a
55
+ * harness adds a row and changes no numbering.
56
+ *
57
+ * `2` (personal) and `3` (global) stay Claude-only because neither has a Codex counterpart: Codex reads
58
+ * one repo-local `hooks.json` and has no personal or home-scoped hook file.
59
+ *
60
+ * `homeDir` is injectable so tests can point the global target at a temp dir instead of the real
61
+ * ~/.claude/settings.json (a unit test must never write the user's actual global settings).
62
+ */
19
63
  export declare function installTargets(projectRoot: string, homeDir?: string): InstallTarget[];
20
- type Json = Record<string, unknown>;
21
- type RuleEntry = Json;
22
- type Section = Record<string, RuleEntry>;
23
- interface ConfigFile {
24
- extends?: string;
25
- rules: Section;
26
- hookGuards: Section;
27
- commands: Json;
28
- excludePaths: string[];
29
- 'match-rules': Json[];
30
- rulesDir: string[];
31
- }
32
- interface MigrateResult {
33
- config: ConfigFile;
34
- changes: string[];
35
- }
36
- export declare function migrate(existing: Json): MigrateResult;
37
64
  export declare function hasHook(settings: ClaudeSettings, bin: string): boolean;
38
65
  export declare function applyHook(hook: HookSpec, chosen: InstallTarget | null, targets: InstallTarget[], projectRoot: string): void;
39
66
  export declare function resolveTargetChoice(name: string): string | null;
40
67
  export declare function parseTargetArg(args: string[]): string | null;
68
+ /**
69
+ * Apply ONE choice for one hook: every target that answer selects, or uninstall when it selects none.
70
+ *
71
+ * The loop is what lets one choice arm several harnesses (choice `1` writes both the Claude settings
72
+ * file and the Codex hooks file — see installTargets). `applyHook` scopes its removals to the chosen
73
+ * target's harness, which is what keeps these calls from undoing one another.
74
+ */
75
+ export declare function applyChoice(hook: HookSpec, choice: string, targets: InstallTarget[], projectRoot: string): void;
41
76
  export declare function main(): Promise<void>;
42
77
  export {};