failproofai 0.0.2-beta.5 → 0.0.2-beta.7

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 (159) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/build-manifest.json +5 -5
  3. package/.next/standalone/.next/prerender-manifest.json +3 -3
  4. package/.next/standalone/.next/required-server-files.json +1 -1
  5. package/.next/standalone/.next/server/app/_global-error/page/build-manifest.json +2 -2
  6. package/.next/standalone/.next/server/app/_global-error/page/server-reference-manifest.json +1 -1
  7. package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
  8. package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  9. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  10. package/.next/standalone/.next/server/app/_global-error.rsc +7 -7
  11. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +2 -2
  12. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
  13. package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +3 -3
  14. package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +3 -3
  15. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  16. package/.next/standalone/.next/server/app/_not-found/page/build-manifest.json +2 -2
  17. package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  18. package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  19. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  20. package/.next/standalone/.next/server/app/_not-found.html +2 -2
  21. package/.next/standalone/.next/server/app/_not-found.rsc +15 -15
  22. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +15 -15
  23. package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +4 -4
  24. package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +10 -10
  25. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
  26. package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
  27. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  28. package/.next/standalone/.next/server/app/index.html +1 -1
  29. package/.next/standalone/.next/server/app/index.rsc +15 -15
  30. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  31. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +15 -15
  32. package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +4 -4
  33. package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +10 -10
  34. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  35. package/.next/standalone/.next/server/app/page/build-manifest.json +2 -2
  36. package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
  37. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  38. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  39. package/.next/standalone/.next/server/app/policies/page/build-manifest.json +2 -2
  40. package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +8 -8
  41. package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
  42. package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
  43. package/.next/standalone/.next/server/app/project/[name]/page/build-manifest.json +2 -2
  44. package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
  45. package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
  46. package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
  47. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/build-manifest.json +2 -2
  48. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
  49. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
  50. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
  51. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
  52. package/.next/standalone/.next/server/app/projects/page/build-manifest.json +2 -2
  53. package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
  54. package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
  55. package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  56. package/.next/standalone/.next/server/chunks/[root-of-the-server]__02nt~6d._.js +1 -1
  57. package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_05pz9._._.js +1 -1
  58. package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_0z7w.hh._.js +1 -1
  59. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__00_.atk._.js → [root-of-the-server]__05zi2mt._.js} +2 -2
  60. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__092s1ta._.js +2 -2
  61. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__09icjsf._.js +2 -2
  62. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0g.lg8b._.js +2 -2
  63. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0h..k-e._.js +2 -2
  64. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0gw4qdj._.js → [root-of-the-server]__0kkt_9z._.js} +2 -2
  65. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0okos0k._.js +2 -2
  66. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0w6l33k._.js +8 -9
  67. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__11pa2ra._.js +2 -2
  68. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__12t-wym._.js +2 -2
  69. package/.next/standalone/.next/server/chunks/ssr/_10lm7or._.js +2 -2
  70. package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_0xerkr6._.js +1 -1
  71. package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_0q-m0y-._.js +1 -1
  72. package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0a_7sdg.js +2 -2
  73. package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0ef3uwk.js +2 -2
  74. package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0j79~gv.js +2 -2
  75. package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0pbja1x.js +2 -2
  76. package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0r6o0i2.js +2 -2
  77. package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_11y81~_.js +2 -2
  78. package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_12or2kf.js +2 -2
  79. package/.next/standalone/.next/server/chunks/ssr/node_modules_posthog-node_dist_entrypoints_index_node_mjs_0mebn66._.js +1 -1
  80. package/.next/standalone/.next/server/middleware-build-manifest.js +5 -5
  81. package/.next/standalone/.next/server/pages/404.html +2 -2
  82. package/.next/standalone/.next/server/pages/500.html +1 -1
  83. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  84. package/.next/standalone/.next/server/server-reference-manifest.json +9 -9
  85. package/.next/standalone/.next/static/chunks/{0issdwvmb81z_.js → 02u4v.k5amfah.js} +1 -1
  86. package/.next/standalone/.next/static/chunks/{031pa5~qfzt~_.js → 09e7drilkf1sn.js} +1 -1
  87. package/.next/standalone/.next/static/chunks/{14ee68i9dy9b3.js → 0bkizbynk9via.js} +1 -1
  88. package/.next/standalone/.next/static/chunks/{0gleuaabeolm~.js → 0e76l4~hq_sei.js} +1 -1
  89. package/.next/standalone/.next/static/chunks/{0odv81fzkn6u~.js → 0ltx5i0xv85_s.js} +1 -1
  90. package/.next/standalone/.next/static/chunks/{040il49xqyq~j.js → 0q7atesxo-36k.js} +1 -1
  91. package/.next/standalone/.next/static/chunks/{0ezymnwrt2x6i.js → 0suauczjqzn07.js} +1 -1
  92. package/.next/standalone/.next/static/chunks/{0d-hv1uc827s6.js → 0w.rtg9.m8dk-.js} +2 -2
  93. package/.next/standalone/.next/static/chunks/{10uhv8kh~ad6m.js → 13jdpvk~s2da8.js} +1 -1
  94. package/.next/standalone/.next/static/chunks/{turbopack-0uc5y~g6h.n7-.js → turbopack-0r26pc8h0y_-e.js} +1 -1
  95. package/.next/standalone/CHANGELOG.md +74 -0
  96. package/.next/standalone/CLAUDE.md +14 -0
  97. package/.next/standalone/README.md +20 -3
  98. package/.next/standalone/bin/failproofai.mjs +5 -0
  99. package/.next/standalone/bun.lock +31 -63
  100. package/.next/standalone/dist/cli.mjs +261 -61
  101. package/.next/standalone/docs/built-in-policies.mdx +2 -2
  102. package/.next/standalone/docs/configuration.mdx +46 -0
  103. package/.next/standalone/docs/custom-policies.mdx +63 -5
  104. package/.next/standalone/docs/docs.json +3 -3
  105. package/.next/standalone/examples/convention-policies/security-policies.mjs +40 -0
  106. package/.next/standalone/examples/convention-policies/workflow-policies.mjs +41 -0
  107. package/.next/standalone/node_modules/@next/env/package.json +1 -1
  108. package/.next/standalone/node_modules/next/dist/build/swc/index.js +1 -1
  109. package/.next/standalone/node_modules/next/dist/compiled/jsonwebtoken/index.js +2 -2
  110. package/.next/standalone/node_modules/next/dist/compiled/next-server/app-page-turbo-experimental.runtime.prod.js +1 -1
  111. package/.next/standalone/node_modules/next/dist/compiled/next-server/app-page-turbo.runtime.prod.js +1 -1
  112. package/.next/standalone/node_modules/next/dist/compiled/next-server/pages-turbo.runtime.prod.js +1 -1
  113. package/.next/standalone/node_modules/next/dist/lib/patch-incorrect-lockfile.js +3 -3
  114. package/.next/standalone/node_modules/next/dist/server/config.js +1 -1
  115. package/.next/standalone/node_modules/next/dist/server/dev/hot-reloader-turbopack.js +7 -2
  116. package/.next/standalone/node_modules/next/dist/server/dev/hot-reloader-webpack.js +1 -1
  117. package/.next/standalone/node_modules/next/dist/server/lib/app-info-log.js +1 -1
  118. package/.next/standalone/node_modules/next/dist/server/lib/start-server.js +1 -1
  119. package/.next/standalone/node_modules/next/dist/server/render.js +20 -19
  120. package/.next/standalone/node_modules/next/dist/shared/lib/errors/canary-only-config-error.js +1 -1
  121. package/.next/standalone/node_modules/next/dist/telemetry/anonymous-meta.js +1 -1
  122. package/.next/standalone/node_modules/next/dist/telemetry/events/swc-load-failure.js +1 -1
  123. package/.next/standalone/node_modules/next/dist/telemetry/events/version.js +2 -2
  124. package/.next/standalone/node_modules/next/package.json +15 -15
  125. package/.next/standalone/node_modules/react/cjs/react.development.js +1 -1
  126. package/.next/standalone/node_modules/react/cjs/react.production.js +1 -1
  127. package/.next/standalone/node_modules/react/package.json +1 -1
  128. package/.next/standalone/node_modules/react-dom/cjs/react-dom-server-legacy.browser.production.js +1 -1
  129. package/.next/standalone/node_modules/react-dom/cjs/react-dom-server-legacy.node.production.js +1 -1
  130. package/.next/standalone/node_modules/react-dom/cjs/react-dom-server.browser.production.js +3 -3
  131. package/.next/standalone/node_modules/react-dom/cjs/react-dom-server.edge.production.js +3 -3
  132. package/.next/standalone/node_modules/react-dom/cjs/react-dom-server.node.production.js +3 -3
  133. package/.next/standalone/node_modules/react-dom/cjs/react-dom.production.js +1 -1
  134. package/.next/standalone/node_modules/react-dom/package.json +2 -2
  135. package/.next/standalone/package.json +1 -1
  136. package/.next/standalone/server.js +1 -1
  137. package/.next/standalone/src/hooks/builtin-policies.ts +110 -18
  138. package/.next/standalone/src/hooks/custom-hooks-loader.ts +158 -21
  139. package/.next/standalone/src/hooks/handler.ts +26 -6
  140. package/.next/standalone/src/hooks/hooks-config.ts +47 -2
  141. package/.next/standalone/src/hooks/llm-client.ts +2 -2
  142. package/.next/standalone/src/hooks/loader-utils.ts +4 -4
  143. package/.next/standalone/src/hooks/manager.ts +57 -14
  144. package/.next/standalone/src/hooks/policy-evaluator.ts +16 -2
  145. package/README.md +20 -3
  146. package/bin/failproofai.mjs +5 -0
  147. package/dist/cli.mjs +261 -61
  148. package/package.json +1 -1
  149. package/src/hooks/builtin-policies.ts +110 -18
  150. package/src/hooks/custom-hooks-loader.ts +158 -21
  151. package/src/hooks/handler.ts +26 -6
  152. package/src/hooks/hooks-config.ts +47 -2
  153. package/src/hooks/llm-client.ts +2 -2
  154. package/src/hooks/loader-utils.ts +4 -4
  155. package/src/hooks/manager.ts +57 -14
  156. package/src/hooks/policy-evaluator.ts +16 -2
  157. /package/.next/standalone/.next/static/{p7b7Yk0VOBDjbtr1aHDyV → Opbai6exOQP2W488FWmr6}/_buildManifest.js +0 -0
  158. /package/.next/standalone/.next/static/{p7b7Yk0VOBDjbtr1aHDyV → Opbai6exOQP2W488FWmr6}/_clientMiddlewareManifest.js +0 -0
  159. /package/.next/standalone/.next/static/{p7b7Yk0VOBDjbtr1aHDyV → Opbai6exOQP2W488FWmr6}/_ssgManifest.js +0 -0
