@agentwares/agentguard 0.1.6 → 0.1.9

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 (48) hide show
  1. package/CHANGELOG.md +89 -0
  2. package/README.md +223 -16
  3. package/dist/audit-2YCMHMCP.js +17 -0
  4. package/dist/audit-2YCMHMCP.js.map +1 -0
  5. package/dist/chunk-3O6KWT3E.js +345 -0
  6. package/dist/chunk-3O6KWT3E.js.map +1 -0
  7. package/dist/chunk-5WRI5ZAA.js +31 -0
  8. package/dist/chunk-5WRI5ZAA.js.map +1 -0
  9. package/dist/chunk-6S7LYVOC.js +1033 -0
  10. package/dist/chunk-6S7LYVOC.js.map +1 -0
  11. package/dist/chunk-6TUQD666.js +828 -0
  12. package/dist/chunk-6TUQD666.js.map +1 -0
  13. package/dist/chunk-BKXXTWIS.js +119 -0
  14. package/dist/chunk-BKXXTWIS.js.map +1 -0
  15. package/dist/chunk-D66U3PVB.js +529 -0
  16. package/dist/chunk-D66U3PVB.js.map +1 -0
  17. package/dist/chunk-HPYZ3JDX.js +206 -0
  18. package/dist/chunk-HPYZ3JDX.js.map +1 -0
  19. package/dist/chunk-KRKZGAJ3.js +769 -0
  20. package/dist/chunk-KRKZGAJ3.js.map +1 -0
  21. package/dist/chunk-SUXQTT3X.js +1268 -0
  22. package/dist/chunk-SUXQTT3X.js.map +1 -0
  23. package/dist/chunk-TW5KJREH.js +190 -0
  24. package/dist/chunk-TW5KJREH.js.map +1 -0
  25. package/dist/chunk-VQWQ5TOM.js +113 -0
  26. package/dist/chunk-VQWQ5TOM.js.map +1 -0
  27. package/dist/chunk-X4M7YWQA.js +270 -0
  28. package/dist/chunk-X4M7YWQA.js.map +1 -0
  29. package/dist/chunk-ZSLWPKXI.js +1144 -0
  30. package/dist/chunk-ZSLWPKXI.js.map +1 -0
  31. package/dist/cli.js +8 -4725
  32. package/dist/cli.js.map +1 -1
  33. package/dist/fixtures/crm-server.js +6 -1272
  34. package/dist/fixtures/crm-server.js.map +1 -1
  35. package/dist/fixtures/demo-agent.js +4 -115
  36. package/dist/fixtures/demo-agent.js.map +1 -1
  37. package/dist/index.d.ts +76 -10
  38. package/dist/index.js +246 -5087
  39. package/dist/index.js.map +1 -1
  40. package/dist/init-CWROGV5I.js +15 -0
  41. package/dist/init-CWROGV5I.js.map +1 -0
  42. package/dist/proxy-3Z5YEZ4R.js +154 -0
  43. package/dist/proxy-3Z5YEZ4R.js.map +1 -0
  44. package/dist/tools-3LLDG3XQ.js +15 -0
  45. package/dist/tools-3LLDG3XQ.js.map +1 -0
  46. package/llms.txt +4 -0
  47. package/package.json +9 -3
  48. package/server.json +2 -2
