Diff
1diff --git a/README.md b/README.md
2index 4efdad12c53cc9da24e5b6f85408682d5f5ccad9..d2f784272e284fbbc551a612b54cd3d1830ce23b 100644
3--- a/README.md
4+++ b/README.md
5@@ -1,4 +1,4 @@
6-# pi-policy-engine
7+# agent-policy-engine
8
9 A policy engine for Pi and OpenCode. It evaluates tool operations in this order:
10
11@@ -14,7 +14,7 @@ A policy engine for Pi and OpenCode. It evaluates tool operations in this order:
12 ### Pi
13
14 ```sh
15-pi install /path/to/pi-policy-engine
16+pi install /path/to/agent-policy-engine
17 ```
18
19 For development:
20@@ -38,10 +38,10 @@ The default reviewer is OpenAI with model `gpt-5.4-nano`. `OPENAI_SMALL_FAST_MOD
21
22 ```json
23 {
24- "reviewer": {
25- "kind": "openai",
26- "model": "gpt-5.4-nano"
27- }
28+ "reviewer": {
29+ "kind": "openai",
30+ "model": "gpt-5.4-nano"
31+ }
32 }
33 ```
34
35@@ -49,11 +49,11 @@ Use local llama.cpp:
36
37 ```json
38 {
39- "reviewer": {
40- "kind": "llama.cpp",
41- "baseUrl": "http://127.0.0.1:9931",
42- "model": "reviewer"
43- }
44+ "reviewer": {
45+ "kind": "llama.cpp",
46+ "baseUrl": "http://127.0.0.1:9931",
47+ "model": "reviewer"
48+ }
49 }
50 ```
51
52@@ -61,12 +61,12 @@ Use an OpenAI-compatible endpoint. `apiKeyEnv` is optional. The endpoint receive
53
54 ```json
55 {
56- "reviewer": {
57- "kind": "openai-compatible",
58- "baseUrl": "https://gateway.example.com/v1",
59- "model": "policy-reviewer",
60- "apiKeyEnv": "POLICY_GATEWAY_API_KEY"
61- }
62+ "reviewer": {
63+ "kind": "openai-compatible",
64+ "baseUrl": "https://gateway.example.com/v1",
65+ "model": "policy-reviewer",
66+ "apiKeyEnv": "POLICY_GATEWAY_API_KEY"
67+ }
68 }
69 ```
70
71diff --git a/bun.lock b/bun.lock
72index 1d0bec775fa613dbb7bbe93589f09efc06314a79..75cbb01c0ce84273bb6c4f2a56ab2dfe24b85953 100644
73--- a/bun.lock
74+++ b/bun.lock
75@@ -3,7 +3,7 @@
76 "configVersion": 1,
77 "workspaces": {
78 "": {
79- "name": "pi-policy-engine",
80+ "name": "agent-policy-engine",
81 "dependencies": {
82 "@opencode-ai/plugin": "1.18.22",
83 "tree-sitter-bash": "0.25.1",
84@@ -499,8 +499,6 @@
85
86 "@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="],
87
88- "@typescript-eslint/typescript-estree/semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="],
89-
90 "eslint/ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="],
91
92 "p-retry/retry": ["retry@0.13.1", "", {}, "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg=="],
93diff --git a/package.json b/package.json
94index 4b73a8e5f592fec9c82b138cf7becd905af7aabc..d31ca83b817017de319db7f2cac6a701a61e151e 100644
95--- a/package.json
96+++ b/package.json
97@@ -1,5 +1,5 @@
98 {
99- "name": "pi-policy-engine",
100+ "name": "agent-policy-engine",
101 "version": "3.0.0",
102 "type": "module",
103 "main": "./src/opencode/index.ts",
104diff --git a/test/pi/config.test.ts b/test/pi/config.test.ts
105index 6994b60cc0d4f478108f79a1cb85742160138182..fd96b323149d236526a07e98038a7b6e2ba43e30 100644
106--- a/test/pi/config.test.ts
107+++ b/test/pi/config.test.ts
108@@ -1,39 +1,47 @@
109-import { afterEach, beforeEach, describe, expect, test } from "bun:test"
110-import { mkdtempSync, rmSync, writeFileSync } from "node:fs"
111-import { tmpdir } from "node:os"
112-import { join } from "node:path"
113-import { parseReviewerConfig } from "../../src/core/config"
114-import { loadPiPolicyConfig } from "../../src/pi/config"
115+import { afterEach, beforeEach, describe, expect, test } from "bun:test";
116+import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
117+import { tmpdir } from "node:os";
118+import { join } from "node:path";
119+import { parseReviewerConfig } from "../../src/core/config";
120+import { loadPiPolicyConfig } from "../../src/pi/config";
121
122-const originalConfigPath = process.env.PI_POLICY_ENGINE_CONFIG
123-let directory: string
124-let configFile: string
125+const originalConfigPath = process.env.PI_POLICY_ENGINE_CONFIG;
126+let directory: string;
127+let configFile: string;
128
129 beforeEach(() => {
130- directory = mkdtempSync(join(tmpdir(), "pi-policy-engine-config-"))
131- configFile = join(directory, "policy-engine.json")
132- process.env.PI_POLICY_ENGINE_CONFIG = configFile
133-})
134+ directory = mkdtempSync(join(tmpdir(), "agent-policy-engine-config-"));
135+ configFile = join(directory, "policy-engine.json");
136+ process.env.PI_POLICY_ENGINE_CONFIG = configFile;
137+});
138
139 afterEach(() => {
140- rmSync(directory, { recursive: true, force: true })
141- if (originalConfigPath === undefined) delete process.env.PI_POLICY_ENGINE_CONFIG
142- else process.env.PI_POLICY_ENGINE_CONFIG = originalConfigPath
143-})
144+ rmSync(directory, { recursive: true, force: true });
145+ if (originalConfigPath === undefined)
146+ delete process.env.PI_POLICY_ENGINE_CONFIG;
147+ else process.env.PI_POLICY_ENGINE_CONFIG = originalConfigPath;
148+});
149
150 describe("Pi policy configuration", () => {
151 test("uses the default reviewer when the configured file is absent", () => {
152- expect(loadPiPolicyConfig()).toEqual({ reviewer: parseReviewerConfig({}) })
153- })
154+ expect(loadPiPolicyConfig()).toEqual({ reviewer: parseReviewerConfig({}) });
155+ });
156
157 test("loads legacy local reviewer configuration", () => {
158- writeFileSync(configFile, JSON.stringify({
159- modelBackend: "local",
160- llamaServer: { baseUrl: "http://127.0.0.1:9999", model: "legacy" },
161- }))
162+ writeFileSync(
163+ configFile,
164+ JSON.stringify({
165+ modelBackend: "local",
166+ llamaServer: { baseUrl: "http://127.0.0.1:9999", model: "legacy" },
167+ }),
168+ );
169
170 expect(loadPiPolicyConfig()).toEqual({
171- reviewer: { kind: "llama.cpp", baseUrl: "http://127.0.0.1:9999", model: "legacy" },
172- })
173- })
174-})
175+ reviewer: {
176+ kind: "llama.cpp",
177+ baseUrl: "http://127.0.0.1:9999",
178+ model: "legacy",
179+ },
180+ });
181+ });
182+});
183diff --git a/test/pi/pipeline.test.ts b/test/pi/pipeline.test.ts
184index 709f68bd264804d468ba723b32c362011f4af940..8efdf1551bec23f1d241456c0020a1dbba2c1361 100644
185--- a/test/pi/pipeline.test.ts
186+++ b/test/pi/pipeline.test.ts
187@@ -1,35 +1,43 @@
188-import { afterEach, beforeEach, describe, expect, test } from "bun:test"
189-import { mkdtempSync, rmSync, writeFileSync } from "node:fs"
190-import { tmpdir } from "node:os"
191-import { join } from "node:path"
192-import { evaluatePiToolCall } from "../../src/pi/index"
193+import { afterEach, beforeEach, describe, expect, test } from "bun:test";
194+import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
195+import { tmpdir } from "node:os";
196+import { join } from "node:path";
197+import { evaluatePiToolCall } from "../../src/pi/index";
198
199-const originalConfig = process.env.PI_POLICY_ENGINE_CONFIG
200-const originalKey = process.env.OPENAI_API_KEY
201-const originalFetch = globalThis.fetch
202-let directory: string
203+const originalConfig = process.env.PI_POLICY_ENGINE_CONFIG;
204+const originalKey = process.env.OPENAI_API_KEY;
205+const originalFetch = globalThis.fetch;
206+let directory: string;
207
208 beforeEach(() => {
209- directory = mkdtempSync(join(tmpdir(), "pi-policy-engine-"))
210- process.env.PI_POLICY_ENGINE_CONFIG = join(directory, "config.json")
211- process.env.OPENAI_API_KEY = "test-key"
212- writeFileSync(process.env.PI_POLICY_ENGINE_CONFIG, "{}")
213-})
214+ directory = mkdtempSync(join(tmpdir(), "agent-policy-engine-"));
215+ process.env.PI_POLICY_ENGINE_CONFIG = join(directory, "config.json");
216+ process.env.OPENAI_API_KEY = "test-key";
217+ writeFileSync(process.env.PI_POLICY_ENGINE_CONFIG, "{}");
218+});
219
220 afterEach(() => {
221- globalThis.fetch = originalFetch
222- rmSync(directory, { recursive: true, force: true })
223- if (originalConfig === undefined) delete process.env.PI_POLICY_ENGINE_CONFIG
224- else process.env.PI_POLICY_ENGINE_CONFIG = originalConfig
225- if (originalKey === undefined) delete process.env.OPENAI_API_KEY
226- else process.env.OPENAI_API_KEY = originalKey
227-})
228+ globalThis.fetch = originalFetch;
229+ rmSync(directory, { recursive: true, force: true });
230+ if (originalConfig === undefined) delete process.env.PI_POLICY_ENGINE_CONFIG;
231+ else process.env.PI_POLICY_ENGINE_CONFIG = originalConfig;
232+ if (originalKey === undefined) delete process.env.OPENAI_API_KEY;
233+ else process.env.OPENAI_API_KEY = originalKey;
234+});
235
236 describe("Pi policy pipeline", () => {
237 test("does not deterministically allow after a parser failure", async () => {
238- globalThis.fetch = (async () => Response.json({
239- choices: [{ message: { content: '{"decision":"ask","reason":"reviewed","category":"uncertain"}' } }],
240- })) as unknown as typeof fetch
241+ globalThis.fetch = (async () =>
242+ Response.json({
243+ choices: [
244+ {
245+ message: {
246+ content:
247+ '{"decision":"ask","reason":"reviewed","category":"uncertain"}',
248+ },
249+ },
250+ ],
251+ })) as unknown as typeof fetch;
252
253 const result = await evaluatePiToolCall(
254 "bash",
255@@ -38,8 +46,11 @@ describe("Pi policy pipeline", () => {
256 undefined,
257 async () => {},
258 async () => ({ commands: ["git status"], parsed: false }),
259- )
260+ );
261
262- expect(result).toMatchObject({ decision: { decision: "ask" }, source: "llm" })
263- })
264-})
265+ expect(result).toMatchObject({
266+ decision: { decision: "ask" },
267+ source: "llm",
268+ });
269+ });
270+});