@@ -37,7 +37,33 @@ failproofai policies --install --custom ./my-policies.js
37
37
 
38
38
  ---
39
39
 
40
- ## Installing and updating
40
+ ## Two ways to load custom policies
41
+
42
+ ### Option 1: Convention-based (recommended, v0.0.2-beta.7+)
43
+
44
+ Drop `*policies.{js,mjs,ts}` files into `.failproofai/policies/` and they're automatically loaded — no flags or config changes needed. This works like git hooks: drop a file, it just works.
45
+
46
+ ```
47
+ # Project level — committed to git, shared with the team
48
+ .failproofai/policies/security-policies.mjs
49
+ .failproofai/policies/workflow-policies.mjs
50
+
51
+ # User level — personal, applies to all projects
52
+ ~/.failproofai/policies/my-policies.mjs
53
+ ```
54
+
55
+ **How it works:**
56
+ - Both project and user directories are scanned (union — not first-scope-wins)
57
+ - Files are loaded alphabetically within each directory. Prefix with `01-`, `02-` to control order
58
+ - Only files matching `*policies.{js,mjs,ts}` are loaded; other files are ignored
59
+ - Each file is loaded independently (fail-open per file)
60
+ - Works alongside explicit `--custom` and built-in policies
61
+
62
+ <Tip>
63
+ Convention policies are the easiest way to share policies across a team. Commit `.failproofai/policies/` to git and every team member gets them automatically.
64
+ </Tip>
65
+
66
+ ### Option 2: Explicit file path
41
67
 