@@ -0,0 +1,345 @@
1
+ import {
2
+ PROXY_PACKAGE
3
+ } from "./chunk-TW5KJREH.js";
4
+ import {
5
+ flagBool,
6
+ flagList,
7
+ flagNumber,
8
+ flagString,
9
+ homeFrom,
10
+ version
11
+ } from "./chunk-SUXQTT3X.js";
12
+
13
+ // src/hooks/clients.ts
14
+ import { copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
15
+ import { dirname, join } from "path";
16
+ var MATCHERS = {
17
+ "claude-code": "^(Bash|PowerShell|Write|Edit|MultiEdit|NotebookEdit)$|^mcp__",
18
+ codex: "^(Bash|apply_patch)$|^mcp__",
19
+ "gemini-cli": "^(run_shell_command|write_file|replace)$|^mcp_"
20
+ };
21
+ var CLIENT_ALIASES = {
22
+ claude: "claude-code",
23
+ "claude-code": "claude-code",
24
+ codex: "codex",
25
+ gemini: "gemini-cli",
26
+ "gemini-cli": "gemini-cli"
27
+ };
28
+ function hookTarget(client, scope, where, command, timeoutS = 30) {
29
+ const root = scope === "project" ? where.cwd : where.home;
30
+ if (client === "claude-code")
31
+ return {
32
+ client,
33
+ label: "Claude Code",
34
+ scope,
35
+ settingsPath: join(root, ".claude", "settings.json"),
36
+ event: "PreToolUse",
37
+ matcher: MATCHERS[client],
38
+ handler: { type: "command", command, timeout: timeoutS, statusMessage: "agentguard" }
39
+ };
40
+ if (client === "codex")
41
+ return {
42
+ client,
43
+ label: "Codex CLI",
44
+ scope,
45
+ settingsPath: join(root, ".codex", "hooks.json"),
46
+ event: "PreToolUse",
47
+ matcher: MATCHERS[client],
48
+ handler: { type: "command", command, timeout: timeoutS, statusMessage: "agentguard" },
49
+ note: "Codex runs a new hook only after you trust it: open /hooks in Codex and trust the agentguard entry."
50
+ };
51
+ return {
52
+ client,
53
+ label: "Gemini CLI",
54
+ scope,
55
+ settingsPath: join(root, ".gemini", "settings.json"),
56
+ event: "BeforeTool",
57
+ matcher: MATCHERS[client],
58
+ handler: {
59
+ name: "agentguard",
60
+ type: "command",
61
+ command,
62
+ timeout: timeoutS * 1e3,
63
+ description: "agentguard: one rulebook for shell commands and file edits"
64
+ },
65
+ note: scope === "project" ? "Gemini CLI fingerprints project hooks: confirm the agentguard hook the first time it asks." : void 0
66
+ };
67
+ }
68
+ function isAgentguardHookCommand(command) {
69
+ return typeof command === "string" && /agentguard/.test(command) && /\bhook\s+pre-tool-use\b/.test(command);
70
+ }
71
+ function readSettings(path) {
72
+ if (!existsSync(path)) return {};
73
+ const text = readFileSync(path, "utf8");
74
+ if (!text.trim()) return {};
75
+ let parsed;
76
+ try {
77
+ parsed = JSON.parse(text);
78
+ } catch (err) {
79
+ throw new Error(
80
+ `${path} is not valid JSON (${err instanceof Error ? err.message : String(err)}); fix it or move it aside \u2014 agentguard will not overwrite it`,
81
+ { cause: err }
82
+ );
83
+ }
84
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
85
+ throw new Error(`${path} is not a JSON object; agentguard will not overwrite it`);
86
+ return parsed;
87
+ }
88
+ function groupsOf(settings, event) {
89
+ const hooks = settings.hooks;
90
+ if (!hooks || typeof hooks !== "object") return [];
91
+ const groups = hooks[event];
92
+ return Array.isArray(groups) ? groups : [];
93
+ }
94
+ function installedHandlers(target) {
95
+ const settings = readSettings(target.settingsPath);
96
+ return groupsOf(settings, target.event).flatMap(
97
+ (g) => (g.hooks ?? []).filter((h) => isAgentguardHookCommand(h.command))
98
+ );
99
+ }
100
+ function installHook(target) {
101
+ const existed = existsSync(target.settingsPath);
102
+ const settings = readSettings(target.settingsPath);
103
+ const hooks = settings.hooks && typeof settings.hooks === "object" ? settings.hooks : {};
104
+ const groups = groupsOf(settings, target.event);
105
+ const isOurs = (h) => isAgentguardHookCommand(h.command);
106
+ const ours = groups.flatMap((g) => (g.hooks ?? []).filter(isOurs));
107
+ const exact = groups.some(
108
+ (g) => g.matcher === target.matcher && g.hooks?.length === 1 && JSON.stringify(g.hooks[0]) === JSON.stringify(target.handler)
109
+ );
110
+ if (exact && ours.length === 1) return { status: "unchanged" };
111
+ const kept = [];
112
+ for (const group of groups) {
113
+ if (!(group.hooks ?? []).some(isOurs)) {
114
+ kept.push(group);
115
+ continue;
116
+ }
117
+ const others = (group.hooks ?? []).filter((h) => !isOurs(h));
118
+ if (others.length > 0) kept.push({ ...group, hooks: others });
119
+ }
120
+ kept.push({ matcher: target.matcher, hooks: [target.handler] });
121
+ const status = ours.length > 0 ? "updated" : "added";
122
+ hooks[target.event] = kept;
123
+ settings.hooks = hooks;
124
+ let backup;
125
+ if (existed) {
126
+ backup = `${target.settingsPath}.agentguard-backup`;
127
+ if (!existsSync(backup)) copyFileSync(target.settingsPath, backup);
128
+ }
129
+ mkdirSync(dirname(target.settingsPath), { recursive: true });
130
+ writeFileSync(target.settingsPath, JSON.stringify(settings, null, 2) + "\n");
131
+ return { status, backup };
132
+ }
133
+ function uninstallHook(target) {
134
+ if (!existsSync(target.settingsPath)) return 0;
135
+ const settings = readSettings(target.settingsPath);
136
+ const groups = groupsOf(settings, target.event);
137
+ let removed = 0;
138
+ const kept = [];
139
+ for (const group of groups) {
140
+ const others = (group.hooks ?? []).filter((h) => !isAgentguardHookCommand(h.command));
141
+ removed += (group.hooks ?? []).length - others.length;
142
+ if (others.length > 0) kept.push({ ...group, hooks: others });
143
+ }
144
+ if (removed === 0) return 0;
145
+ const hooks = settings.hooks;
146
+ if (kept.length > 0) hooks[target.event] = kept;
147
+ else delete hooks[target.event];
148
+ if (Object.keys(hooks).length === 0) delete settings.hooks;
149
+ writeFileSync(target.settingsPath, JSON.stringify(settings, null, 2) + "\n");
150
+ return removed;
151
+ }
152
+ function hookSettingsFiles(where) {
153
+ const out = [];
154
+ for (const root of [where.cwd, where.home]) {
155
+ out.push(
156
+ join(root, ".claude", "settings.json"),
157
+ join(root, ".claude", "settings.local.json"),
158
+ join(root, ".codex", "hooks.json"),
159
+ join(root, ".codex", "config.toml"),
160
+ join(root, ".gemini", "settings.json")
161
+ );
162
+ }
163
+ out.push(join(where.home, ".agentguard", "agentguard.yaml"));
164
+ return out;
165
+ }
166
+
167
+ // src/commands/hooks.ts
168
+ import { appendFileSync, existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
169
+ import { dirname as dirname2, join as join2, relative, resolve } from "path";
170
+ var HOOKS_POLICY_BLOCK = `
171
+ # Hook mode: your coding agent's own shell commands and file edits (Claude Code, Codex, Gemini CLI),
172
+ # checked before they run. \`agentguard hooks install\` wired it; \`agentguard report\` shows the decisions.
173
+ hooks:
174
+ # dry-run: every decision is logged and nothing is blocked. Read \`agentguard report\`, then set
175
+ # enforce. The kill switch (\`agentguard kill\`) stops guarded calls in both modes.
176
+ mode: dry-run
177
+ # Irreversible commands run only on a turn a person typed: after the session's previous
178
+ # irreversible command, recent, and naming the action ("push it", or "yes" to "shall I push?").
179
+ # Text the model writes, tool output and injected messages never count. Otherwise the agent
180
+ # gets APPROVAL_REQUIRED and an id; \`agentguard approve <id>\` lets that exact command run once.
181
+ # Built in: git-push, merge, tag-delete, rm-outside-workspace, publish, send, guard-config.
182
+ irreversible:
183
+ builtins: true
184
+ window_s: 1800 # the authorizing turn is at most 30 minutes old
185
+ require_mention: true # ...and names the action
186
+ require_origin: false # true: only entries Claude Code labels as typed by a person
187
+ mentions: {} # extra words per class, e.g. { git-push: [deploy] }
188
+ rules: []
189
+ # - name: deploy
190
+ # shell: ["vercel --prod*", "fly deploy*"]
191
+ # mentions: [deploy]
192
+ shell:
193
+ deny: [] # e.g. ["terraform destroy*", "curl * | sh"]
194
+ approval: [] # e.g. ["kubectl delete *"]
195
+ paths:
196
+ deny: [] # e.g. [".env", "*.pem"]
197
+ approval: [] # e.g. ["**/migrations/**"]
198
+ `;
199
+ function renderHooksStarterPolicy(generatedAt = /* @__PURE__ */ new Date()) {
200
+ return `# agentguard.yaml \u2014 generated by \`agentguard hooks install\` on ${generatedAt.toISOString().slice(0, 10)}
201
+ # Docs: https://github.com/agentwares/agentguard/tree/main/apps/agentguard-cli#hook-mode-a-coding-agents-own-commands
202
+ version: 1
203
+
204
+ # MCP proxy mode (agentguard init) reads upstreams; hook mode needs none.
205
+ mode: dry-run
206
+ upstreams: []
207
+ ${HOOKS_POLICY_BLOCK}
208
+ # Kill switch: \`agentguard kill\` creates this file; every guarded call is refused until
209
+ # \`agentguard resume\`. AGENTGUARD_KILL=1 in the environment does the same.
210
+ kill:
211
+ file: .agentguard/KILL
212
+
213
+ # Hash-chained JSONL of every decision; \`agentguard verify\` proves it was not edited.
214
+ audit:
215
+ path: .agentguard/audit.jsonl
216
+ redact: true
217
+ `;
218
+ }
219
+ function quoteArg(arg) {
220
+ return /^[A-Za-z0-9_@%+=:,./-]+$/.test(arg) ? arg : JSON.stringify(arg);
221
+ }
222
+ function clientsFrom(args) {
223
+ const names = flagList(args, "client");
224
+ if (names.length === 0) return ["claude-code"];
225
+ if (names.includes("all")) return ["claude-code", "codex", "gemini-cli"];
226
+ return names.map((n) => {
227
+ const c = CLIENT_ALIASES[n.trim()];
228
+ if (!c) throw new Error(`unknown --client "${n}" (claude, codex, gemini or all)`);
229
+ return c;
230
+ });
231
+ }
232
+ function hasTopLevelHooks(yamlText) {
233
+ return /^hooks\s*:/m.test(yamlText);
234
+ }
235
+ async function hooksCommand(args, io) {
236
+ const sub = args.positionals[0] ?? "status";
237
+ const scope = flagBool(args, "user") ? "user" : "project";
238
+ const home = homeFrom(io);
239
+ const where = { cwd: io.cwd, home };
240
+ const rel = (p) => {
241
+ const r = relative(io.cwd, p);
242
+ return r.startsWith("..") ? p : r || ".";
243
+ };
244
+ const clients = clientsFrom(args);
245
+ const policyPath = resolve(
246
+ io.cwd,
247
+ flagString(args, "config") ?? (scope === "user" ? join2(home, ".agentguard", "agentguard.yaml") : "agentguard.yaml")
248
+ );
249
+ const base = flagString(args, "command") ?? `npx -y ${PROXY_PACKAGE}@${version()}`;
250
+ const commandFor = (client) => {
251
+ let cmd = `${base} hook pre-tool-use --client ${client === "claude-code" ? "claude" : client === "gemini-cli" ? "gemini" : "codex"}`;
252
+ if (flagString(args, "config")) cmd += ` --config ${quoteArg(policyPath)}`;
253
+ else if (scope === "user") cmd += ` --fallback-config ${quoteArg(policyPath)}`;
254
+ return cmd;
255
+ };
256
+ const timeoutS = Math.max(30, flagNumber(args, "timeout") ?? 30);
257
+ if (sub === "install") {
258
+ if (!existsSync2(policyPath)) {
259
+ mkdirSync2(dirname2(policyPath), { recursive: true });
260
+ writeFileSync2(policyPath, renderHooksStarterPolicy());
261
+ io.out(`wrote ${rel(policyPath)} (hooks.mode: dry-run)`);
262
+ } else if (!hasTopLevelHooks(readFileSync2(policyPath, "utf8"))) {
263
+ appendFileSync(policyPath, HOOKS_POLICY_BLOCK);
264
+ io.out(`added a hooks: block to ${rel(policyPath)} (hooks.mode: dry-run)`);
265
+ } else io.out(`kept ${rel(policyPath)} (it already has a hooks: block)`);
266
+ for (const client of clients) {
267
+ const target = hookTarget(client, scope, where, commandFor(client), timeoutS);
268
+ const { status, backup } = installHook(target);
269
+ const verb = status === "unchanged" ? "kept " : status === "updated" ? "updated" : "added ";
270
+ io.out(
271
+ `${verb} ${target.label} ${target.event} hook in ${rel(target.settingsPath)}${backup ? ` (backup: ${rel(backup)})` : ""}`
272
+ );
273
+ if (target.note) io.out(` ${target.note}`);
274
+ }
275
+ if (scope === "project" && existsSync2(join2(io.cwd, ".git"))) {
276
+ const gitignore = join2(io.cwd, ".gitignore");
277
+ const text = existsSync2(gitignore) ? readFileSync2(gitignore, "utf8") : "";
278
+ if (!/^\/?\.agentguard\/?$/m.test(text)) {
279
+ appendFileSync(gitignore, `${text && !text.endsWith("\n") ? "\n" : ""}.agentguard/
280
+ `);
281
+ io.out(
282
+ `added .agentguard/ to .gitignore (approvals, counters and the audit log stay local)`
283
+ );
284
+ }
285
+ }
286
+ io.out("");
287
+ io.out("Next:");
288
+ io.out(" 1. start a new session of your coding agent (hooks are read at start)");
289
+ io.out(" 2. work as usual \u2014 hooks.mode is dry-run: decisions are logged, nothing is blocked");
290
+ io.out(" 3. agentguard report # what enforce mode would have stopped, and why");
291
+ io.out(` 4. set \`hooks.mode: enforce\` in ${rel(policyPath)} when it looks right`);
292
+ io.out(" undo: agentguard hooks uninstall" + (scope === "user" ? " --user" : ""));
293
+ return 0;
294
+ }
295
+ if (sub === "uninstall") {
296
+ let total = 0;
297
+ for (const client of flagString(args, "client") ? clients : ["claude-code", "codex", "gemini-cli"]) {
298
+ const target = hookTarget(client, scope, where, commandFor(client), timeoutS);
299
+ const removed = uninstallHook(target);
300
+ total += removed;
301
+ if (removed) io.out(`removed ${target.label} hook from ${rel(target.settingsPath)}`);
302
+ }
303
+ if (total === 0) io.out(`no agentguard hooks in ${scope}-level settings`);
304
+ else
305
+ io.out(
306
+ `kept ${rel(policyPath)} and .agentguard/ (delete them yourself if you want them gone)`
307
+ );
308
+ return 0;
309
+ }
310
+ if (sub === "status") {
311
+ for (const s of ["project", "user"]) {
312
+ for (const client of ["claude-code", "codex", "gemini-cli"]) {
313
+ const target = hookTarget(client, s, where, "", timeoutS);
314
+ let handlers;
315
+ try {
316
+ handlers = installedHandlers(target);
317
+ } catch (err) {
318
+ io.out(
319
+ `${s.padEnd(7)} ${target.label.padEnd(11)} unreadable: ${err instanceof Error ? err.message : String(err)}`
320
+ );
321
+ continue;
322
+ }
323
+ io.out(
324
+ `${s.padEnd(7)} ${target.label.padEnd(11)} ${handlers.length ? `installed: ${String(handlers[0].command)}` : "\u2014"} (${rel(target.settingsPath)})`
325
+ );
326
+ }
327
+ }
328
+ return 0;
329
+ }
330
+ io.err(
331
+ "usage: agentguard hooks install|uninstall|status [--project|--user] [--client claude|codex|gemini|all] [--command cmd] [--config path]"
332
+ );
333
+ return 1;
334
+ }
335
+
336
+ export {
337
+ CLIENT_ALIASES,
338
+ hookTarget,
339
+ installedHandlers,
340
+ hookSettingsFiles,
341
+ HOOKS_POLICY_BLOCK,
342
+ renderHooksStarterPolicy,
343
+ hooksCommand
344
+ };
345
+ //# sourceMappingURL=chunk-3O6KWT3E.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/hooks/clients.ts","../src/commands/hooks.ts"],"sourcesContent":["/**\n * Where each coding agent reads its pre-execution hooks, and the entry agentguard writes there.\n * Verified 7 October 2026 against:\n *\n * - Claude Code: https://code.claude.com/docs/en/hooks — `hooks.PreToolUse[]` in\n * `.claude/settings.json` (project) or `~/.claude/settings.json` (user); a matcher with\n * characters beyond letters, digits, `_`, `-`, `,` and `|` is an unanchored regex; `timeout`\n * in seconds.\n * - Codex CLI: https://developers.openai.com/codex/hooks — `hooks.PreToolUse[]` in\n * `.codex/hooks.json` or `~/.codex/hooks.json`; the matcher is a regex over the tool name\n * (`Bash`, `apply_patch`, `mcp__…`); `timeout` in seconds; a new hook runs only after the user\n * trusts it in `/hooks`.\n * - Gemini CLI: https://github.com/google-gemini/gemini-cli/blob/main/docs/hooks/reference.md —\n * `hooks.BeforeTool[]` in `.gemini/settings.json` or `~/.gemini/settings.json`; regex matcher\n * over `run_shell_command`, `write_file`, `replace`, `mcp_…`; `timeout` in milliseconds.\n */\nimport { copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport type { HookClient } from \"@agentwares/agentguard-core\";\n\nexport type InstallScope = \"project\" | \"user\";\n\nexport interface HookTarget {\n client: HookClient;\n label: string;\n scope: InstallScope;\n settingsPath: string;\n event: \"PreToolUse\" | \"BeforeTool\";\n matcher: string;\n handler: Record<string, unknown>;\n /** what the user has to do in the client before the hook runs */\n note?: string;\n}\n\n/** Tools worth a check: the shell, file writes and MCP tools. Reads are left alone. */\nexport const MATCHERS: Record<HookClient, string> = {\n \"claude-code\": \"^(Bash|PowerShell|Write|Edit|MultiEdit|NotebookEdit)$|^mcp__\",\n codex: \"^(Bash|apply_patch)$|^mcp__\",\n \"gemini-cli\": \"^(run_shell_command|write_file|replace)$|^mcp_\",\n};\n\nexport const CLIENT_ALIASES: Record<string, HookClient> = {\n claude: \"claude-code\",\n \"claude-code\": \"claude-code\",\n codex: \"codex\",\n gemini: \"gemini-cli\",\n \"gemini-cli\": \"gemini-cli\",\n};\n\nexport function hookTarget(\n client: HookClient,\n scope: InstallScope,\n where: { cwd: string; home: string },\n command: string,\n timeoutS = 30,\n): HookTarget {\n const root = scope === \"project\" ? where.cwd : where.home;\n if (client === \"claude-code\")\n return {\n client,\n label: \"Claude Code\",\n scope,\n settingsPath: join(root, \".claude\", \"settings.json\"),\n event: \"PreToolUse\",\n matcher: MATCHERS[client],\n handler: { type: \"command\", command, timeout: timeoutS, statusMessage: \"agentguard\" },\n };\n if (client === \"codex\")\n return {\n client,\n label: \"Codex CLI\",\n scope,\n settingsPath: join(root, \".codex\", \"hooks.json\"),\n event: \"PreToolUse\",\n matcher: MATCHERS[client],\n handler: { type: \"command\", command, timeout: timeoutS, statusMessage: \"agentguard\" },\n note: \"Codex runs a new hook only after you trust it: open /hooks in Codex and trust the agentguard entry.\",\n };\n return {\n client,\n label: \"Gemini CLI\",\n scope,\n settingsPath: join(root, \".gemini\", \"settings.json\"),\n event: \"BeforeTool\",\n matcher: MATCHERS[client],\n handler: {\n name: \"agentguard\",\n type: \"command\",\n command,\n timeout: timeoutS * 1000,\n description: \"agentguard: one rulebook for shell commands and file edits\",\n },\n note:\n scope === \"project\"\n ? \"Gemini CLI fingerprints project hooks: confirm the agentguard hook the first time it asks.\"\n : undefined,\n };\n}\n\n/** Is this hook command one agentguard wrote? */\nexport function isAgentguardHookCommand(command: unknown): boolean {\n return (\n typeof command === \"string\" &&\n /agentguard/.test(command) &&\n /\\bhook\\s+pre-tool-use\\b/.test(command)\n );\n}\n\ntype Json = Record<string, unknown>;\ninterface MatcherGroup {\n matcher?: string;\n hooks?: Json[];\n [k: string]: unknown;\n}\n\nfunction readSettings(path: string): Json {\n if (!existsSync(path)) return {};\n const text = readFileSync(path, \"utf8\");\n if (!text.trim()) return {};\n let parsed: unknown;\n try {\n parsed = JSON.parse(text);\n } catch (err) {\n throw new Error(\n `${path} is not valid JSON (${err instanceof Error ? err.message : String(err)}); fix it or move it aside — agentguard will not overwrite it`,\n { cause: err },\n );\n }\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed))\n throw new Error(`${path} is not a JSON object; agentguard will not overwrite it`);\n return parsed as Json;\n}\n\nfunction groupsOf(settings: Json, event: string): MatcherGroup[] {\n const hooks = settings.hooks;\n if (!hooks || typeof hooks !== \"object\") return [];\n const groups = (hooks as Json)[event];\n return Array.isArray(groups) ? (groups as MatcherGroup[]) : [];\n}\n\n/** The agentguard handlers currently in a settings file. */\nexport function installedHandlers(target: HookTarget): Json[] {\n const settings = readSettings(target.settingsPath);\n return groupsOf(settings, target.event).flatMap((g) =>\n (g.hooks ?? []).filter((h) => isAgentguardHookCommand(h.command)),\n );\n}\n\n/**\n * Write (or update in place) the agentguard entry, keeping every other setting and hook. The\n * first change to an existing file leaves a `*.agentguard-backup` next to it.\n */\nexport function installHook(target: HookTarget): {\n status: \"added\" | \"updated\" | \"unchanged\";\n backup?: string;\n} {\n const existed = existsSync(target.settingsPath);\n const settings = readSettings(target.settingsPath);\n const hooks = (\n settings.hooks && typeof settings.hooks === \"object\" ? settings.hooks : {}\n ) as Json;\n const groups = groupsOf(settings, target.event);\n const isOurs = (h: Json): boolean => isAgentguardHookCommand(h.command);\n const ours = groups.flatMap((g) => (g.hooks ?? []).filter(isOurs));\n const exact = groups.some(\n (g) =>\n g.matcher === target.matcher &&\n g.hooks?.length === 1 &&\n JSON.stringify(g.hooks[0]) === JSON.stringify(target.handler),\n );\n if (exact && ours.length === 1) return { status: \"unchanged\" };\n const kept: MatcherGroup[] = [];\n for (const group of groups) {\n if (!(group.hooks ?? []).some(isOurs)) {\n kept.push(group);\n continue;\n }\n const others = (group.hooks ?? []).filter((h) => !isOurs(h));\n if (others.length > 0) kept.push({ ...group, hooks: others });\n }\n kept.push({ matcher: target.matcher, hooks: [target.handler] });\n const status = ours.length > 0 ? \"updated\" : \"added\";\n hooks[target.event] = kept;\n settings.hooks = hooks;\n let backup: string | undefined;\n if (existed) {\n backup = `${target.settingsPath}.agentguard-backup`;\n if (!existsSync(backup)) copyFileSync(target.settingsPath, backup);\n }\n mkdirSync(dirname(target.settingsPath), { recursive: true });\n writeFileSync(target.settingsPath, JSON.stringify(settings, null, 2) + \"\\n\");\n return { status, backup };\n}\n\n/** Remove agentguard's entries; other hooks and settings stay. Returns how many were removed. */\nexport function uninstallHook(target: HookTarget): number {\n if (!existsSync(target.settingsPath)) return 0;\n const settings = readSettings(target.settingsPath);\n const groups = groupsOf(settings, target.event);\n let removed = 0;\n const kept: MatcherGroup[] = [];\n for (const group of groups) {\n const others = (group.hooks ?? []).filter((h) => !isAgentguardHookCommand(h.command));\n removed += (group.hooks ?? []).length - others.length;\n if (others.length > 0) kept.push({ ...group, hooks: others });\n }\n if (removed === 0) return 0;\n const hooks = settings.hooks as Json;\n if (kept.length > 0) hooks[target.event] = kept;\n else delete hooks[target.event];\n if (Object.keys(hooks).length === 0) delete settings.hooks;\n writeFileSync(target.settingsPath, JSON.stringify(settings, null, 2) + \"\\n\");\n return removed;\n}\n\n/** Every settings file that can hold a hook, project and user level: edits to them are guard-config. */\nexport function hookSettingsFiles(where: { cwd: string; home: string }): string[] {\n const out: string[] = [];\n for (const root of [where.cwd, where.home]) {\n out.push(\n join(root, \".claude\", \"settings.json\"),\n join(root, \".claude\", \"settings.local.json\"),\n join(root, \".codex\", \"hooks.json\"),\n join(root, \".codex\", \"config.toml\"),\n join(root, \".gemini\", \"settings.json\"),\n );\n }\n out.push(join(where.home, \".agentguard\", \"agentguard.yaml\"));\n return out;\n}\n","/**\n * `agentguard hooks install|uninstall|status [--project|--user] [--client claude|codex|gemini]`\n *\n * Install writes the coding agent's pre-execution hook entry (Claude Code `PreToolUse`, Codex\n * `PreToolUse`, Gemini CLI `BeforeTool`) pointing at `agentguard hook pre-tool-use`, and makes\n * sure the policy has a `hooks:` block in dry-run. Uninstall removes only agentguard's entries.\n */\nimport { appendFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, join, relative, resolve } from \"node:path\";\nimport type { HookClient } from \"@agentwares/agentguard-core\";\nimport { flagBool, flagList, flagNumber, flagString, type ParsedArgs } from \"../args.js\";\nimport { homeFrom, type Io } from \"../context.js\";\nimport {\n CLIENT_ALIASES,\n hookTarget,\n installHook,\n installedHandlers,\n uninstallHook,\n type InstallScope,\n} from \"../hooks/clients.js\";\nimport { PROXY_PACKAGE } from \"../configs.js\";\nimport { version } from \"../version.js\";\n\n/** The commented `hooks:` block: the file people read, so every knob explains itself. */\nexport const HOOKS_POLICY_BLOCK = `\n# Hook mode: your coding agent's own shell commands and file edits (Claude Code, Codex, Gemini CLI),\n# checked before they run. \\`agentguard hooks install\\` wired it; \\`agentguard report\\` shows the decisions.\nhooks:\n # dry-run: every decision is logged and nothing is blocked. Read \\`agentguard report\\`, then set\n # enforce. The kill switch (\\`agentguard kill\\`) stops guarded calls in both modes.\n mode: dry-run\n # Irreversible commands run only on a turn a person typed: after the session's previous\n # irreversible command, recent, and naming the action (\"push it\", or \"yes\" to \"shall I push?\").\n # Text the model writes, tool output and injected messages never count. Otherwise the agent\n # gets APPROVAL_REQUIRED and an id; \\`agentguard approve <id>\\` lets that exact command run once.\n # Built in: git-push, merge, tag-delete, rm-outside-workspace, publish, send, guard-config.\n irreversible:\n builtins: true\n window_s: 1800 # the authorizing turn is at most 30 minutes old\n require_mention: true # ...and names the action\n require_origin: false # true: only entries Claude Code labels as typed by a person\n mentions: {} # extra words per class, e.g. { git-push: [deploy] }\n rules: []\n # - name: deploy\n # shell: [\"vercel --prod*\", \"fly deploy*\"]\n # mentions: [deploy]\n shell:\n deny: [] # e.g. [\"terraform destroy*\", \"curl * | sh\"]\n approval: [] # e.g. [\"kubectl delete *\"]\n paths:\n deny: [] # e.g. [\".env\", \"*.pem\"]\n approval: [] # e.g. [\"**/migrations/**\"]\n`;\n\n/** A policy for a project that has no agentguard.yaml yet: hooks only, no MCP upstreams. */\nexport function renderHooksStarterPolicy(generatedAt = new Date()): string {\n return `# agentguard.yaml — generated by \\`agentguard hooks install\\` on ${generatedAt.toISOString().slice(0, 10)}\n# Docs: https://github.com/agentwares/agentguard/tree/main/apps/agentguard-cli#hook-mode-a-coding-agents-own-commands\nversion: 1\n\n# MCP proxy mode (agentguard init) reads upstreams; hook mode needs none.\nmode: dry-run\nupstreams: []\n${HOOKS_POLICY_BLOCK}\n# Kill switch: \\`agentguard kill\\` creates this file; every guarded call is refused until\n# \\`agentguard resume\\`. AGENTGUARD_KILL=1 in the environment does the same.\nkill:\n file: .agentguard/KILL\n\n# Hash-chained JSONL of every decision; \\`agentguard verify\\` proves it was not edited.\naudit:\n path: .agentguard/audit.jsonl\n redact: true\n`;\n}\n\nfunction quoteArg(arg: string): string {\n return /^[A-Za-z0-9_@%+=:,./-]+$/.test(arg) ? arg : JSON.stringify(arg);\n}\n\nfunction clientsFrom(args: ParsedArgs): HookClient[] {\n const names = flagList(args, \"client\");\n if (names.length === 0) return [\"claude-code\"];\n if (names.includes(\"all\")) return [\"claude-code\", \"codex\", \"gemini-cli\"];\n return names.map((n) => {\n const c = CLIENT_ALIASES[n.trim()];\n if (!c) throw new Error(`unknown --client \"${n}\" (claude, codex, gemini or all)`);\n return c;\n });\n}\n\nfunction hasTopLevelHooks(yamlText: string): boolean {\n return /^hooks\\s*:/m.test(yamlText);\n}\n\nexport async function hooksCommand(args: ParsedArgs, io: Io): Promise<number> {\n const sub = args.positionals[0] ?? \"status\";\n const scope: InstallScope = flagBool(args, \"user\") ? \"user\" : \"project\";\n const home = homeFrom(io);\n const where = { cwd: io.cwd, home };\n const rel = (p: string): string => {\n const r = relative(io.cwd, p);\n return r.startsWith(\"..\") ? p : r || \".\";\n };\n const clients = clientsFrom(args);\n const policyPath = resolve(\n io.cwd,\n flagString(args, \"config\") ??\n (scope === \"user\" ? join(home, \".agentguard\", \"agentguard.yaml\") : \"agentguard.yaml\"),\n );\n const base = flagString(args, \"command\") ?? `npx -y ${PROXY_PACKAGE}@${version()}`;\n const commandFor = (client: HookClient): string => {\n let cmd = `${base} hook pre-tool-use --client ${client === \"claude-code\" ? \"claude\" : client === \"gemini-cli\" ? \"gemini\" : \"codex\"}`;\n if (flagString(args, \"config\")) cmd += ` --config ${quoteArg(policyPath)}`;\n else if (scope === \"user\") cmd += ` --fallback-config ${quoteArg(policyPath)}`;\n return cmd;\n };\n const timeoutS = Math.max(30, flagNumber(args, \"timeout\") ?? 30);\n\n if (sub === \"install\") {\n // the policy first: a hook with no policy to read guards nothing\n if (!existsSync(policyPath)) {\n mkdirSync(dirname(policyPath), { recursive: true });\n writeFileSync(policyPath, renderHooksStarterPolicy());\n io.out(`wrote ${rel(policyPath)} (hooks.mode: dry-run)`);\n } else if (!hasTopLevelHooks(readFileSync(policyPath, \"utf8\"))) {\n appendFileSync(policyPath, HOOKS_POLICY_BLOCK);\n io.out(`added a hooks: block to ${rel(policyPath)} (hooks.mode: dry-run)`);\n } else io.out(`kept ${rel(policyPath)} (it already has a hooks: block)`);\n\n for (const client of clients) {\n const target = hookTarget(client, scope, where, commandFor(client), timeoutS);\n const { status, backup } = installHook(target);\n const verb =\n status === \"unchanged\" ? \"kept \" : status === \"updated\" ? \"updated\" : \"added \";\n io.out(\n `${verb} ${target.label} ${target.event} hook in ${rel(target.settingsPath)}${backup ? ` (backup: ${rel(backup)})` : \"\"}`,\n );\n if (target.note) io.out(` ${target.note}`);\n }\n\n if (scope === \"project\" && existsSync(join(io.cwd, \".git\"))) {\n const gitignore = join(io.cwd, \".gitignore\");\n const text = existsSync(gitignore) ? readFileSync(gitignore, \"utf8\") : \"\";\n if (!/^\\/?\\.agentguard\\/?$/m.test(text)) {\n appendFileSync(gitignore, `${text && !text.endsWith(\"\\n\") ? \"\\n\" : \"\"}.agentguard/\\n`);\n io.out(\n `added .agentguard/ to .gitignore (approvals, counters and the audit log stay local)`,\n );\n }\n }\n\n io.out(\"\");\n io.out(\"Next:\");\n io.out(\" 1. start a new session of your coding agent (hooks are read at start)\");\n io.out(\" 2. work as usual — hooks.mode is dry-run: decisions are logged, nothing is blocked\");\n io.out(\" 3. agentguard report # what enforce mode would have stopped, and why\");\n io.out(` 4. set \\`hooks.mode: enforce\\` in ${rel(policyPath)} when it looks right`);\n io.out(\" undo: agentguard hooks uninstall\" + (scope === \"user\" ? \" --user\" : \"\"));\n return 0;\n }\n\n if (sub === \"uninstall\") {\n let total = 0;\n for (const client of flagString(args, \"client\")\n ? clients\n : ([\"claude-code\", \"codex\", \"gemini-cli\"] as HookClient[])) {\n const target = hookTarget(client, scope, where, commandFor(client), timeoutS);\n const removed = uninstallHook(target);\n total += removed;\n if (removed) io.out(`removed ${target.label} hook from ${rel(target.settingsPath)}`);\n }\n if (total === 0) io.out(`no agentguard hooks in ${scope}-level settings`);\n else\n io.out(\n `kept ${rel(policyPath)} and .agentguard/ (delete them yourself if you want them gone)`,\n );\n return 0;\n }\n\n if (sub === \"status\") {\n for (const s of [\"project\", \"user\"] as InstallScope[]) {\n for (const client of [\"claude-code\", \"codex\", \"gemini-cli\"] as HookClient[]) {\n const target = hookTarget(client, s, where, \"\", timeoutS);\n let handlers: Record<string, unknown>[];\n try {\n handlers = installedHandlers(target);\n } catch (err) {\n io.out(\n `${s.padEnd(7)} ${target.label.padEnd(11)} unreadable: ${err instanceof Error ? err.message : String(err)}`,\n );\n continue;\n }\n io.out(\n `${s.padEnd(7)} ${target.label.padEnd(11)} ${handlers.length ? `installed: ${String(handlers[0]!.command)}` : \"—\"} (${rel(target.settingsPath)})`,\n );\n }\n }\n return 0;\n }\n\n io.err(\n \"usage: agentguard hooks install|uninstall|status [--project|--user] [--client claude|codex|gemini|all] [--command cmd] [--config path]\",\n );\n return 1;\n}\n"],"mappings":"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","names":["existsSync","mkdirSync","readFileSync","writeFileSync","dirname","join","join","existsSync","mkdirSync","dirname","writeFileSync","readFileSync"]}
@@ -0,0 +1,31 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __commonJS = (cb, mod) => function __require() {
8
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
19
+ // If the importer is in node compatibility mode or this is not an ESM
20
+ // file that has been converted to a CommonJS file using a Babel-
21
+ // compatible transform (i.e. "__esModule" has not been set), then set
22
+ // "default" to the CommonJS "module.exports" for node compatibility.
23
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
24
+ mod
25
+ ));
26
+
27
+ export {
28
+ __commonJS,
29
+ __toESM
30
+ };
31
+ //# sourceMappingURL=chunk-5WRI5ZAA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}