failproofai 0.0.5 → 0.0.6-beta.1
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/.next/standalone/.failproofai/policies/review-policies.mjs +112 -0
- package/.next/standalone/.failproofai/policies/workflow-policies.mjs +2 -1
- package/.next/standalone/.next/BUILD_ID +1 -1
- package/.next/standalone/.next/build-manifest.json +5 -5
- package/.next/standalone/.next/prerender-manifest.json +3 -3
- package/.next/standalone/.next/required-server-files.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/_global-error/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_global-error.html +1 -1
- package/.next/standalone/.next/server/app/_global-error.rsc +7 -7
- package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
- package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +3 -3
- package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +3 -3
- package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_not-found.html +2 -2
- package/.next/standalone/.next/server/app/_not-found.rsc +15 -15
- package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +15 -15
- package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +4 -4
- package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +10 -10
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
- package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/index.html +1 -1
- package/.next/standalone/.next/server/app/index.rsc +15 -15
- package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +15 -15
- package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +4 -4
- package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +10 -10
- package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/policies/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +8 -8
- package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/projects/page/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0g72weg._.js +1 -1
- package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_0z7w.hh._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__092s1ta._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__09icjsf._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0g.lg8b._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0h..k-e._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0okos0k._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0a~g15g._.js → [root-of-the-server]__0rh.18_._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0w6l33k._.js +6 -6
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0qn95h3._.js → [root-of-the-server]__0~kmh8w._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__11pa2ra._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__12t-wym._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/_10lm7or._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_0xerkr6._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_0q-m0y-._.js +1 -1
- package/.next/standalone/.next/server/middleware-build-manifest.js +5 -5
- package/.next/standalone/.next/server/pages/404.html +2 -2
- package/.next/standalone/.next/server/pages/500.html +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.json +9 -9
- package/.next/standalone/.next/static/chunks/{0sme4lkv.tgn-.js → 01b~z8f1ws0rk.js} +1 -1
- package/.next/standalone/.next/static/chunks/{0lgbwkfqmnsmc.js → 03rz6ykw-a2xi.js} +1 -1
- package/.next/standalone/.next/static/chunks/{17manv47o-~wp.js → 08t08igdql9yt.js} +1 -1
- package/.next/standalone/.next/static/chunks/09_k80d~cq2wg.js +4 -0
- package/.next/standalone/.next/static/chunks/{0ksdlt_1hucdm.js → 0bvhsa6zva2o..js} +1 -1
- package/.next/standalone/.next/static/chunks/{09ikntpt2-o9b.js → 0gbf4cphy8ksq.js} +1 -1
- package/.next/standalone/.next/static/chunks/{0yumumfzx_f27.js → 0v.yd0kg_ld3r.js} +1 -1
- package/.next/standalone/.next/static/chunks/{13juklu.vksks.js → 0wlyoif4_kj_t.js} +1 -1
- package/.next/standalone/.next/static/chunks/{09e7drilkf1sn.js → 12simlrcfk3g2.js} +1 -1
- package/.next/standalone/.next/static/chunks/{0em7tspi4kylh.js → 12~yi9oj8av8p.js} +2 -2
- package/.next/standalone/.next/static/chunks/{turbopack-0r26pc8h0y_-e.js → turbopack-0o7k.hakttp4k.js} +1 -1
- package/.next/standalone/CHANGELOG.md +13 -0
- package/.next/standalone/README.md +2 -2
- package/.next/standalone/bun.lock +43 -85
- package/.next/standalone/dist/cli.mjs +107 -3
- package/.next/standalone/docs/ar/architecture.mdx +65 -64
- package/.next/standalone/docs/ar/configuration.mdx +42 -42
- package/.next/standalone/docs/ar/custom-policies.mdx +62 -64
- package/.next/standalone/docs/built-in-policies.mdx +37 -0
- package/.next/standalone/docs/custom-policies.mdx +1 -1
- package/.next/standalone/docs/de/architecture.mdx +92 -92
- package/.next/standalone/docs/de/configuration.mdx +34 -34
- package/.next/standalone/docs/de/custom-policies.mdx +49 -50
- package/.next/standalone/docs/es/architecture.mdx +72 -72
- package/.next/standalone/docs/es/configuration.mdx +25 -25
- package/.next/standalone/docs/es/custom-policies.mdx +48 -49
- package/.next/standalone/docs/examples.mdx +54 -0
- package/.next/standalone/docs/fr/architecture.mdx +53 -53
- package/.next/standalone/docs/fr/configuration.mdx +25 -25
- package/.next/standalone/docs/fr/custom-policies.mdx +42 -43
- package/.next/standalone/docs/getting-started.mdx +52 -0
- package/.next/standalone/docs/he/architecture.mdx +66 -66
- package/.next/standalone/docs/he/configuration.mdx +53 -52
- package/.next/standalone/docs/he/custom-policies.mdx +72 -73
- package/.next/standalone/docs/hi/architecture.mdx +106 -106
- package/.next/standalone/docs/hi/configuration.mdx +39 -39
- package/.next/standalone/docs/hi/custom-policies.mdx +75 -76
- package/.next/standalone/docs/i18n/README.ar.md +66 -66
- package/.next/standalone/docs/i18n/README.de.md +38 -38
- package/.next/standalone/docs/i18n/README.es.md +38 -38
- package/.next/standalone/docs/i18n/README.fr.md +42 -42
- package/.next/standalone/docs/i18n/README.he.md +67 -67
- package/.next/standalone/docs/i18n/README.hi.md +70 -70
- package/.next/standalone/docs/i18n/README.it.md +62 -62
- package/.next/standalone/docs/i18n/README.ja.md +54 -54
- package/.next/standalone/docs/i18n/README.ko.md +58 -58
- package/.next/standalone/docs/i18n/README.pt-br.md +43 -43
- package/.next/standalone/docs/i18n/README.ru.md +69 -69
- package/.next/standalone/docs/i18n/README.tr.md +76 -76
- package/.next/standalone/docs/i18n/README.vi.md +70 -70
- package/.next/standalone/docs/i18n/README.zh.md +52 -52
- package/.next/standalone/docs/it/architecture.mdx +54 -53
- package/.next/standalone/docs/it/configuration.mdx +44 -45
- package/.next/standalone/docs/it/custom-policies.mdx +76 -78
- package/.next/standalone/docs/ja/architecture.mdx +93 -93
- package/.next/standalone/docs/ja/configuration.mdx +47 -47
- package/.next/standalone/docs/ja/custom-policies.mdx +62 -63
- package/.next/standalone/docs/ko/architecture.mdx +66 -66
- package/.next/standalone/docs/ko/configuration.mdx +35 -35
- package/.next/standalone/docs/ko/custom-policies.mdx +71 -72
- package/.next/standalone/docs/pt-br/architecture.mdx +55 -55
- package/.next/standalone/docs/pt-br/configuration.mdx +35 -35
- package/.next/standalone/docs/pt-br/custom-policies.mdx +60 -61
- package/.next/standalone/docs/ru/architecture.mdx +59 -60
- package/.next/standalone/docs/ru/configuration.mdx +52 -53
- package/.next/standalone/docs/ru/custom-policies.mdx +68 -69
- package/.next/standalone/docs/tr/architecture.mdx +124 -124
- package/.next/standalone/docs/tr/configuration.mdx +45 -46
- package/.next/standalone/docs/tr/custom-policies.mdx +75 -75
- package/.next/standalone/docs/vi/architecture.mdx +65 -64
- package/.next/standalone/docs/vi/configuration.mdx +41 -41
- package/.next/standalone/docs/vi/custom-policies.mdx +68 -69
- package/.next/standalone/docs/zh/architecture.mdx +67 -67
- package/.next/standalone/docs/zh/configuration.mdx +34 -34
- package/.next/standalone/docs/zh/custom-policies.mdx +53 -54
- package/.next/standalone/node_modules/@next/env/package.json +1 -1
- package/.next/standalone/node_modules/next/dist/build/swc/index.js +1 -1
- package/.next/standalone/node_modules/next/dist/compiled/next-server/pages-turbo.runtime.prod.js +7 -7
- package/.next/standalone/node_modules/next/dist/lib/patch-incorrect-lockfile.js +3 -3
- package/.next/standalone/node_modules/next/dist/server/config-schema.js +10 -2
- package/.next/standalone/node_modules/next/dist/server/config.js +1 -1
- package/.next/standalone/node_modules/next/dist/server/dev/hot-reloader-turbopack.js +2 -2
- package/.next/standalone/node_modules/next/dist/server/dev/hot-reloader-webpack.js +1 -1
- package/.next/standalone/node_modules/next/dist/server/lib/app-info-log.js +1 -1
- package/.next/standalone/node_modules/next/dist/server/lib/start-server.js +1 -1
- package/.next/standalone/node_modules/next/dist/server/render.js +27 -20
- package/.next/standalone/node_modules/next/dist/shared/lib/errors/canary-only-config-error.js +1 -1
- package/.next/standalone/node_modules/next/dist/telemetry/anonymous-meta.js +1 -1
- package/.next/standalone/node_modules/next/dist/telemetry/events/swc-load-failure.js +1 -1
- package/.next/standalone/node_modules/next/dist/telemetry/events/version.js +2 -2
- package/.next/standalone/node_modules/next/package.json +15 -15
- package/.next/standalone/package.json +2 -2
- package/.next/standalone/server.js +1 -1
- package/.next/standalone/src/hooks/builtin-policies.ts +131 -0
- package/README.md +2 -2
- package/dist/cli.mjs +107 -3
- package/package.json +2 -2
- package/src/hooks/builtin-policies.ts +131 -0
- package/.next/standalone/.next/static/chunks/0_yayar~bpphd.js +0 -4
- /package/.next/standalone/.next/static/{hYQM6iCWnF1W5XDpsIRhV → CkmOT-ZvDN-sVULinGVKT}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{hYQM6iCWnF1W5XDpsIRhV → CkmOT-ZvDN-sVULinGVKT}/_clientMiddlewareManifest.js +0 -0
- /package/.next/standalone/.next/static/{hYQM6iCWnF1W5XDpsIRhV → CkmOT-ZvDN-sVULinGVKT}/_ssgManifest.js +0 -0
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: 自定义策略
|
|
3
|
-
description: "用 JavaScript
|
|
3
|
+
description: "用 JavaScript 编写自己的策略——强制执行项目规范、防止偏离、检测失败、与外部系统集成"
|
|
4
4
|
icon: code
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
自定义策略允许你为任意 Agent 行为编写规则:强制执行项目规范、防止偏离、拦截破坏性操作、检测卡死的 Agent,或与 Slack、审批工作流等系统集成。它们使用与内置策略相同的 Hook 事件系统以及 `allow`、`deny`、`instruct` 决策机制。
|
|
8
8
|
|
|
9
9
|
---
|
|
10
10
|
|
|
@@ -41,32 +41,32 @@ failproofai policies --install --custom ./my-policies.js
|
|
|
41
41
|
|
|
42
42
|
### 方式一:基于约定(推荐)
|
|
43
43
|
|
|
44
|
-
将 `*policies.{js,mjs,ts}` 文件放入 `.failproofai/policies/`
|
|
44
|
+
将 `*policies.{js,mjs,ts}` 文件放入 `.failproofai/policies/` 目录,它们会被自动加载——无需任何命令行参数或配置变更。这与 git hooks 的工作方式类似:放入文件即可生效。
|
|
45
45
|
|
|
46
46
|
```
|
|
47
47
|
# 项目级别——提交到 git,与团队共享
|
|
48
48
|
.failproofai/policies/security-policies.mjs
|
|
49
49
|
.failproofai/policies/workflow-policies.mjs
|
|
50
50
|
|
|
51
|
-
#
|
|
51
|
+
# 用户级别——个人使用,适用于所有项目
|
|
52
52
|
~/.failproofai/policies/my-policies.mjs
|
|
53
53
|
```
|
|
54
54
|
|
|
55
55
|
**工作原理:**
|
|
56
|
-
-
|
|
57
|
-
-
|
|
58
|
-
- 只加载匹配 `*policies.{js,mjs,ts}`
|
|
59
|
-
-
|
|
60
|
-
-
|
|
56
|
+
- 项目目录和用户目录都会被扫描(取并集,而非先命中即生效)
|
|
57
|
+
- 同一目录内的文件按字母顺序加载。可通过 `01-`、`02-` 等前缀控制顺序
|
|
58
|
+
- 只加载匹配 `*policies.{js,mjs,ts}` 的文件,其他文件被忽略
|
|
59
|
+
- 每个文件独立加载(单文件失败不影响其他文件)
|
|
60
|
+
- 可与显式 `--custom` 参数及内置策略共存
|
|
61
61
|
|
|
62
62
|
<Tip>
|
|
63
|
-
|
|
63
|
+
基于约定的策略是在团队间共享策略的最简单方式。将 `.failproofai/policies/` 提交到 git,团队所有成员即可自动获得这些策略。
|
|
64
64
|
</Tip>
|
|
65
65
|
|
|
66
|
-
###
|
|
66
|
+
### 方式二:显式指定文件路径
|
|
67
67
|
|
|
68
68
|
```bash
|
|
69
|
-
#
|
|
69
|
+
# 安装时指定自定义策略文件
|
|
70
70
|
failproofai policies --install --custom ./my-policies.js
|
|
71
71
|
|
|
72
72
|
# 替换策略文件路径
|
|
@@ -76,13 +76,13 @@ failproofai policies --install --custom ./new-policies.js
|
|
|
76
76
|
failproofai policies --uninstall --custom
|
|
77
77
|
```
|
|
78
78
|
|
|
79
|
-
解析后的绝对路径以 `customPoliciesPath`
|
|
79
|
+
解析后的绝对路径以 `customPoliciesPath` 字段存储于 `policies-config.json` 中。每次 Hook 事件触发时都会重新加载该文件,事件之间不存在缓存。
|
|
80
80
|
|
|
81
|
-
###
|
|
81
|
+
### 两种方式同时使用
|
|
82
82
|
|
|
83
|
-
|
|
83
|
+
基于约定的策略和显式 `--custom` 文件可以共存。加载顺序如下:
|
|
84
84
|
|
|
85
|
-
1. 显式 `customPoliciesPath`
|
|
85
|
+
1. 显式 `customPoliciesPath` 文件(若已配置)
|
|
86
86
|
2. 项目约定文件(`{cwd}/.failproofai/policies/`,按字母顺序)
|
|
87
87
|
3. 用户约定文件(`~/.failproofai/policies/`,按字母顺序)
|
|
88
88
|
|
|
@@ -98,12 +98,12 @@ import { customPolicies, allow, deny, instruct } from "failproofai";
|
|
|
98
98
|
|
|
99
99
|
### `customPolicies.add(hook)`
|
|
100
100
|
|
|
101
|
-
|
|
101
|
+
注册一条策略。可多次调用,在同一文件中注册多条策略。
|
|
102
102
|
|
|
103
103
|
```ts
|
|
104
104
|
customPolicies.add({
|
|
105
105
|
name: string; // 必填 - 唯一标识符
|
|
106
|
-
description?: string; //
|
|
106
|
+
description?: string; // 在 `failproofai policies` 输出中显示
|
|
107
107
|
match?: { events?: HookEventType[] }; // 按事件类型过滤;省略则匹配所有事件
|
|
108
108
|
fn: (ctx: PolicyContext) => PolicyResult | Promise<PolicyResult>;
|
|
109
109
|
});
|
|
@@ -117,27 +117,26 @@ customPolicies.add({
|
|
|
117
117
|
| `deny(message)` | 阻止操作 | Agent 不应执行此操作 |
|
|
118
118
|
| `instruct(message)` | 添加上下文但不阻止 | 为 Agent 提供额外上下文以保持正轨 |
|
|
119
119
|
|
|
120
|
-
`deny(message)`
|
|
120
|
+
`deny(message)` —— 消息会以 `"Blocked by failproofai:"` 为前缀显示给 Claude。单个 `deny` 会短路所有后续评估。
|
|
121
121
|
|
|
122
|
-
`instruct(message)`
|
|
122
|
+
`instruct(message)` —— 消息会被追加到当前工具调用的 Claude 上下文中。所有 `instruct` 消息会被累积并一并传递。
|
|
123
123
|
|
|
124
124
|
<Tip>
|
|
125
|
-
|
|
125
|
+
你可以通过在 `policyParams` 中添加 `hint` 字段,为任意 `deny` 或 `instruct` 消息追加额外指导——无需修改代码。这对自定义策略(`custom/`)、项目约定策略(`.failproofai-project/`)和用户约定策略(`.failproofai-user/`)同样适用。详见 [配置 → hint](/zh/configuration#hint-cross-cutting)。
|
|
126
126
|
</Tip>
|
|
127
127
|
|
|
128
|
-
###
|
|
128
|
+
### 信息性允许消息
|
|
129
129
|
|
|
130
|
-
|
|
131
|
-
`allow(message)` 允许操作**并**向 Claude 发送一条信息性消息。该消息以 `additionalContext` 的形式通过 hook 处理器的 stdout 响应发送——与 `instruct` 使用相同的机制,但语义不同:它是状态更新,而非警告。
|
|
130
|
+
`allow(message)` 允许操作**并**向 Claude 发送一条信息性消息。该消息通过 Hook 处理器的 stdout 响应中的 `additionalContext` 字段传递——与 `instruct` 使用相同机制,但语义不同:它是状态更新,而非警告。
|
|
132
131
|
|
|
133
132
|
| 函数 | 效果 | 适用场景 |
|
|
134
133
|
|----------|--------|----------|
|
|
135
|
-
| `allow(message)` | 允许并向 Claude 发送上下文 |
|
|
134
|
+
| `allow(message)` | 允许并向 Claude 发送上下文 | 确认检查通过,或说明跳过检查的原因 |
|
|
136
135
|
|
|
137
136
|
使用场景:
|
|
138
|
-
- **状态确认:** `allow("All CI checks passed.")`
|
|
139
|
-
- **失败开放说明:** `allow("GitHub CLI not installed, skipping CI check.")`
|
|
140
|
-
- **多条消息累积:**
|
|
137
|
+
- **状态确认:** `allow("All CI checks passed.")` —— 告知 Claude 一切正常
|
|
138
|
+
- **失败开放说明:** `allow("GitHub CLI not installed, skipping CI check.")` —— 告知 Claude 跳过检查的原因,保持完整上下文
|
|
139
|
+
- **多条消息累积:** 若多条策略各自返回 `allow(message)`,所有消息会用换行符连接后一并传递
|
|
141
140
|
|
|
142
141
|
```js
|
|
143
142
|
customPolicies.add({
|
|
@@ -161,9 +160,9 @@ customPolicies.add({
|
|
|
161
160
|
| 字段 | 类型 | 描述 |
|
|
162
161
|
|-------|------|-------------|
|
|
163
162
|
| `eventType` | `string` | `"PreToolUse"`、`"PostToolUse"`、`"Notification"`、`"Stop"` |
|
|
164
|
-
| `toolName` | `string \| undefined` |
|
|
163
|
+
| `toolName` | `string \| undefined` | 被调用的工具名(如 `"Bash"`、`"Write"`、`"Read"`) |
|
|
165
164
|
| `toolInput` | `Record<string, unknown> \| undefined` | 工具的输入参数 |
|
|
166
|
-
| `payload` | `Record<string, unknown>` | 来自 Claude Code
|
|
165
|
+
| `payload` | `Record<string, unknown>` | 来自 Claude Code 的完整原始事件负载 |
|
|
167
166
|
| `session` | `SessionMetadata \| undefined` | 会话上下文(见下文) |
|
|
168
167
|
|
|
169
168
|
### `SessionMetadata` 字段
|
|
@@ -178,9 +177,9 @@ customPolicies.add({
|
|
|
178
177
|
|
|
179
178
|
| 事件 | 触发时机 | `toolInput` 内容 |
|
|
180
179
|
|-------|--------------|----------------------|
|
|
181
|
-
| `PreToolUse` | Claude
|
|
182
|
-
| `PostToolUse` | 工具执行完成之后 |
|
|
183
|
-
| `Notification` | Claude 发送通知时 | `{ message: "...", notification_type: "idle" \| "permission_prompt" \| ... }`
|
|
180
|
+
| `PreToolUse` | Claude 运行工具之前 | 工具输入(如 Bash 对应 `{ command: "..." }`) |
|
|
181
|
+
| `PostToolUse` | 工具执行完成之后 | 工具输入 + `tool_result`(输出结果) |
|
|
182
|
+
| `Notification` | Claude 发送通知时 | `{ message: "...", notification_type: "idle" \| "permission_prompt" \| ... }` —— Hook 必须始终返回 `allow()`,不能阻止通知 |
|
|
184
183
|
| `Stop` | Claude 会话结束时 | 空 |
|
|
185
184
|
|
|
186
185
|
---
|
|
@@ -190,19 +189,19 @@ customPolicies.add({
|
|
|
190
189
|
策略按以下顺序评估:
|
|
191
190
|
|
|
192
191
|
1. 内置策略(按定义顺序)
|
|
193
|
-
2. 来自 `customPoliciesPath` 的显式自定义策略(按 `.add()`
|
|
194
|
-
3.
|
|
195
|
-
4.
|
|
192
|
+
2. 来自 `customPoliciesPath` 的显式自定义策略(按 `.add()` 调用顺序)
|
|
193
|
+
3. 项目约定策略,来自 `.failproofai/policies/`(文件按字母顺序,文件内按 `.add()` 顺序)
|
|
194
|
+
4. 用户约定策略,来自 `~/.failproofai/policies/`(文件按字母顺序,文件内按 `.add()` 顺序)
|
|
196
195
|
|
|
197
196
|
<Note>
|
|
198
|
-
第一个 `deny` 会短路所有后续策略。所有 `instruct`
|
|
197
|
+
第一个 `deny` 会短路所有后续策略。所有 `instruct` 消息会被累积并一并传递。
|
|
199
198
|
</Note>
|
|
200
199
|
|
|
201
200
|
---
|
|
202
201
|
|
|
203
202
|
## 传递性导入
|
|
204
203
|
|
|
205
|
-
|
|
204
|
+
自定义策略文件可使用相对路径导入本地模块:
|
|
206
205
|
|
|
207
206
|
```js
|
|
208
207
|
// my-policies.js
|
|
@@ -219,7 +218,7 @@ customPolicies.add({
|
|
|
219
218
|
});
|
|
220
219
|
```
|
|
221
220
|
|
|
222
|
-
|
|
221
|
+
所有从入口文件可达的相对导入都会被解析。其实现方式是将 `from "failproofai"` 的导入重写为实际的 dist 路径,并创建临时 `.mjs` 文件以确保 ESM 兼容性。
|
|
223
222
|
|
|
224
223
|
---
|
|
225
224
|
|
|
@@ -239,26 +238,26 @@ customPolicies.add({
|
|
|
239
238
|
});
|
|
240
239
|
```
|
|
241
240
|
|
|
242
|
-
省略 `match`
|
|
241
|
+
省略 `match` 则对所有事件类型触发。
|
|
243
242
|
|
|
244
243
|
---
|
|
245
244
|
|
|
246
245
|
## 错误处理与失败模式
|
|
247
246
|
|
|
248
|
-
|
|
247
|
+
自定义策略采用**失败开放**机制:错误不会阻止内置策略运行,也不会导致 Hook 处理器崩溃。
|
|
249
248
|
|
|
250
|
-
|
|
|
249
|
+
| 失败情况 | 行为 |
|
|
251
250
|
|---------|----------|
|
|
252
251
|
| `customPoliciesPath` 未设置 | 不运行显式自定义策略;约定策略和内置策略正常继续 |
|
|
253
|
-
| 文件未找到 |
|
|
254
|
-
| 语法/导入错误(显式) |
|
|
252
|
+
| 文件未找到 | 警告记录至 `~/.failproofai/hook.log`;内置策略继续运行 |
|
|
253
|
+
| 语法/导入错误(显式) | 错误记录至 `~/.failproofai/hook.log`;跳过显式自定义策略 |
|
|
255
254
|
| 语法/导入错误(约定) | 错误记录;跳过该文件,其他约定文件继续加载 |
|
|
256
|
-
| `fn` 运行时抛出异常 | 错误记录;该
|
|
255
|
+
| `fn` 运行时抛出异常 | 错误记录;该 Hook 视为 `allow`;其他 Hook 继续运行 |
|
|
257
256
|
| `fn` 执行超过 10 秒 | 超时记录;视为 `allow` |
|
|
258
|
-
| 约定目录不存在 |
|
|
257
|
+
| 约定目录不存在 | 不运行约定策略;无报错 |
|
|
259
258
|
|
|
260
259
|
<Tip>
|
|
261
|
-
|
|
260
|
+
如需调试自定义策略错误,可监听日志文件:
|
|
262
261
|
|
|
263
262
|
```bash
|
|
264
263
|
tail -f ~/.failproofai/hook.log
|
|
@@ -267,13 +266,13 @@ tail -f ~/.failproofai/hook.log
|
|
|
267
266
|
|
|
268
267
|
---
|
|
269
268
|
|
|
270
|
-
##
|
|
269
|
+
## 完整示例:多条策略
|
|
271
270
|
|
|
272
271
|
```js
|
|
273
272
|
// my-policies.js
|
|
274
273
|
import { customPolicies, allow, deny, instruct } from "failproofai";
|
|
275
274
|
|
|
276
|
-
//
|
|
275
|
+
// 禁止 Agent 向 secrets/ 目录写入
|
|
277
276
|
customPolicies.add({
|
|
278
277
|
name: "block-secrets-dir",
|
|
279
278
|
description: "Prevent agent from writing to secrets/ directory",
|
|
@@ -286,7 +285,7 @@ customPolicies.add({
|
|
|
286
285
|
},
|
|
287
286
|
});
|
|
288
287
|
|
|
289
|
-
//
|
|
288
|
+
// 保持 Agent 在轨:提交前验证测试
|
|
290
289
|
customPolicies.add({
|
|
291
290
|
name: "remind-test-before-commit",
|
|
292
291
|
description: "Keep the agent on track: verify tests pass before committing",
|
|
@@ -301,7 +300,7 @@ customPolicies.add({
|
|
|
301
300
|
},
|
|
302
301
|
});
|
|
303
302
|
|
|
304
|
-
//
|
|
303
|
+
// 冻结期间禁止计划外的依赖变更
|
|
305
304
|
customPolicies.add({
|
|
306
305
|
name: "dependency-freeze",
|
|
307
306
|
description: "Prevent unplanned dependency changes during freeze period",
|
|
@@ -328,8 +327,8 @@ export { customPolicies };
|
|
|
328
327
|
|
|
329
328
|
| 文件 | 内容 |
|
|
330
329
|
|------|----------|
|
|
331
|
-
| `examples/policies-basic.js` |
|
|
332
|
-
| `examples/policies-advanced/index.js` |
|
|
330
|
+
| `examples/policies-basic.js` | 五条入门策略,涵盖常见 Agent 失败模式 |
|
|
331
|
+
| `examples/policies-advanced/index.js` | 高级模式:传递性导入、异步调用、输出清洗、会话结束 Hook |
|
|
333
332
|
| `examples/convention-policies/security-policies.mjs` | 基于约定的安全策略(阻止 .env 写入、防止 git 历史重写) |
|
|
334
333
|
| `examples/convention-policies/workflow-policies.mjs` | 基于约定的工作流策略(测试提醒、审计文件写入) |
|
|
335
334
|
|
|
@@ -351,4 +350,4 @@ mkdir -p ~/.failproofai/policies
|
|
|
351
350
|
cp examples/convention-policies/*.mjs ~/.failproofai/policies/
|
|
352
351
|
```
|
|
353
352
|
|
|
354
|
-
|
|
353
|
+
无需执行安装命令——下次 Hook 事件触发时,文件会被自动加载。
|
|
@@ -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.
|
|
137
|
+
const nextVersion = "16.2.4";
|
|
138
138
|
const ArchName = (0, _os.arch)();
|
|
139
139
|
const PlatformName = (0, _os.platform)();
|
|
140
140
|
function infoLog(...args) {
|