42
68
  ```bash
43
69
  # Install with a custom policies file
@@ -52,6 +78,14 @@ failproofai policies --uninstall --custom
52
78
 
53
79
  The resolved absolute path is stored in `policies-config.json` as `customPoliciesPath`. The file is loaded fresh on every hook event - there is no caching between events.
54
80
 
81
+ ### Using both together
82
+
83
+ Convention policies and the explicit `--custom` file can coexist. Load order:
84
+
85
+ 1. Explicit `customPoliciesPath` file (if configured)
86
+ 2. Project convention files (`{cwd}/.failproofai/policies/`, alphabetical)
87
+ 3. User convention files (`~/.failproofai/policies/`, alphabetical)
88
+
55
89
  ---
56
90
 
57
91
  ## API
@@ -87,6 +121,10 @@ customPolicies.add({
87
121
 
88
122
  `instruct(message)` - the message is appended to Claude's context for the current tool call. The first `instruct` wins — subsequent `instruct` returns from other policies are ignored.
89
123
 
124
+ <Tip>
125
+ You can append extra guidance to any `deny` or `instruct` message by adding a `hint` field in `policyParams` — no code change needed. This works for custom (`custom/`) and convention (`convention/`) policies too. See [Configuration → hint](/configuration#hint-cross-cutting) for details.
126
+ </Tip>
127
+
90
128
  ### Informational allow messages (beta)
91
129
 
92
130
  <Note>
@@ -155,7 +193,9 @@ customPolicies.add({
155
193
  Policies are evaluated in this order:
156
194
 
157
195
  1. Built-in policies (in definition order)
158
- 2. Custom policies (in `.add()` order)
196
+ 2. Explicit custom policies from `customPoliciesPath` (in `.add()` order)
197
+ 3. Convention policies from project `.failproofai/policies/` (files alphabetical, `.add()` order within)
198
+ 4. Convention policies from user `~/.failproofai/policies/` (files alphabetical, `.add()` order within)
159
199
 
160
200
  <Note>
161
201
  The first `deny` short-circuits all subsequent policies. The first `instruct` wins — subsequent `instruct` returns are ignored.
@@ -212,11 +252,13 @@ Custom policies are **fail-open**: errors never block built-in policies or crash
212
252
 
213
253
  | Failure | Behavior |
214
254
  |---------|----------|
215
- | `customPoliciesPath` not set | No custom policies run; built-ins continue normally |
255
+ | `customPoliciesPath` not set | No explicit custom policies run; convention policies and built-ins continue normally |
216
256
  | File not found | Warning logged to `~/.failproofai/hook.log`; built-ins continue |
217
- | Syntax/import error | Error logged to `~/.failproofai/hook.log`; all custom policies skipped |
257
+ | Syntax/import error (explicit) | Error logged to `~/.failproofai/hook.log`; explicit custom policies skipped |
258
+ | Syntax/import error (convention) | Error logged; that file skipped, other convention files still load |
218
259
  | `fn` throws at runtime | Error logged; that hook treated as `allow`; other hooks continue |
219
260
  | `fn` takes longer than 10s | Timeout logged; treated as `allow` |
261
+ | Convention directory missing | No convention policies run; no error |
220
262
 
221
263
  <Tip>
222
264
  To debug custom policy errors, watch the log file:
@@ -291,9 +333,25 @@ The `examples/` directory contains ready-to-run policy files:
291
333
  |------|----------|
292
334
  | `examples/policies-basic.js` | Five starter policies covering common agent failure modes |
293
335
  | `examples/policies-advanced/index.js` | Advanced patterns: transitive imports, async calls, output scrubbing, and session-end hooks |
336
+ | `examples/convention-policies/security-policies.mjs` | Convention-based security policies (block .env writes, prevent git history rewriting) |
337
+ | `examples/convention-policies/workflow-policies.mjs` | Convention-based workflow policies (test reminders, audit file writes) |
294
338
 
295
- Install the basic examples:
339
+ ### Using explicit file examples
296
340
 
297
341
  ```bash
298
342
  failproofai policies --install --custom ./examples/policies-basic.js
299
343
  ```
344
+
345
+ ### Using convention-based examples
346
+
347
+ ```bash
348
+ # Copy to project level
349
+ mkdir -p .failproofai/policies
350
+ cp examples/convention-policies/*.mjs .failproofai/policies/
351
+
352
+ # Or copy to user level
353
+ mkdir -p ~/.failproofai/policies
354
+ cp examples/convention-policies/*.mjs ~/.failproofai/policies/
355
+ ```
356
+
357
+ No install command needed — the files are picked up automatically on the next hook event.
@@ -86,9 +86,9 @@
86
86
  "icon": "npm"
87
87
  },
88
88
  {
89
- "anchor": "Discord",
90
- "href": "https://discord.com/invite/zT92CAgvkj",
91
- "icon": "discord"
89
+ "anchor": "Slack",
90
+ "href": "https://join.slack.com/t/failproofai/shared_invite/zt-3v63b7k5e-O3NBHmj8X6n9gZSGDx6ggQ",
91
+ "icon": "slack"
92
92
  }
93
93
  ]
94
94
  }
@@ -0,0 +1,40 @@
1
+ /**
2
+ * security-policies.mjs — Convention-based security policies
3
+ *
4
+ * Drop this file into .failproofai/policies/ at the project or user level
5
+ * and it will be automatically loaded — no --custom flag needed.
6
+ *
7
+ * Project level: .failproofai/policies/security-policies.mjs
8
+ * User level: ~/.failproofai/policies/security-policies.mjs
9
+ */
10
+ import { customPolicies, allow, deny } from "failproofai";
11
+
12
+ // Block writes to .env files
13
+ customPolicies.add({
14
+ name: "block-env-writes",
15
+ description: "Prevent Claude from writing to .env files",
16
+ match: { events: ["PreToolUse"] },
17
+ fn: async (ctx) => {
18
+ if (!["Write", "Edit"].includes(ctx.toolName ?? "")) return allow();
19
+ const path = String(ctx.toolInput?.file_path ?? "");
20
+ if (/\.env($|\.)/.test(path)) {
21
+ return deny(`Writing to .env files is blocked: ${path}`);
22
+ }
23
+ return allow();
24
+ },
25
+ });
26
+
27
+ // Block commands that delete git history
28
+ customPolicies.add({
29
+ name: "block-git-history-rewrite",
30
+ description: "Prevent destructive git history operations",
31
+ match: { events: ["PreToolUse"] },
32
+ fn: async (ctx) => {
33
+ if (ctx.toolName !== "Bash") return allow();
34
+ const cmd = String(ctx.toolInput?.command ?? "");
35
+ if (/git\s+(rebase\s+-i|filter-branch|reflog\s+expire)/.test(cmd)) {
36
+ return deny("Rewriting git history is not allowed — use a revert commit instead");
37
+ }
38
+ return allow();
39
+ },
40
+ });
@@ -0,0 +1,41 @@
1
+ /**
2
+ * workflow-policies.mjs — Convention-based workflow policies
3
+ *
4
+ * Drop this file into .failproofai/policies/ at the project or user level
5
+ * and it will be automatically loaded — no --custom flag needed.
6
+ *
7
+ * Project level: .failproofai/policies/workflow-policies.mjs
8
+ * User level: ~/.failproofai/policies/workflow-policies.mjs
9
+ */
10
+ import { customPolicies, allow, instruct } from "failproofai";
11
+
12
+ // Remind to run tests before committing
13
+ customPolicies.add({
14
+ name: "test-before-commit",
15
+ description: "Remind Claude to run tests before git commit",
16
+ match: { events: ["PreToolUse"] },
17
+ fn: async (ctx) => {
18
+ if (ctx.toolName !== "Bash") return allow();
19
+ const cmd = String(ctx.toolInput?.command ?? "");
20
+ if (/git\s+commit/.test(cmd)) {
21
+ return instruct(
22
+ "Before committing, make sure all tests pass. " +
23
+ "Run the test suite first if you haven't already."
24
+ );
25
+ }
26
+ return allow();
27
+ },
28
+ });
29
+
30
+ // Log all file writes for audit trail
31
+ customPolicies.add({
32
+ name: "audit-file-writes",
33
+ description: "Log all file write operations",
34
+ match: { events: ["PostToolUse"] },
35
+ fn: async (ctx) => {
36
+ if (!["Write", "Edit"].includes(ctx.toolName ?? "")) return allow();
37
+ const path = ctx.toolInput?.file_path ?? "unknown";
38
+ console.error(`[audit] File written: ${path}`);
39
+ return allow();
40
+ },
41
+ });
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@next/env",
3
- "version": "16.2.2",
3
+ "version": "16.2.3",
4
4
  "keywords": [
5
5
  "react",
6
6
  "next",
@@ -134,7 +134,7 @@ var HmrTarget = /*#__PURE__*/ function(HmrTarget) {
134
134
  HmrTarget["Server"] = "server";
135
135
  return HmrTarget;
136
136
  }({});
137
- const nextVersion = "16.2.2";
137
+ const nextVersion = "16.2.3";
138
138
  const ArchName = (0, _os.arch)();
139
139
  const PlatformName = (0, _os.platform)();
140
140
  function infoLog(...args) {