@agentwares/agentguard 0.1.9 → 0.1.10

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 (62) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/dist/audit-5LUDXZLG.js +18 -0
  3. package/dist/chunk-2QDPPTPY.js +179 -0
  4. package/dist/chunk-2QDPPTPY.js.map +1 -0
  5. package/dist/{chunk-SUXQTT3X.js → chunk-4WTFMFRY.js} +18 -16
  6. package/dist/chunk-4WTFMFRY.js.map +1 -0
  7. package/dist/{chunk-VQWQ5TOM.js → chunk-DEVXG3IB.js} +4 -4
  8. package/dist/chunk-DEVXG3IB.js.map +1 -0
  9. package/dist/chunk-F73VDY3W.js +202 -0
  10. package/dist/chunk-F73VDY3W.js.map +1 -0
  11. package/dist/{chunk-X4M7YWQA.js → chunk-IEJK7N3B.js} +32 -27
  12. package/dist/chunk-IEJK7N3B.js.map +1 -0
  13. package/dist/{chunk-ZSLWPKXI.js → chunk-IS3DAHZI.js} +562 -8
  14. package/dist/chunk-IS3DAHZI.js.map +1 -0
  15. package/dist/{chunk-KRKZGAJ3.js → chunk-JSELR4SG.js} +66 -55
  16. package/dist/chunk-JSELR4SG.js.map +1 -0
  17. package/dist/{chunk-TW5KJREH.js → chunk-OM5L7A32.js} +20 -11
  18. package/dist/chunk-OM5L7A32.js.map +1 -0
  19. package/dist/{chunk-HPYZ3JDX.js → chunk-SWZQMPDG.js} +3 -3
  20. package/dist/{chunk-HPYZ3JDX.js.map → chunk-SWZQMPDG.js.map} +1 -1
  21. package/dist/{chunk-D66U3PVB.js → chunk-TJXZBOHL.js} +6 -6
  22. package/dist/chunk-TJXZBOHL.js.map +1 -0
  23. package/dist/{chunk-BKXXTWIS.js → chunk-XOBFANL4.js} +5 -5
  24. package/dist/chunk-XOBFANL4.js.map +1 -0
  25. package/dist/chunk-XPNBYSIN.js +23 -0
  26. package/dist/chunk-XPNBYSIN.js.map +1 -0
  27. package/dist/{chunk-6S7LYVOC.js → chunk-YBVD6HTT.js} +27 -24
  28. package/dist/chunk-YBVD6HTT.js.map +1 -0
  29. package/dist/{chunk-6TUQD666.js → chunk-ZG4LGUJE.js} +100 -81
  30. package/dist/chunk-ZG4LGUJE.js.map +1 -0
  31. package/dist/cli.js +6 -4
  32. package/dist/fixtures/crm-server.js +2 -2
  33. package/dist/fixtures/demo-agent.js +1 -1
  34. package/dist/index.d.ts +5 -5
  35. package/dist/index.js +23 -21
  36. package/dist/index.js.map +1 -1
  37. package/dist/init-MKPQU2JG.js +17 -0
  38. package/dist/{proxy-3Z5YEZ4R.js → proxy-6GP63TLD.js} +21 -29
  39. package/dist/proxy-6GP63TLD.js.map +1 -0
  40. package/dist/tools-XS7PMTLT.js +15 -0
  41. package/llms.txt +8 -6
  42. package/package.json +10 -4
  43. package/server.json +9 -9
  44. package/dist/audit-2YCMHMCP.js +0 -17
  45. package/dist/chunk-3O6KWT3E.js +0 -345
  46. package/dist/chunk-3O6KWT3E.js.map +0 -1
  47. package/dist/chunk-6S7LYVOC.js.map +0 -1
  48. package/dist/chunk-6TUQD666.js.map +0 -1
  49. package/dist/chunk-BKXXTWIS.js.map +0 -1
  50. package/dist/chunk-D66U3PVB.js.map +0 -1
  51. package/dist/chunk-KRKZGAJ3.js.map +0 -1
  52. package/dist/chunk-SUXQTT3X.js.map +0 -1
  53. package/dist/chunk-TW5KJREH.js.map +0 -1
  54. package/dist/chunk-VQWQ5TOM.js.map +0 -1
  55. package/dist/chunk-X4M7YWQA.js.map +0 -1
  56. package/dist/chunk-ZSLWPKXI.js.map +0 -1
  57. package/dist/init-CWROGV5I.js +0 -15
  58. package/dist/proxy-3Z5YEZ4R.js.map +0 -1
  59. package/dist/tools-3LLDG3XQ.js +0 -15
  60. /package/dist/{audit-2YCMHMCP.js.map → audit-5LUDXZLG.js.map} +0 -0
  61. /package/dist/{init-CWROGV5I.js.map → init-MKPQU2JG.js.map} +0 -0
  62. /package/dist/{tools-3LLDG3XQ.js.map → tools-XS7PMTLT.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/audit.ts","../src/audit/cache.ts","../src/audit/enforce.ts","../src/audit/read.ts","../src/audit/repo.ts","../src/audit/sources.ts"],"sourcesContent":["/**\n * `okgate audit [--since 7d|30d|all|YYYY-MM-DD] [--client claude|codex|all] [--json]\n * [--enforce [--preview] [--yes]]`\n *\n * Which written rules the coding agents broke in this repository: the rules come from the repo's\n * CLAUDE.md, AGENTS.md, GEMINI.md, .cursor/rules (and okgate.yaml `audit.rules`); the\n * sessions are this machine's Claude Code and Codex transcripts whose working directory is in the\n * repo. Per rule: sessions checked, sessions broken, the last three dates — and on screen only,\n * the command or path that broke it. No network, no telemetry, no LLM: nothing leaves the\n * machine. `--json` (what `/okgate:audit` reads) carries counts, rule ids and dates, never a\n * command, a path or a prompt from a transcript.\n *\n * `--enforce` writes the checkable rules into okgate.yaml as hook-mode rules — in dry-run;\n * it never switches `hooks.mode` to enforce — shows the diff, and installs the hook if it is not.\n */\nimport { writeFileSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { basename, join, resolve } from \"node:path\";\nimport { findPolicyFile } from \"@agentwares/agentguard-core/node\";\nimport {\n NOT_CHECKABLE_HINT,\n applicableNoun,\n describeStep,\n evaluateChecks,\n extractRules,\n planEnforcement,\n stableHash,\n summarizeAudit,\n type AuditClient,\n type AuditContext,\n type AuditStep,\n type GroupAudit,\n type LocatedBreak,\n type Rule,\n type RuleCheck,\n type RuleSummary,\n STATE_DIR,\n envTwin,\n} from \"@agentwares/agentguard-core\";\nimport { flagBool, flagList, flagString, parseArgs, type ParsedArgs } from \"../args.js\";\nimport { homeFrom, type Io } from \"../context.js\";\nimport { AuditCache, sha } from \"../audit/cache.js\";\nimport { applyEnforcePlan, lineDiff } from \"../audit/enforce.js\";\nimport { fetchSteps, readGroup } from \"../audit/read.js\";\nimport { findRepo, readConfigRules, readRuleFiles, repoMatcher } from \"../audit/repo.js\";\nimport {\n claudeGroups,\n claudeProjectDirs,\n codexGroups,\n sourceDirs,\n type TranscriptGroup,\n} from \"../audit/sources.js\";\nimport { installedHandlers, hookTarget } from \"../hooks/clients.js\";\nimport { version } from \"../version.js\";\nimport { hooksCommand } from \"./hooks.js\";\n\n/** The willingness-to-pay test: a page that says what the team view would be, and one button. */\nexport const TEAM_HISTORY_URL = \"https://agentwares-agentguard.vercel.app/team-history\";\nexport const TEAM_HISTORY_LINE = `Team adherence history across repos and developers is coming — ${TEAM_HISTORY_URL}`;\n\nconst CLIENT_LABEL: Record<AuditClient, string> = { \"claude-code\": \"Claude Code\", codex: \"Codex\" };\n\n/** `7d`, `30d`, `24h`, `all`, or a date. Undefined: all history. */\nexport function parseSince(value: string | undefined, now: Date): number | undefined {\n const v = (value ?? \"7d\").trim().toLowerCase();\n if (v === \"all\") return undefined;\n const rel = /^(\\d+)\\s*([dhw])$/.exec(v);\n if (rel) {\n const n = Number(rel[1]);\n const unit = rel[2] === \"h\" ? 3_600_000 : rel[2] === \"w\" ? 7 * 86_400_000 : 86_400_000;\n return now.getTime() - n * unit;\n }\n const t = Date.parse(/^\\d{4}-\\d{2}-\\d{2}$/.test(v) ? `${v}T00:00:00` : v);\n if (!Number.isFinite(t))\n throw new Error(`--since \"${value}\": use 7d, 30d, 24h, all or a date (YYYY-MM-DD)`);\n return t;\n}\n\nfunction clientsFrom(args: ParsedArgs): AuditClient[] {\n const names = flagList(args, \"client\").map((n) => n.trim().toLowerCase());\n if (names.length === 0 || names.includes(\"all\")) return [\"claude-code\", \"codex\"];\n return names.map((n) => {\n if (n === \"claude\" || n === \"claude-code\") return \"claude-code\";\n if (n === \"codex\") return \"codex\";\n throw new Error(`unknown --client \"${n}\" (claude, codex or all)`);\n });\n}\n\nconst pad = (n: number): string => String(n).padStart(2, \"0\");\nconst localTime = (ms: number): string => {\n const d = new Date(ms);\n return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}`;\n};\nconst localDay = (ms: number): string => localTime(ms).slice(0, 10);\nconst plural = (n: number, one: string, many = `${one}s`): string => `${n} ${n === 1 ? one : many}`;\nconst clip = (s: string, n: number): string => (s.length > n ? `${s.slice(0, n - 1)}…` : s);\n\ninterface Entry {\n group?: TranscriptGroup;\n audit: GroupAudit;\n /** steps kept from a group read this run, for the evidence */\n steps?: Map<string, AuditStep>;\n}\n\ninterface SourceCount {\n transcripts: number;\n read: number;\n cached: number;\n retained: number;\n /** groups last written before the window: not read */\n older: number;\n}\n\nasync function pool<T>(\n items: readonly T[],\n size: number,\n work: (item: T) => Promise<void>,\n): Promise<void> {\n let next = 0;\n const run = async (): Promise<void> => {\n while (next < items.length) await work(items[next++]!);\n };\n await Promise.all(Array.from({ length: Math.min(size, items.length) }, run));\n}\n\n/** The hook-rule list a check would be enforced through, or \"audit-only\". */\nfunction enforceTarget(check: RuleCheck): string {\n switch (check.spec.kind) {\n case \"run-before\":\n case \"no-commit-to\":\n return \"audit-only\";\n case \"no-edit\":\n return \"hooks.paths.deny\";\n case \"no-new-deps\":\n return check.spec.unlessAsked ? \"hooks.shell.approval\" : \"hooks.shell.deny\";\n case \"no-rm-outside\":\n case \"no-publish\":\n return \"hooks.irreversible.builtins\";\n case \"no-deploy\":\n return \"hooks.irreversible.rules\";\n default:\n return \"hooks.shell.deny\";\n }\n}\n\nexport async function auditCommand(args: ParsedArgs, io: Io): Promise<number> {\n const now = new Date();\n const json = flagBool(args, \"json\") === true;\n const since = parseSince(flagString(args, \"since\"), now);\n const clients = clientsFrom(args);\n const home = homeFrom(io);\n const repo = findRepo(resolve(io.cwd, flagString(args, \"repo\") ?? \".\"));\n const named = flagString(args, \"config\") ?? envTwin(io.env, \"CONFIG\");\n const policyPath =\n named !== undefined ? resolve(repo.checkout, named) : findPolicyFile(repo.checkout);\n\n // the rules\n const files = readRuleFiles(repo.checkout, flagList(args, \"rules\"));\n const config = readConfigRules(policyPath);\n const { rules, errors } = extractRules(files, config.rules, basename(policyPath));\n const warnings = [\n ...(config.warning ? [config.warning] : []),\n ...errors.map((e) => `${e.file}:${e.line}: ${e.message}`),\n ];\n const checks = rules.flatMap((r) => r.checks);\n const keys = [...new Set(checks.map((c) => c.key))];\n\n if (flagBool(args, \"enforce\")) return enforce(args, io, rules, policyPath, repo.checkout, json);\n\n // the sessions\n const dirs = sourceDirs(io.env, home, {\n claudeDir: flagString(args, \"claude-dir\"),\n codexDir: flagString(args, \"codex-dir\"),\n });\n const groups: TranscriptGroup[] = [\n ...(clients.includes(\"claude-code\")\n ? claudeGroups(claudeProjectDirs(dirs[\"claude-code\"], repo.root))\n : []),\n ...(clients.includes(\"codex\") ? codexGroups(dirs.codex) : []),\n ];\n const cache = new AuditCache(\n resolve(io.cwd, flagString(args, \"cache-dir\") ?? join(home, STATE_DIR)),\n sha(repo.root),\n flagBool(args, \"cache\") !== false,\n );\n const inRepo = repoMatcher(repo.root);\n const ctx: AuditContext = {\n repoRoot: repo.root,\n home,\n tmpDirs: [\n tmpdir(),\n io.env.TMPDIR ?? \"\",\n \"/tmp\",\n \"/private/tmp\",\n \"/var/folders\",\n \"/private/var/folders\",\n ].filter(Boolean),\n };\n const counts: Record<AuditClient, SourceCount> = {\n \"claude-code\": { transcripts: 0, read: 0, cached: 0, retained: 0, older: 0 },\n codex: { transcripts: 0, read: 0, cached: 0, retained: 0, older: 0 },\n };\n const entries: Entry[] = [];\n const evidence = !json && flagBool(args, \"evidence\") !== false;\n await pool(groups, 6, async (group) => {\n const c = counts[group.client];\n c.transcripts += group.files.length;\n const hit = cache.lookup(group, keys);\n if (hit) {\n c.cached += group.files.length;\n entries.push({ group, audit: hit });\n return;\n }\n if (since !== undefined && group.lastWrite < since) {\n c.older += group.files.length;\n return;\n }\n let read;\n try {\n read = await readGroup(group, { inRepo });\n } catch {\n return; // unreadable (permissions, deleted mid-run): skip, never fail the audit\n }\n c.read += group.files.length;\n const audit = evaluateChecks(checks, read, ctx);\n cache.store(group, audit);\n const hasBreaks = Object.values(audit.checks).some((o) => o.breaks.length > 0);\n entries.push({\n group,\n audit,\n ...(evidence && hasBreaks\n ? { steps: new Map(read.steps.map((s) => [stableHash(s.id), s])) }\n : {}),\n });\n });\n const present = new Set(groups.map((g) => cache.groupKey(g)));\n for (const client of clients)\n for (const audit of cache.retained(present, client)) {\n counts[client].retained += 1;\n entries.push({ audit });\n }\n\n const summary = summarizeAudit(\n rules,\n entries.map((e) => e.audit),\n { since },\n );\n const plan = planEnforcement(rules);\n const enforceable = new Set([\n ...plan.items.map((i) => i.rule.id),\n ...plan.builtins.map((b) => b.rule.id),\n ...plan.irreversible.map((r) => r.rule.id),\n ]);\n\n if (json) {\n io.out(\n JSON.stringify(\n {\n tool: \"okgate audit\",\n version: version(),\n repo: repo.root,\n checkout: repo.checkout,\n since: since === undefined ? null : new Date(since).toISOString(),\n until: now.toISOString(),\n rule_files: files.map((f) => f.path),\n sources: counts,\n sessions: {\n total: summary.sessions,\n \"claude-code\": summary.sessionsByClient[\"claude-code\"],\n codex: summary.sessionsByClient.codex,\n },\n unread_tool_calls: summary.unread,\n rules: summary.rules.map((r) => ({\n id: r.rule.id,\n n: r.rule.n,\n file: r.rule.file,\n line: r.rule.line,\n text: r.rule.text,\n status: r.status,\n checkable: r.rule.checks.length > 0,\n ...(r.rule.silenced ? { marked_not_checkable: true } : {}),\n sessions_broken: r.sessionsBroken,\n last_broken: r.last.map((b) => new Date(b.at).toISOString()),\n checks: r.checks.map((c, k) => ({\n check: c.label,\n kind: c.kind,\n via: c.via,\n enforce: enforceTarget(r.rule.checks[k]!),\n sessions_applicable: c.sessionsApplicable,\n sessions_broken: c.sessionsBroken,\n sessions_on_request: c.sessionsOnRequest,\n sessions_undetermined: c.sessionsUndetermined,\n breaks: c.breaks,\n refused: c.refused,\n })),\n })),\n not_checkable: {\n count: summary.rules.filter((r) => r.status === \"not-checkable\").length,\n hint: NOT_CHECKABLE_HINT,\n },\n warnings,\n enforce: {\n command: \"okgate audit --enforce\",\n rules: enforceable.size,\n note: \"writes hook-mode rules into okgate.yaml in dry-run; nothing is blocked until hooks.mode is enforce\",\n },\n team_history: { available: false, url: TEAM_HISTORY_URL },\n privacy:\n \"counts, rule ids and dates only: no command, path or prompt from a transcript is in this output, and nothing was sent anywhere\",\n },\n null,\n 2,\n ),\n );\n return 0;\n }\n\n // evidence for the latest breaks, on this screen only\n const lines = new Map<string, string>();\n if (evidence) {\n const wanted = new Map<number, LocatedBreak[]>();\n for (const r of summary.rules)\n for (const b of r.last) {\n const list = wanted.get(b.group) ?? [];\n list.push(b);\n wanted.set(b.group, list);\n }\n for (const [gi, breaks] of wanted) {\n const entry = entries[gi];\n if (!entry?.group) continue;\n let steps = entry.steps;\n if (!steps) {\n try {\n steps = await fetchSteps(entry.group, breaks, { inRepo });\n } catch {\n continue;\n }\n }\n for (const b of breaks) {\n const step = steps.get(b.step);\n if (step) lines.set(`${gi}:${b.step}:${b.what}:${b.index}`, describeStep(step, b, ctx));\n }\n }\n }\n\n renderHuman(io, {\n root: repo.root,\n since,\n files: files.map((f) => f.path),\n counts,\n clients,\n summary,\n evidence: evidence\n ? (b) =>\n lines.get(`${b.group}:${b.step}:${b.what}:${b.index}`) ?? \"(transcript no longer on disk)\"\n : () => undefined,\n enforceable: enforceable.size,\n warnings,\n });\n return 0;\n}\n\ninterface View {\n root: string;\n since?: number;\n files: string[];\n counts: Record<AuditClient, SourceCount>;\n clients: AuditClient[];\n summary: ReturnType<typeof summarizeAudit>;\n evidence: (b: LocatedBreak) => string | undefined;\n enforceable: number;\n warnings: string[];\n}\n\nfunction ruleHead(r: RuleSummary): string {\n const id = `R${r.rule.n}`.padEnd(4);\n return ` ${id} ${clip(r.rule.text, 78)} (${r.rule.file}:${r.rule.line})`;\n}\n\nfunction renderHuman(io: Io, v: View): void {\n const s = v.summary;\n const window = v.since === undefined ? \"all history\" : `since ${localDay(v.since)}`;\n io.out(`okgate audit — ${v.root} · ${window}`);\n const read = v.clients.map((c) => {\n const n = v.counts[c];\n const parts = [`${n.read} read`, `${n.cached} from cache`];\n if (n.retained) parts.push(`${n.retained} kept from deleted transcripts`);\n if (n.older) parts.push(`${n.older} older than the window`);\n return `${CLIENT_LABEL[c]}: ${plural(n.transcripts, \"transcript\")} (${parts.join(\", \")})`;\n });\n io.out(read.join(\" · \"));\n const byClient = v.clients\n .filter((c) => s.sessionsByClient[c] > 0)\n .map((c) => `${CLIENT_LABEL[c]} ${s.sessionsByClient[c]}`);\n io.out(\n `${plural(s.sessions, \"session\")} in this repository${byClient.length ? ` (${byClient.join(\", \")})` : \"\"}. Read on this machine; nothing was sent anywhere.`,\n );\n if (s.unread > 0)\n io.out(\n `${plural(s.unread, \"Codex tool call\")} ran JavaScript (\\`exec\\`), not a command line, and ${s.unread === 1 ? \"was\" : \"were\"} not read.`,\n );\n for (const w of v.warnings) io.out(`warning: ${w}`);\n io.out(\"\");\n\n if (v.files.length === 0 && s.rules.length === 0) {\n io.out(\n \"No rule files here (CLAUDE.md, AGENTS.md, GEMINI.md, .cursor/rules, …) and no audit.rules in okgate.yaml: nothing to audit.\",\n );\n io.out(\"\");\n io.out(TEAM_HISTORY_LINE);\n return;\n }\n const checkable = s.rules.filter((r) => r.status !== \"not-checkable\");\n const perFile = new Map<string, number>();\n for (const r of s.rules) perFile.set(r.rule.file, (perFile.get(r.rule.file) ?? 0) + 1);\n io.out(\n `${plural(s.rules.length, \"rule\")} found (${[...perFile].map(([f, n]) => `${n} in ${f}`).join(\", \")}); ${checkable.length} checkable.`,\n );\n if (s.sessions === 0)\n io.out(\n `No Claude Code or Codex sessions in ${v.root} ${window}. Transcripts are read from ~/.claude/projects and ~/.codex/sessions (--claude-dir, --codex-dir); try --since 30d or --since all.`,\n );\n\n const section = (title: string, list: RuleSummary[], body: (r: RuleSummary) => void): void => {\n if (list.length === 0) return;\n io.out(\"\");\n io.out(title);\n for (const r of list) {\n io.out(ruleHead(r));\n body(r);\n }\n };\n const checkLines = (r: RuleSummary): void => {\n r.rule.checks.forEach((check, k) => {\n const c = r.checks[k]!;\n const noun = applicableNoun(c.kind, check.spec);\n const scope = noun ? ` (${c.sessionsApplicable} ${noun})` : \"\";\n let verdict: string;\n if (c.sessionsBroken > 0) {\n verdict = `broken in ${c.sessionsBroken} of ${s.sessions} sessions${scope}`;\n const extra: string[] = [];\n if (c.breaks > c.sessionsBroken) extra.push(`${c.breaks} times`);\n if (c.sessionsOnRequest > 0)\n extra.push(`${c.sessionsOnRequest} on a turn that asked for it`);\n if (c.refused > 0) extra.push(`${c.refused} refused by the harness`);\n if (extra.length) verdict += `; ${extra.join(\", \")}`;\n } else if (c.sessionsApplicable > 0 || !noun) {\n const n = noun ? c.sessionsApplicable : s.sessions;\n verdict =\n n === 1\n ? `kept in the 1 session${noun ? ` that ${noun}` : \"\"}`\n : `kept in all ${n} sessions${noun ? ` that ${noun}` : \"\"}`;\n } else verdict = `nothing in these sessions could break it`;\n if (c.sessionsUndetermined > 0)\n verdict += `; ${c.sessionsUndetermined} more in sessions that do not say who asked (Codex)`;\n io.out(` ${c.label} — ${verdict}`);\n });\n for (const b of r.last) {\n const what = v.evidence(b);\n io.out(\n ` ${localTime(b.at)}${what ? ` ${what}` : \"\"}${b.refused ? \" [refused]\" : \"\"}${b.asked ? \" [asked]\" : \"\"} · session ${b.session.slice(0, 8)}`,\n );\n }\n };\n section(\n \"BROKEN\",\n s.rules\n .filter((r) => r.status === \"broken\")\n .sort((a, b) => b.sessionsBroken - a.sessionsBroken),\n checkLines,\n );\n section(\n \"KEPT\",\n s.rules.filter((r) => r.status === \"kept\"),\n checkLines,\n );\n section(\n \"NOTHING IN THESE SESSIONS COULD BREAK IT\",\n s.rules.filter((r) => r.status === \"not-applicable\"),\n checkLines,\n );\n const notCheckable = s.rules.filter((r) => r.status === \"not-checkable\");\n if (notCheckable.length > 0) {\n io.out(\"\");\n io.out(\n `NOT CHECKABLE MECHANICALLY (${notCheckable.length}) — ${NOT_CHECKABLE_HINT.replace(/^not checkable mechanically — /, \"\")}`,\n );\n for (const r of notCheckable)\n io.out(`${ruleHead(r)}${r.rule.silenced ? \" [marked none]\" : \"\"}`);\n }\n io.out(\"\");\n if (v.enforceable > 0)\n io.out(\n `Enforce: okgate audit --enforce writes ${plural(v.enforceable, \"rule\")} into okgate.yaml as hook rules, in dry-run (nothing is blocked until hooks.mode: enforce)`,\n );\n io.out(TEAM_HISTORY_LINE);\n}\n\nasync function enforce(\n args: ParsedArgs,\n io: Io,\n rules: Rule[],\n policyPath: string,\n checkout: string,\n json: boolean,\n): Promise<number> {\n const plan = planEnforcement(rules);\n const preview = flagBool(args, \"preview\") === true;\n const edit = applyEnforcePlan(policyPath, plan);\n const diff = lineDiff(edit.before, edit.after);\n const changed = edit.before !== edit.after;\n const blocked = edit.mode === \"enforce\" && flagBool(args, \"yes\") !== true;\n const write = changed && !preview && !blocked;\n if (write) writeFileSync(policyPath, edit.after);\n\n // the hook: install it (project level) if no okgate hook is in place for Claude Code\n const home = homeFrom(io);\n const installed = ([\"project\", \"user\"] as const).some((scope) => {\n try {\n return (\n installedHandlers(hookTarget(\"claude-code\", scope, { cwd: checkout, home }, \"\")).length > 0\n );\n } catch {\n return true; // an unreadable settings file: leave it to `hooks status`\n }\n });\n let hookInstalled = installed;\n const hookOut: string[] = [];\n if (!installed && !preview && !blocked) {\n const sub: Io = { ...io, cwd: checkout, out: (l) => hookOut.push(l) };\n const passthrough = [\"hooks\", \"install\"];\n const config = flagString(args, \"config\");\n if (config) passthrough.push(\"--config\", resolve(io.cwd, config));\n const command = flagString(args, \"command\");\n if (command) passthrough.push(\"--command\", command);\n await hooksCommand(parseArgs(passthrough), sub);\n hookInstalled = true;\n }\n\n if (json) {\n io.out(\n JSON.stringify(\n {\n policy: policyPath,\n written: write,\n preview,\n hooks_mode: edit.mode,\n added: edit.added,\n audit_only: plan.auditOnly.map((a) => ({\n rule: a.rule.id,\n check: a.check.label,\n why: a.why,\n })),\n notes: plan.notes,\n hook_installed: hookInstalled,\n },\n null,\n 2,\n ),\n );\n return blocked && changed ? 1 : 0;\n }\n\n if (!changed)\n io.out(`okgate.yaml already has a hook rule for every enforceable rule (${policyPath}).`);\n else {\n io.out(\n `${write ? (edit.created ? \"wrote\" : \"updated\") : \"would update\"} ${policyPath} — ${plural(edit.added.length, \"hook rule\")}:`,\n );\n for (const line of diff) io.out(` ${line}`);\n }\n if (plan.auditOnly.length > 0) {\n io.out(\"\");\n io.out(\"Audit only (a pre-execution hook cannot check these):\");\n for (const a of plan.auditOnly) io.out(` R${a.rule.n} ${a.check.label} — ${a.why}`);\n }\n if (plan.notes.length > 0) {\n io.out(\"\");\n for (const n of plan.notes) io.out(`note: ${n}`);\n }\n io.out(\"\");\n if (blocked && changed) {\n io.out(\n \"hooks.mode is enforce in this okgate.yaml, so these rules would block at once. Nothing was written. Rerun with --enforce --yes to add them anyway, or set hooks.mode: dry-run first.\",\n );\n return 1;\n }\n if (preview) {\n io.out(\"Preview only: nothing was written. Run okgate audit --enforce to write it.\");\n return 0;\n }\n for (const l of hookOut) io.out(l);\n if (installed) io.out(\"The okgate hook is already installed (okgate hooks status).\");\n io.out(\n `hooks.mode is ${edit.mode}: ${edit.mode === \"dry-run\" ? \"every decision is logged and nothing is blocked. Read okgate report, then set hooks.mode: enforce yourself.\" : \"the rules apply from the next session.\"}`,\n );\n return 0;\n}\n","/**\n * The audit's own copy of the counts, one small file per transcript group under\n * `~/.okgate/audit-cache-v1/`, the way seatledger keeps its own (PROD-1A):\n *\n * 1. Speed: a group whose files are unchanged (same size and mtime) is not read again for checks\n * it already answered.\n * 2. History: Claude Code deletes transcripts older than `cleanupPeriodDays` (30 by default). The\n * counts already taken from a deleted transcript stay here, so a 30- or 90-day audit keeps its\n * history. Delete the directory to forget it.\n *\n * Only what `GroupAudit` holds is written — session ids, times, line numbers, hashed call ids and\n * per-check counts — plus SHA-256 hashes of the repository and transcript paths. Never a command,\n * a path, a prompt or anything else a transcript says.\n */\nimport { createHash } from \"node:crypto\";\nimport { mkdirSync, readFileSync, readdirSync, renameSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type {\n AuditClient,\n CheckBreak,\n CheckOutcome,\n GroupAudit,\n} from \"@agentwares/agentguard-core\";\nimport type { TranscriptGroup } from \"./sources.js\";\n\nexport const CACHE_DIR = \"audit-cache-v1\";\n/** Bump when the readers or the checks change what they count: every entry is then re-read. */\nexport const ENGINE = \"1\";\n\nexport const sha = (text: string): string => createHash(\"sha256\").update(text).digest(\"hex\");\n\ntype WireBreak = [\n at: number,\n session: string,\n step: string,\n file: number,\n line: number,\n what: 0 | 1 | 2,\n index: number,\n asked: 0 | 1 | 2,\n refused: 0 | 1,\n];\n\ninterface Wire {\n v: 1;\n engine: string;\n repo: string;\n group: string;\n client: AuditClient;\n files: [src: string, size: number, mtimeMs: number][];\n sessions: [id: string, client: AuditClient, start: number, end: number, turnsKnown: 0 | 1][];\n unread: number;\n checks: Record<string, { a: string[]; b: WireBreak[] }>;\n}\n\nexport interface CacheEntry {\n repo: string;\n group: string;\n client: AuditClient;\n files: [string, number, number][];\n audit: GroupAudit;\n}\n\nconst WHAT = [\"command\", \"path\", \"call\"] as const;\n\nfunction encodeBreak(b: CheckBreak): WireBreak {\n return [\n b.at,\n b.session,\n b.step,\n b.file,\n b.line,\n WHAT.indexOf(b.what) as 0 | 1 | 2,\n b.index,\n b.asked === null ? 2 : b.asked ? 1 : 0,\n b.refused ? 1 : 0,\n ];\n}\n\nfunction decodeBreak(w: WireBreak): CheckBreak {\n return {\n at: w[0],\n session: w[1],\n step: w[2],\n file: w[3],\n line: w[4],\n what: WHAT[w[5]] ?? \"call\",\n index: w[6],\n asked: w[7] === 2 ? null : w[7] === 1,\n refused: w[8] === 1,\n };\n}\n\nexport function fileSignature(group: TranscriptGroup): [string, number, number][] {\n return group.files.map((f) => [sha(f.path), f.size, Math.round(f.mtimeMs)]);\n}\n\nexport class AuditCache {\n private readonly dir: string;\n private readonly entries = new Map<string, CacheEntry>();\n\n constructor(\n home: string,\n private readonly repo: string,\n private readonly enabled = true,\n ) {\n this.dir = join(home, CACHE_DIR);\n if (!enabled) return;\n let names: string[];\n try {\n names = readdirSync(this.dir);\n } catch {\n return;\n }\n for (const name of names) {\n if (!name.endsWith(\".json\")) continue;\n try {\n const w = JSON.parse(readFileSync(join(this.dir, name), \"utf8\")) as Wire;\n if (w.v !== 1 || w.engine !== ENGINE || w.repo !== repo) continue;\n this.entries.set(w.group, {\n repo: w.repo,\n group: w.group,\n client: w.client,\n files: w.files,\n audit: {\n sessions: w.sessions.map(([id, client, start, end, known]) => ({\n id,\n client,\n start,\n end,\n turnsKnown: known === 1,\n })),\n unread: w.unread,\n checks: Object.fromEntries(\n Object.entries(w.checks).map(([k, c]): [string, CheckOutcome] => [\n k,\n { applicable: c.a, breaks: c.b.map(decodeBreak) },\n ]),\n ),\n },\n });\n } catch {\n // a partial write from an interrupted run: re-read from the transcript\n }\n }\n }\n\n groupKey(group: TranscriptGroup): string {\n return sha(`${this.repo}\\u0000${group.key}`);\n }\n\n /** The cached counts for a group, if its files are unchanged and every check is answered. */\n lookup(group: TranscriptGroup, keys: readonly string[]): GroupAudit | undefined {\n const hit = this.entries.get(this.groupKey(group));\n if (!hit) return undefined;\n if (JSON.stringify(hit.files) !== JSON.stringify(fileSignature(group))) return undefined;\n if (!keys.every((k) => hit.audit.checks[k])) return undefined;\n return hit.audit;\n }\n\n /** Counts kept from groups whose transcripts are gone (deleted by the client's cleanup). */\n retained(present: ReadonlySet<string>, client: AuditClient): GroupAudit[] {\n const out: GroupAudit[] = [];\n for (const e of this.entries.values())\n if (e.client === client && !present.has(e.group)) out.push(e.audit);\n return out;\n }\n\n /** Best effort: a cache that cannot be written only costs speed and history. */\n store(group: TranscriptGroup, audit: GroupAudit): void {\n const key = this.groupKey(group);\n const files = fileSignature(group);\n const prev = this.entries.get(key);\n // checks this run did not ask for stay valid while the files are unchanged\n const checks =\n prev && JSON.stringify(prev.files) === JSON.stringify(files)\n ? { ...prev.audit.checks, ...audit.checks }\n : audit.checks;\n const merged: GroupAudit = { ...audit, checks };\n this.entries.set(key, {\n repo: this.repo,\n group: key,\n client: group.client,\n files,\n audit: merged,\n });\n if (!this.enabled) return;\n const wire: Wire = {\n v: 1,\n engine: ENGINE,\n repo: this.repo,\n group: key,\n client: group.client,\n files,\n sessions: merged.sessions.map((s) => [s.id, s.client, s.start, s.end, s.turnsKnown ? 1 : 0]),\n unread: merged.unread,\n checks: Object.fromEntries(\n Object.entries(merged.checks).map(([k, c]) => [\n k,\n { a: c.applicable, b: c.breaks.map(encodeBreak) },\n ]),\n ),\n };\n try {\n mkdirSync(this.dir, { recursive: true, mode: 0o700 });\n const file = join(this.dir, `${key.slice(0, 32)}.json`);\n const tmp = `${file}.${process.pid}.tmp`;\n writeFileSync(tmp, JSON.stringify(wire), { mode: 0o600 });\n renameSync(tmp, file);\n } catch {\n // read-only home, full disk: the next run reads the transcripts again\n }\n }\n}\n","/**\n * `okgate audit --enforce`: write the plan `planEnforcement` made into okgate.yaml with\n * the `yaml` document API, so every comment and setting already there stays. Each added rule\n * carries a comment naming the rule it came from. `hooks.mode` is never touched: a new policy, or\n * a new hooks block, starts in dry-run.\n */\nimport { existsSync, readFileSync } from \"node:fs\";\nimport YAML, { isMap, isScalar, isSeq, type Document, type Scalar, type YAMLSeq } from \"yaml\";\nimport type { EnforcePlan, Rule } from \"@agentwares/agentguard-core\";\nimport { HOOKS_POLICY_BLOCK, renderHooksStarterPolicy } from \"../commands/hooks.js\";\n\nexport interface EnforceEdit {\n /** the policy before (empty when there was none) and after */\n before: string;\n after: string;\n created: boolean;\n /** one line per hook rule added */\n added: string[];\n mode: \"dry-run\" | \"enforce\";\n}\n\nconst origin = (rule: Rule): string => ` R${rule.n} ${rule.file}:${rule.line}`;\n\nfunction seqAt(doc: Document, path: string[]): YAMLSeq {\n let node = doc.getIn(path, true);\n if (!isSeq(node)) {\n doc.setIn(path, doc.createNode([]));\n node = doc.getIn(path, true);\n }\n const seq = node as YAMLSeq;\n seq.flow = false;\n return seq;\n}\n\nconst values = (seq: YAMLSeq): string[] =>\n seq.items.map((n) => (isScalar(n) ? String(n.value) : \"\")).map((v) => v.toLowerCase());\n\n/** The policy text with the plan applied. Throws on a policy that is not valid YAML. */\nexport function applyEnforcePlan(\n policyPath: string,\n plan: EnforcePlan,\n now = new Date(),\n): EnforceEdit {\n const created = !existsSync(policyPath);\n const before = created ? \"\" : readFileSync(policyPath, \"utf8\");\n let text = created ? renderHooksStarterPolicy(now) : before;\n if (!/^hooks\\s*:/m.test(text)) text = `${text.replace(/\\n*$/, \"\\n\")}${HOOKS_POLICY_BLOCK}`;\n const doc = YAML.parseDocument(text);\n if (doc.errors.length > 0)\n throw new Error(`${policyPath} is not valid YAML: ${doc.errors[0]!.message}`);\n const added: string[] = [];\n\n for (const item of plan.items) {\n const seq = seqAt(doc, item.list.split(\".\"));\n if (values(seq).includes(item.pattern.toLowerCase())) continue;\n const node = doc.createNode(item.pattern) as Scalar;\n node.comment = origin(item.rule);\n seq.items.push(node);\n added.push(`${item.list}: ${item.pattern} (R${item.rule.n}, ${item.check.label})`);\n }\n\n if (plan.builtins.length > 0) {\n const path = [\"hooks\", \"irreversible\", \"builtins\"];\n const node = doc.getIn(path, true);\n const enabled = isScalar(node) ? node.value : undefined;\n if (enabled === false || isSeq(node)) {\n const seq = seqAt(doc, path);\n for (const b of plan.builtins) {\n if (values(seq).includes(b.name)) continue;\n const scalar = doc.createNode(b.name) as Scalar;\n scalar.comment = origin(b.rule);\n seq.items.push(scalar);\n added.push(`hooks.irreversible.builtins: ${b.name} (R${b.rule.n}, ${b.check.label})`);\n }\n }\n // `true` or absent: every built-in class is already on\n }\n\n if (plan.irreversible.length > 0) {\n const seq = seqAt(doc, [\"hooks\", \"irreversible\", \"rules\"]);\n const names = new Set(\n seq.items.map((n) => (isMap(n) ? String(n.get(\"name\") ?? \"\") : \"\")).filter(Boolean),\n );\n for (const r of plan.irreversible) {\n if (names.has(r.name)) continue;\n const node = doc.createNode({ name: r.name, shell: r.shell, mentions: r.mentions });\n if (isMap(node)) node.commentBefore = origin(r.rule);\n seq.items.push(node);\n added.push(\n `hooks.irreversible.rules: ${r.name} (${r.shell.length} commands) (R${r.rule.n}, ${r.check.label})`,\n );\n }\n }\n\n const mode = doc.getIn([\"hooks\", \"mode\"]) === \"enforce\" ? \"enforce\" : \"dry-run\";\n return { before, after: doc.toString({ lineWidth: 0 }), created, added, mode };\n}\n\n/** A unified-style line diff, with `context` unchanged lines around each change. */\nexport function lineDiff(a: string, b: string, context = 2): string[] {\n const x = a === \"\" ? [] : a.replace(/\\n$/, \"\").split(\"\\n\");\n const y = b.replace(/\\n$/, \"\").split(\"\\n\");\n const n = x.length;\n const m = y.length;\n // longest common subsequence, small files only\n const lcs: number[][] = Array.from({ length: n + 1 }, () => new Array<number>(m + 1).fill(0));\n for (let i = n - 1; i >= 0; i -= 1)\n for (let j = m - 1; j >= 0; j -= 1)\n lcs[i]![j] =\n x[i] === y[j] ? lcs[i + 1]![j + 1]! + 1 : Math.max(lcs[i + 1]![j]!, lcs[i]![j + 1]!);\n const ops: { op: \" \" | \"+\" | \"-\"; line: string }[] = [];\n let i = 0;\n let j = 0;\n while (i < n || j < m) {\n if (i < n && j < m && x[i] === y[j]) {\n ops.push({ op: \" \", line: x[i]! });\n i += 1;\n j += 1;\n } else if (j < m && (i >= n || lcs[i]![j + 1]! >= lcs[i + 1]![j]!)) {\n ops.push({ op: \"+\", line: y[j]! });\n j += 1;\n } else {\n ops.push({ op: \"-\", line: x[i]! });\n i += 1;\n }\n }\n const keep = new Set<number>();\n ops.forEach((o, k) => {\n if (o.op === \" \") return;\n for (let d = -context; d <= context; d += 1) keep.add(k + d);\n });\n const out: string[] = [];\n let last = -2;\n ops.forEach((o, k) => {\n if (!keep.has(k)) return;\n if (k !== last + 1 && out.length > 0) out.push(\" …\");\n out.push(`${o.op} ${o.line}`);\n last = k;\n });\n return out;\n}\n","/**\n * Stream a transcript group through agentguard-core's readers. Transcripts run to hundreds of\n * megabytes and most of every line is text the audit never needs, so a substring test decides\n * which lines are parsed at all. Nothing read here is written anywhere: the readers' steps and\n * turns stay in memory, and only `evaluateChecks`' counts reach the cache.\n */\nimport { createReadStream } from \"node:fs\";\nimport { createInterface } from \"node:readline\";\nimport {\n ClaudeCodeAuditReader,\n CodexAuditReader,\n stableHash,\n type AuditReaderOptions,\n type AuditStep,\n type TranscriptAudit,\n} from \"@agentwares/agentguard-core\";\nimport type { TranscriptGroup } from \"./sources.js\";\n\nconst CLAUDE_WANTED = (raw: string): boolean =>\n raw.includes('\"type\":\"assistant\"') || raw.includes('\"type\":\"user\"');\nconst CODEX_WANTED = (raw: string): boolean =>\n raw.includes('\"session_meta\"') ||\n raw.includes('\"turn_context\"') ||\n raw.includes('\"function_call\"') ||\n raw.includes('\"local_shell_call\"') ||\n raw.includes('\"custom_tool_call\"');\n\n/**\n * Each line of a file, 1-based. `onLine` returns false to stop early. Lines that are not JSON\n * (a transcript being written ends mid-line) are skipped.\n */\nasync function eachLine(\n path: string,\n wanted: (raw: string, line: number) => boolean,\n onLine: (value: unknown, line: number) => boolean | void,\n): Promise<void> {\n const stream = createReadStream(path, { encoding: \"utf8\", highWaterMark: 1 << 20 });\n const lines = createInterface({ input: stream, crlfDelay: Infinity });\n let n = 0;\n try {\n for await (const raw of lines) {\n n += 1;\n if (raw.length === 0 || !wanted(raw, n)) continue;\n let value: unknown;\n try {\n value = JSON.parse(raw);\n } catch {\n continue;\n }\n if (onLine(value, n) === false) break;\n }\n } finally {\n lines.close();\n stream.destroy();\n }\n}\n\n/** Every step and turn in a group that happened in the repository. */\nexport async function readGroup(\n group: TranscriptGroup,\n opts: AuditReaderOptions,\n): Promise<TranscriptAudit> {\n if (group.client === \"codex\") {\n const reader = new CodexAuditReader(opts);\n await eachLine(group.files[0]!.path, CODEX_WANTED, (value, line) => {\n reader.add(value, line, 0);\n return reader.relevant;\n });\n return reader.result();\n }\n const reader = new ClaudeCodeAuditReader(opts);\n for (const [i, file] of group.files.entries())\n await eachLine(file.path, CLAUDE_WANTED, (value, line) => reader.add(value, line, i));\n return reader.result();\n}\n\n/**\n * The steps behind a few breaks, for the evidence on screen: only the lines that hold them are\n * parsed (and, for Codex, the lines that say where the rollout ran).\n */\nexport async function fetchSteps(\n group: TranscriptGroup,\n wanted: readonly { file: number; line: number; step: string }[],\n opts: AuditReaderOptions,\n): Promise<Map<string, AuditStep>> {\n const out = new Map<string, AuditStep>();\n const byFile = new Map<number, Set<number>>();\n for (const w of wanted) {\n const set = byFile.get(w.file) ?? new Set<number>();\n set.add(w.line);\n byFile.set(w.file, set);\n }\n for (const [fileIndex, lines] of byFile) {\n const file = group.files[fileIndex];\n if (!file) continue;\n const last = Math.max(...lines);\n const reader =\n group.client === \"codex\" ? new CodexAuditReader(opts) : new ClaudeCodeAuditReader(opts);\n await eachLine(\n file.path,\n (raw, n) =>\n lines.has(n) ||\n (group.client === \"codex\" &&\n (raw.includes('\"session_meta\"') || raw.includes('\"turn_context\"'))),\n (value, n) => {\n reader.add(value, n, fileIndex);\n return n < last;\n },\n );\n for (const step of reader.result().steps) out.set(stableHash(step.id), step);\n }\n return out;\n}\n","/**\n * The repository being audited: where its rule files are, and which working directories count\n * as \"in it\" when matching sessions.\n */\nimport { existsSync, readFileSync, readdirSync, statSync } from \"node:fs\";\nimport { dirname, isAbsolute, join, relative, resolve, sep } from \"node:path\";\nimport YAML from \"yaml\";\nimport {\n AuditRulesSchema,\n isWithin,\n normalizePath,\n type ConfigRule,\n type RuleFileInput,\n} from \"@agentwares/agentguard-core\";\nimport { pathForms } from \"./sources.js\";\n\nexport interface AuditRepo {\n /** where the rule files are read from: the checkout the command ran in */\n checkout: string;\n /**\n * the repository sessions are matched against: the main checkout when `checkout` is a git\n * worktree, so sessions in its other worktrees (`.claude/worktrees/*`) count too\n */\n root: string;\n}\n\n/** The git checkout holding `cwd` (or `cwd` itself outside git), and its main checkout. */\nexport function findRepo(cwd: string): AuditRepo {\n let dir = resolve(cwd);\n for (let i = 0; i < 64; i += 1) {\n const dotgit = join(dir, \".git\");\n if (existsSync(dotgit)) {\n let root = dir;\n try {\n if (statSync(dotgit).isFile()) {\n // a worktree: `gitdir: <main>/.git/worktrees/<name>`\n const m = /^gitdir:\\s*(.+)$/m.exec(readFileSync(dotgit, \"utf8\"));\n const gitdir = m ? resolve(dir, m[1]!.trim()) : \"\";\n const at = gitdir.lastIndexOf(`${sep}.git${sep}worktrees${sep}`);\n if (at > 0) root = gitdir.slice(0, at);\n }\n } catch {\n // unreadable .git file: audit this checkout alone\n }\n return { checkout: dir, root };\n }\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n return { checkout: resolve(cwd), root: resolve(cwd) };\n}\n\n/** Is a session's working directory inside the repository (in any form its path can take)? */\nexport function repoMatcher(root: string): (cwd: string) => boolean {\n const forms = pathForms(root).map(normalizePath);\n return (cwd: string) => forms.some((f) => isWithin(normalizePath(cwd), f));\n}\n\n/** Rule files at the root of a checkout, as agentsmd-lint looks for them, plus Cursor's rules. */\nexport const RULE_FILES = [\n \"CLAUDE.md\",\n \"CLAUDE.local.md\",\n \".claude/CLAUDE.md\",\n \"AGENTS.md\",\n \"GEMINI.md\",\n \".cursorrules\",\n \".github/copilot-instructions.md\",\n \".windsurfrules\",\n \".clinerules\",\n] as const;\n\nconst MAX_CURSOR_RULES = 20;\nconst MAX_BYTES = 512 * 1024;\n\nfunction cursorRules(dir: string, out: string[], depth = 0): void {\n if (depth > 3 || out.length >= MAX_CURSOR_RULES) return;\n let entries;\n try {\n entries = readdirSync(dir, { withFileTypes: true });\n } catch {\n return;\n }\n for (const e of entries.sort((a, b) => a.name.localeCompare(b.name))) {\n const p = join(dir, e.name);\n if (e.isDirectory()) cursorRules(p, out, depth + 1);\n else if (e.isFile() && /\\.(mdc|md)$/.test(e.name) && out.length < MAX_CURSOR_RULES) out.push(p);\n }\n}\n\n/** The rule files this checkout has, repo-relative, plus any named with `--rules`. */\nexport function readRuleFiles(checkout: string, extra: readonly string[] = []): RuleFileInput[] {\n const paths: string[] = RULE_FILES.map((f) => join(checkout, f));\n cursorRules(join(checkout, \".cursor\", \"rules\"), paths);\n for (const e of extra) paths.push(isAbsolute(e) ? e : resolve(checkout, e));\n const out: RuleFileInput[] = [];\n const seen = new Set<string>();\n for (const p of paths) {\n if (seen.has(p)) continue;\n seen.add(p);\n try {\n if (!statSync(p).isFile()) continue;\n const text = readFileSync(p, \"utf8\").slice(0, MAX_BYTES);\n const rel = relative(checkout, p);\n out.push({ path: rel.startsWith(\"..\") ? p : rel.split(sep).join(\"/\"), text });\n } catch {\n // absent\n }\n }\n return out;\n}\n\n/**\n * `audit.rules` from okgate.yaml, read on its own so a policy that fails for another reason\n * (an unset `${VAR}`, say) does not hide them. Returns a warning instead of throwing.\n */\nexport function readConfigRules(policyPath: string): { rules: ConfigRule[]; warning?: string } {\n if (!existsSync(policyPath)) return { rules: [] };\n let raw: unknown;\n try {\n raw = YAML.parse(readFileSync(policyPath, \"utf8\"));\n } catch (err) {\n return {\n rules: [],\n warning: `${policyPath} is not valid YAML (${err instanceof Error ? err.message : String(err)}); its audit.rules were skipped`,\n };\n }\n const audit = raw && typeof raw === \"object\" ? (raw as Record<string, unknown>).audit : undefined;\n const rules =\n audit && typeof audit === \"object\" ? (audit as Record<string, unknown>).rules : undefined;\n if (rules === undefined) return { rules: [] };\n const parsed = AuditRulesSchema.safeParse(rules);\n if (!parsed.success)\n return {\n rules: [],\n warning: `audit.rules in ${policyPath} is invalid (${parsed.error.issues\n .map((i) => `${i.path.join(\".\")}: ${i.message}`)\n .join(\"; \")}); skipped`,\n };\n return { rules: parsed.data };\n}\n","/**\n * Where coding agents keep their transcripts, and which of them are about one repository.\n *\n * The layout is the one seatledger reads (apps/seatledger-cli/src/paths.ts, PROD-1A), kept in\n * step with it rather than imported: seatledger is not on npm yet, and the public okgate repo\n * is generated without it (see docs/reports/AG-AUDIT.md).\n *\n * - Claude Code: `$CLAUDE_CONFIG_DIR/projects` (comma-separated for several), else\n * `~/.claude/projects` and `~/.config/claude/projects`. One directory per working directory,\n * named after its path with every character that is not a letter or digit turned into `-`;\n * a session is `<session>.jsonl` there, its subagents under `<session>/subagents/`.\n * - Codex: `$CODEX_HOME/sessions` and `$CODEX_HOME/archived_sessions`, `CODEX_HOME` defaulting\n * to `~/.codex`. One rollout per thread, by date; its first line names the working directory.\n */\nimport { existsSync, readdirSync, realpathSync, statSync } from \"node:fs\";\nimport { basename, join, resolve } from \"node:path\";\nimport type { AuditClient } from \"@agentwares/agentguard-core\";\n\nexport interface SourceDirs {\n \"claude-code\": string[];\n codex: string[];\n}\n\nexport function sourceDirs(\n env: NodeJS.ProcessEnv,\n home: string,\n overrides: { claudeDir?: string; codexDir?: string } = {},\n): SourceDirs {\n const claude = overrides.claudeDir\n ? [resolve(overrides.claudeDir)]\n : env.CLAUDE_CONFIG_DIR\n ? env.CLAUDE_CONFIG_DIR.split(\",\")\n .map((d) => d.trim())\n .filter(Boolean)\n .map((d) => join(resolve(d), \"projects\"))\n : [join(home, \".claude\", \"projects\"), join(home, \".config\", \"claude\", \"projects\")];\n const codexHome = env.CODEX_HOME ? resolve(env.CODEX_HOME) : join(home, \".codex\");\n const codex = overrides.codexDir\n ? [resolve(overrides.codexDir)]\n : [join(codexHome, \"sessions\"), join(codexHome, \"archived_sessions\")];\n return { \"claude-code\": claude, codex };\n}\n\nexport interface TranscriptFile {\n path: string;\n size: number;\n mtimeMs: number;\n}\n\n/** What is read, cached and evaluated together: a session and its subagents, or a rollout. */\nexport interface TranscriptGroup {\n client: AuditClient;\n /** the main transcript's path (the session directory for subagents with no main file) */\n key: string;\n files: TranscriptFile[];\n /** the latest write to any of its files */\n lastWrite: number;\n}\n\n/** Spilled tool output and memory notes live beside transcripts; neither is a transcript. */\nconst SKIP_DIRS = new Set([\"tool-results\", \"memory\", \"node_modules\", \".git\"]);\n\nfunction stat(path: string): TranscriptFile | undefined {\n try {\n const s = statSync(path);\n return s.isFile() ? { path, size: s.size, mtimeMs: s.mtimeMs } : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction jsonlUnder(dir: string, out: TranscriptFile[], depth = 0): void {\n if (depth > 6) return;\n let entries;\n try {\n entries = readdirSync(dir, { withFileTypes: true });\n } catch {\n return;\n }\n for (const e of entries) {\n const p = join(dir, e.name);\n if (e.isDirectory()) {\n if (!SKIP_DIRS.has(e.name)) jsonlUnder(p, out, depth + 1);\n } else if (e.isFile() && e.name.endsWith(\".jsonl\")) {\n const f = stat(p);\n if (f) out.push(f);\n }\n }\n}\n\n/** Claude Code's directory name for a working directory. */\nexport function claudeProjectName(dir: string): string {\n return dir.replace(/[^a-zA-Z0-9]/g, \"-\");\n}\n\n/** The forms a path can take in a transcript: as given, and with symlinks resolved (/var → /private/var). */\nexport function pathForms(dir: string): string[] {\n const forms = new Set([resolve(dir)]);\n try {\n forms.add(realpathSync(dir));\n } catch {\n // not on disk (a deleted checkout): the given form only\n }\n return [...forms];\n}\n\n/**\n * Claude Code project directories that can hold sessions for `repoRoot`: its own, and any whose\n * name starts with it (subdirectories, worktrees under it). The name is lossy, so the\n * transcripts' own `cwd` decides in the end.\n */\nexport function claudeProjectDirs(roots: readonly string[], repoRoot: string): string[] {\n const names = pathForms(repoRoot).map(claudeProjectName);\n const out: string[] = [];\n for (const root of roots) {\n let entries;\n try {\n entries = readdirSync(root, { withFileTypes: true });\n } catch {\n continue;\n }\n for (const e of entries) {\n if (!e.isDirectory()) continue;\n if (names.some((n) => e.name === n || e.name.startsWith(`${n}-`)))\n out.push(join(root, e.name));\n }\n }\n return out;\n}\n\n/** Sessions in Claude Code project directories, each with its subagents. */\nexport function claudeGroups(projectDirs: readonly string[]): TranscriptGroup[] {\n const groups: TranscriptGroup[] = [];\n for (const dir of projectDirs) {\n let entries;\n try {\n entries = readdirSync(dir, { withFileTypes: true });\n } catch {\n continue;\n }\n const mains = new Map<string, TranscriptFile>();\n const subdirs: string[] = [];\n for (const e of entries) {\n const p = join(dir, e.name);\n if (e.isFile() && e.name.endsWith(\".jsonl\")) {\n const f = stat(p);\n if (f) mains.set(basename(e.name, \".jsonl\"), f);\n } else if (e.isDirectory() && !SKIP_DIRS.has(e.name)) subdirs.push(e.name);\n }\n for (const [id, main] of mains) {\n const files = [main];\n if (subdirs.includes(id)) jsonlUnder(join(dir, id), files);\n groups.push(group(\"claude-code\", main.path, files));\n }\n for (const id of subdirs) {\n if (mains.has(id)) continue;\n const files: TranscriptFile[] = [];\n jsonlUnder(join(dir, id), files);\n if (files.length > 0) groups.push(group(\"claude-code\", join(dir, id), files));\n }\n }\n return groups;\n}\n\n/** Codex rollouts, one group each. */\nexport function codexGroups(roots: readonly string[]): TranscriptGroup[] {\n const files: TranscriptFile[] = [];\n for (const root of roots) if (existsSync(root)) jsonlUnder(root, files);\n return files.map((f) => group(\"codex\", f.path, [f]));\n}\n\nfunction group(client: AuditClient, key: string, files: TranscriptFile[]): TranscriptGroup {\n files.sort((a, b) => (a.path === key ? -1 : b.path === key ? 1 : a.path.localeCompare(b.path)));\n return { client, key, files, lastWrite: Math.max(...files.map((f) => f.mtimeMs)) };\n}\n"],"mappings":"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","names":["writeFileSync","basename","join","resolve","stableHash","group","readFileSync","readFileSync","i","j","group","reader","existsSync","readFileSync","readdirSync","statSync","join","resolve","YAML","existsSync","readdirSync","join","resolve","join","existsSync","statSync","readFileSync","readdirSync","YAML","resolve","basename","join","group","stableHash","writeFileSync"]}
@@ -1,17 +1,22 @@
1
1
  import {
2
- CLIENT_ALIASES,
3
- hookSettingsFiles,
4
- hooksCommand
5
- } from "./chunk-3O6KWT3E.js";
6
- import {
2
+ LEGACY_PROXY_SERVER_NAME,
7
3
  PROXY_SERVER_NAME,
8
4
  describeConfigPath,
9
5
  detectClientConfigs,
10
6
  isGeminiConfig,
11
7
  mergeServerIntoConfig
12
- } from "./chunk-TW5KJREH.js";
8
+ } from "./chunk-OM5L7A32.js";
9
+ import {
10
+ hooksCommand
11
+ } from "./chunk-F73VDY3W.js";
12
+ import {
13
+ CLIENT_ALIASES,
14
+ hookSettingsFiles
15
+ } from "./chunk-2QDPPTPY.js";
16
+ import {
17
+ INSTALL
18
+ } from "./chunk-XPNBYSIN.js";
13
19
  import {
14
- DEFAULT_POLICY_FILE,
15
20
  approvalUrlFor,
16
21
  createFileGuard,
17
22
  defaultIo,
@@ -26,23 +31,24 @@ import {
26
31
  policyPathFrom,
27
32
  readRegistration,
28
33
  version
29
- } from "./chunk-SUXQTT3X.js";
34
+ } from "./chunk-4WTFMFRY.js";
30
35
 
31
36
  // src/commands/connect.ts
32
37
  import { existsSync } from "fs";
33
38
  import { relative } from "path";
39
+ import { envTwin } from "@agentwares/agentguard-core";
34
40
  var DEFAULT_PROXY_URL = "https://agentwares-agentguard-proxy.vercel.app";
35
41
  function fail(e) {
36
42
  throw e;
37
43
  }
38
44
  async function connectCommand(args, io, fetchImpl = fetch) {
39
- const key = args.positionals[0] ?? io.env.AGENTGUARD_KEY;
45
+ const key = args.positionals[0] ?? envTwin(io.env, "KEY");
40
46
  if (!key) {
41
- io.err("usage: agentguard connect <key> [--write] [--client <path>] [--url <proxy-url>]");
47
+ io.err("usage: okgate connect <key> [--write] [--client <path>] [--url <proxy-url>]");
42
48
  io.err(" the key is on your dashboard; it starts with agk_");
43
49
  return 2;
44
50
  }
45
- const base = (flagString(args, "url") ?? io.env.AGENTGUARD_PROXY_URL ?? DEFAULT_PROXY_URL).replace(/\/+$/, "");
51
+ const base = (flagString(args, "url") ?? envTwin(io.env, "PROXY_URL") ?? DEFAULT_PROXY_URL).replace(/\/+$/, "");
46
52
  let res;
47
53
  try {
48
54
  res = await fetchImpl(`${base}/connect`, {
@@ -66,7 +72,7 @@ async function connectCommand(args, io, fetchImpl = fetch) {
66
72
  fail({
67
73
  code: "PROXY_BAD_RESPONSE",
68
74
  cause: `${base}/connect returned ${res.status} that was not JSON: ${text.slice(0, 200)}`,
69
- fix: "check --url points at an agentguard proxy, not at the dashboard",
75
+ fix: "check --url points at an okgate proxy, not at the dashboard",
70
76
  retryable: false
71
77
  });
72
78
  }
@@ -85,7 +91,7 @@ async function connectCommand(args, io, fetchImpl = fetch) {
85
91
  return 0;
86
92
  }
87
93
  const rel = (p) => p.startsWith(io.cwd + "/") ? relative(io.cwd, p) : p;
88
- const entry = conn.mcpServers[PROXY_SERVER_NAME] ?? {
94
+ const entry = conn.mcpServers[PROXY_SERVER_NAME] ?? conn.mcpServers[LEGACY_PROXY_SERVER_NAME] ?? {
89
95
  type: "http",
90
96
  url: conn.mcpUrl,
91
97
  headers: conn.headers
@@ -112,7 +118,9 @@ async function connectCommand(args, io, fetchImpl = fetch) {
112
118
  return 1;
113
119
  }
114
120
  const forClient = isGeminiConfig(c) ? { httpUrl: entry.url, ...entry.headers ? { headers: entry.headers } : {} } : entry;
115
- const { backup, replaced } = mergeServerIntoConfig(c, PROXY_SERVER_NAME, forClient);
121
+ const { backup, replaced } = mergeServerIntoConfig(c, PROXY_SERVER_NAME, forClient, [
122
+ LEGACY_PROXY_SERVER_NAME
123
+ ]);
116
124
  io.out(
117
125
  `${replaced ? "updated" : "wrote "} ${rel(c.path)} (${c.label}) \u2192 ${PROXY_SERVER_NAME} = ${conn.mcpUrl}`
118
126
  );
@@ -136,6 +144,7 @@ run again with --write to add this to your MCP client config`);
136
144
  }
137
145
 
138
146
  // src/commands/control.ts
147
+ import { KILL_ENV, LEGACY_KILL_ENV } from "@agentwares/agentguard-core";
139
148
  async function pokeHttp(io, reg, path, body) {
140
149
  if (!reg) return;
141
150
  try {
@@ -158,11 +167,11 @@ async function pokeHttp(io, reg, path, body) {
158
167
  async function killCommand(args, io) {
159
168
  const loaded = loadPolicyFor(args, io, { allowMissingEnv: true });
160
169
  const { kill } = createFileGuard(loaded, { alerts: false, env: io.env });
161
- const reason = args.positionals.join(" ") || flagString(args, "reason") || `agentguard kill by ${io.env.USER ?? "operator"}`;
170
+ const reason = args.positionals.join(" ") || flagString(args, "reason") || `okgate kill by ${io.env.USER ?? "operator"}`;
162
171
  kill.kill(reason);
163
172
  await pokeHttp(io, readRegistration(loaded), "/kill", { reason });
164
173
  io.out(
165
- `KILLED: ${kill.path} written \u2014 every tool call through this policy now returns KILLED. Clear with: agentguard resume`
174
+ `KILLED: ${kill.path} written \u2014 every tool call through this policy now returns KILLED. Clear with: okgate resume`
166
175
  );
167
176
  return 0;
168
177
  }
@@ -172,17 +181,18 @@ async function resumeCommand(args, io) {
172
181
  kill.resume();
173
182
  await pokeHttp(io, readRegistration(loaded), "/resume");
174
183
  io.out(`resumed: ${kill.path} removed`);
175
- if (io.env[loaded.policy.kill.env])
176
- io.err(
177
- `note: ${loaded.policy.kill.env} is set in this shell's environment; proxies started from it stay killed`
178
- );
184
+ for (const name of /* @__PURE__ */ new Set([loaded.policy.kill.env, KILL_ENV, LEGACY_KILL_ENV]))
185
+ if (io.env[name] && io.env[name] !== "0" && io.env[name].toLowerCase() !== "false")
186
+ io.err(
187
+ `note: ${name} is set in this shell's environment; proxies started from it stay killed`
188
+ );
179
189
  return 0;
180
190
  }
181
191
  async function decideCommand(decision, args, io) {
182
192
  const id = args.positionals[0];
183
193
  if (!id) {
184
194
  io.err(
185
- `usage: agentguard ${decision === "approved" ? "approve" : "deny"} <approval-id> [--by name] [--note text]`
195
+ `usage: okgate ${decision === "approved" ? "approve" : "deny"} <approval-id> [--by name] [--note text]`
186
196
  );
187
197
  return 1;
188
198
  }
@@ -195,7 +205,7 @@ async function decideCommand(decision, args, io) {
195
205
  flagString(args, "note")
196
206
  );
197
207
  if (!record) {
198
- io.err(`no approval ${id} \u2014 pending ones: agentguard approvals`);
208
+ io.err(`no approval ${id} \u2014 pending ones: okgate approvals`);
199
209
  return 1;
200
210
  }
201
211
  io.out(
@@ -220,8 +230,7 @@ async function approvalsCommand(args, io) {
220
230
  `${r.id} ${r.status.padEnd(9)} ${r.tool} run ${r.run_id}${r.agent ? ` agent ${r.agent}` : ""} expires ${r.expires_at}`
221
231
  );
222
232
  io.out(` args: ${JSON.stringify(r.args).slice(0, 300)}`);
223
- if (r.status === "pending")
224
- io.out(` \u2192 agentguard approve ${r.id} | agentguard deny ${r.id}`);
233
+ if (r.status === "pending") io.out(` \u2192 okgate approve ${r.id} | okgate deny ${r.id}`);
225
234
  }
226
235
  return 0;
227
236
  }
@@ -229,10 +238,12 @@ async function approvalsCommand(args, io) {
229
238
  // src/commands/hook.ts
230
239
  import { existsSync as existsSync3 } from "fs";
231
240
  import { tmpdir } from "os";
232
- import { dirname, join, resolve } from "path";
241
+ import { basename, dirname, join, resolve } from "path";
233
242
  import {
243
+ POLICY_FILES,
234
244
  assessHookAction,
235
245
  detectHookClient,
246
+ envTwin as envTwin2,
236
247
  hookActionFromInput
237
248
  } from "@agentwares/agentguard-core";
238
249
 
@@ -290,8 +301,10 @@ var RUN_PREFIX = {
290
301
  function findPolicyUpwards(start) {
291
302
  let dir = resolve(start);
292
303
  for (let i = 0; i < 64; i += 1) {
293
- const candidate = join(dir, DEFAULT_POLICY_FILE);
294
- if (existsSync3(candidate)) return candidate;
304
+ for (const name of POLICY_FILES) {
305
+ const candidate = join(dir, name);
306
+ if (existsSync3(candidate)) return candidate;
307
+ }
295
308
  const parent = dirname(dir);
296
309
  if (parent === dir) return void 0;
297
310
  dir = parent;
@@ -304,8 +317,8 @@ function projectDir(io, inputCwd) {
304
317
  function resolveHookPolicy(args, io, inputCwd) {
305
318
  const flag = flagString(args, "config");
306
319
  if (flag) return { path: resolve(io.cwd, flag), found: "flag" };
307
- if (io.env.AGENTGUARD_CONFIG)
308
- return { path: resolve(io.cwd, io.env.AGENTGUARD_CONFIG), found: "env" };
320
+ const fromEnv = envTwin2(io.env, "CONFIG");
321
+ if (fromEnv) return { path: resolve(io.cwd, fromEnv), found: "env" };
309
322
  const start = projectDir(io, inputCwd) ?? io.cwd;
310
323
  const near = findPolicyUpwards(start);
311
324
  if (near) return { path: near, found: "project" };
@@ -326,7 +339,7 @@ function respond(io, client, result, summary, approveCommand) {
326
339
  const reason = JSON.stringify(e);
327
340
  const id = result.approvalId ? `, approval ${result.approvalId}` : "";
328
341
  const approve = e.code === "APPROVAL_REQUIRED" && result.approvalId ? ` To let this exact command run once: ${approveCommand(result.approvalId)}` : "";
329
- const systemMessage = `agentguard refused "${summary.slice(0, 120)}" (${e.code}${id}): ${e.cause}${approve}`;
342
+ const systemMessage = `okgate refused "${summary.slice(0, 120)}" (${e.code}${id}): ${e.cause}${approve}`;
330
343
  if (client === "gemini-cli") out(io, { decision: "deny", reason, systemMessage });
331
344
  else
332
345
  out(io, {
@@ -341,7 +354,7 @@ function respond(io, client, result, summary, approveCommand) {
341
354
  }
342
355
  if (result.would) {
343
356
  out(io, {
344
- systemMessage: `agentguard (hooks.mode: dry-run) would have stopped "${summary.slice(0, 120)}" with ${result.would.code}: ${result.would.cause} \u2014 it ran; nothing is blocked until hooks.mode is enforce`
357
+ systemMessage: `okgate (hooks.mode: dry-run) would have stopped "${summary.slice(0, 120)}" with ${result.would.code}: ${result.would.cause} \u2014 it ran; nothing is blocked until hooks.mode is enforce`
345
358
  });
346
359
  }
347
360
  }
@@ -349,7 +362,7 @@ async function hookCommand(args, io) {
349
362
  const event = args.positionals[0];
350
363
  if (event !== "pre-tool-use") {
351
364
  io.err(
352
- "usage: agentguard hook pre-tool-use [--client claude|codex|gemini] [--config agentguard.yaml] [--fallback-config path]\n run by a coding agent's pre-execution hook, with the hook's JSON on stdin; `agentguard hooks install` sets it up"
365
+ "usage: okgate hook pre-tool-use [--client claude|codex|gemini] [--config okgate.yaml] [--fallback-config path]\n run by a coding agent's pre-execution hook, with the hook's JSON on stdin; `okgate hooks install` sets it up"
353
366
  );
354
367
  return 1;
355
368
  }
@@ -381,7 +394,13 @@ async function hookCommand(args, io) {
381
394
  home,
382
395
  tmpDirs,
383
396
  stateDir: loaded.stateDir,
384
- guardFiles: [loaded.path, ...hookSettingsFiles({ cwd: resolve(workspace), home })]
397
+ // both names: creating okgate.yaml beside agentguard.yaml would replace the policy read
398
+ guardFiles: [
399
+ loaded.path,
400
+ ...POLICY_FILES.map((name) => join(dirname(loaded.path), name)),
401
+ ...hookSettingsFiles({ cwd: resolve(workspace), home })
402
+ ],
403
+ policyFile: basename(loaded.path)
385
404
  };
386
405
  const assessment = assessHookAction(loaded.policy, action, ctx);
387
406
  const reg = readRegistration(loaded);
@@ -391,7 +410,7 @@ async function hookCommand(args, io) {
391
410
  log: (line) => io.err(line)
392
411
  });
393
412
  const configHint = policyRef.found === "project" && dirname(policyRef.path) === resolve(workspace) ? "" : ` --config ${JSON.stringify(policyRef.path)}`;
394
- const approveCommand = (id) => `npx @agentwares/agentguard approve ${id}${configHint}`;
413
+ const approveCommand = (id) => `${INSTALL} approve ${id}${configHint}`;
395
414
  const result = await guard.preflight({
396
415
  action,
397
416
  assessment,
@@ -399,7 +418,7 @@ async function hookCommand(args, io) {
399
418
  humanTurn: () => client === "claude-code" ? humanTurnFromTranscript(action.transcriptPath, {
400
419
  requireOrigin: loaded.policy.hooks.irreversible.require_origin
401
420
  }) : {
402
- missing: `${client} transcripts are not a verified format for this check, so an irreversible command needs \`agentguard approve\``
421
+ missing: `${client} transcripts are not a verified format for this check, so an irreversible command needs \`okgate approve\``
403
422
  },
404
423
  approveCommand
405
424
  });
@@ -408,7 +427,7 @@ async function hookCommand(args, io) {
408
427
  } catch (err) {
409
428
  warn(
410
429
  io,
411
- `agentguard hook error \u2014 this call was NOT checked: ${describeError(err).replace(/\s+/g, " ").slice(0, 400)}`
430
+ `okgate hook error \u2014 this call was NOT checked: ${describeError(err).replace(/\s+/g, " ").slice(0, 400)}`
412
431
  );
413
432
  return 0;
414
433
  }
@@ -431,9 +450,7 @@ async function keyCommand(args, io) {
431
450
  const items = seq.items.filter(isMap);
432
451
  if (sub === "list" || sub === void 0) {
433
452
  if (items.length === 0)
434
- io.out(
435
- "no agents in agentguard.yaml \u2014 create one: agentguard key create <name> --allow 'crm_get_*'"
436
- );
453
+ io.out("no agents in okgate.yaml \u2014 create one: okgate key create <name> --allow 'crm_get_*'");
437
454
  for (const a of items) {
438
455
  const allow2 = a.get("allow");
439
456
  io.out(
@@ -444,7 +461,7 @@ async function keyCommand(args, io) {
444
461
  }
445
462
  if (!name) {
446
463
  io.err(
447
- "usage: agentguard key create <agent> [--allow pattern]... [--deny pattern]... [--writes n] [--spend n] [--deletes n] [--emails n] [--tool-calls n] [--mode dry-run|enforce] [--upstream name]..."
464
+ "usage: okgate key create <agent> [--allow pattern]... [--deny pattern]... [--writes n] [--spend n] [--deletes n] [--emails n] [--tool-calls n] [--mode dry-run|enforce] [--upstream name]..."
448
465
  );
449
466
  return 1;
450
467
  }
@@ -456,7 +473,7 @@ async function keyCommand(args, io) {
456
473
  }
457
474
  seq.items.splice(seq.items.indexOf(items[idx]), 1);
458
475
  writeFileSync(path, doc.toString());
459
- io.out(`revoked ${name}: removed from agentguard.yaml (running proxies pick it up on restart)`);
476
+ io.out(`revoked ${name}: removed from okgate.yaml (running proxies pick it up on restart)`);
460
477
  return 0;
461
478
  }
462
479
  if (sub !== "create") {
@@ -497,7 +514,7 @@ async function keyCommand(args, io) {
497
514
  `${existing ? "rotated" : "created"} agent "${name}" in ${path}${allow.length ? ` (allow: ${allow.join(", ")})` : " (allow: all tools)"}`
498
515
  );
499
516
  io.err(
500
- "the key is shown once; give it to the agent as `Authorization: Bearer <key>` (HTTP) \u2014 over stdio use `agentguard proxy --agent " + name + "`"
517
+ "the key is shown once; give it to the agent as `Authorization: Bearer <key>` (HTTP) \u2014 over stdio use `okgate proxy --agent " + name + "`"
501
518
  );
502
519
  io.out(key);
503
520
  return 0;
@@ -510,6 +527,9 @@ import {
510
527
  renderPermissionDiffMarkdown
511
528
  } from "@agentwares/agentguard-core";
512
529
  var DEFAULT_PERMISSION_PATHS = [
530
+ "okgate.yaml",
531
+ "okgate.yml",
532
+ // the policy's name before the rename, still read when there is no okgate.yaml
513
533
  "agentguard.yaml",
514
534
  "agentguard.yml",
515
535
  ".claude/settings.json",
@@ -519,7 +539,7 @@ var DEFAULT_PERMISSION_PATHS = [
519
539
  ".cursor/mcp.json",
520
540
  ".vscode/mcp.json"
521
541
  ];
522
- var PERMISSION_FILE = /(^|\/)(agentguard[^/]*\.ya?ml|\.claude\/settings(\.local)?\.json|[^/]*mcp[^/]*\.json|claude_desktop_config\.json)$/;
542
+ var PERMISSION_FILE = /(^|\/)((okgate|agentguard)[^/]*\.ya?ml|\.claude\/settings(\.local)?\.json|[^/]*mcp[^/]*\.json|claude_desktop_config\.json)$/;
523
543
  function git(cwd, argv) {
524
544
  try {
525
545
  return execFileSync("git", argv, {
@@ -629,7 +649,7 @@ async function reportCommand(args, io) {
629
649
  io.out(
630
650
  chain.ok ? `Audit chain: ${chain.entries} entries, verified (${loaded.auditPath}).` : `Audit chain BROKEN at entry ${chain.brokenAt}: ${chain.reason}`
631
651
  );
632
- if (runId && listRuns(entries).length > 1) io.out(`Other runs: agentguard report --all`);
652
+ if (runId && listRuns(entries).length > 1) io.out(`Other runs: okgate report --all`);
633
653
  return 0;
634
654
  }
635
655
  async function diffCommand(args, io) {
@@ -654,11 +674,11 @@ async function verifyCommand(args, io) {
654
674
  }
655
675
  async function statusCommand(args, io) {
656
676
  const loaded = loadPolicyFor(args, io, { allowMissingEnv: true });
657
- const { guard, kill } = createFileGuard(loaded, { alerts: false, env: io.env });
677
+ const { guard } = createFileGuard(loaded, { alerts: false, env: io.env });
658
678
  const entries = readAuditFile(loaded.auditPath);
659
679
  const runId = flagString(args, "run") ?? latestRunId(entries) ?? "(none yet)";
660
680
  const status = await guard.status(runId);
661
- const killed = kill.check();
681
+ const killed = status.killed;
662
682
  const reg = readRegistration(loaded);
663
683
  const pending = await guard.approvals.list("pending");
664
684
  if (flagBool(args, "json")) {
@@ -682,15 +702,11 @@ async function statusCommand(args, io) {
682
702
  io.out(
683
703
  `policy ${loaded.path} (mode: ${loaded.policy.mode}, ${loaded.policy.upstreams.length} upstreams)`
684
704
  );
685
- io.out(
686
- `kill ${killed.killed ? `ON \u2014 ${killed.reason} (agentguard resume to clear)` : "off"}`
687
- );
688
- io.out(
689
- `http ${reg ? `${reg.url} (pid ${reg.pid})` : "not running (agentguard proxy --http)"}`
690
- );
705
+ io.out(`kill ${killed.killed ? `ON \u2014 ${killed.reason} (okgate resume to clear)` : "off"}`);
706
+ io.out(`http ${reg ? `${reg.url} (pid ${reg.pid})` : "not running (okgate proxy --http)"}`);
691
707
  io.out(`audit ${entries.length} entries in ${loaded.auditPath}`);
692
708
  io.out(
693
- `pending ${pending.length} approval${pending.length === 1 ? "" : "s"}${pending.length ? ` \u2014 agentguard approvals` : ""}`
709
+ `pending ${pending.length} approval${pending.length === 1 ? "" : "s"}${pending.length ? ` \u2014 okgate approvals` : ""}`
694
710
  );
695
711
  io.out(`run ${runId}`);
696
712
  const fmt = (scope) => Object.entries(status.caps[scope]).map(([k, limit]) => `${k} ${status.usage[scope][k] ?? 0}/${limit}`).join(" ") || "no caps";
@@ -700,41 +716,43 @@ async function statusCommand(args, io) {
700
716
  }
701
717
 
702
718
  // src/cli.ts
703
- var proxyCommand = async (args, io) => (await import("./proxy-3Z5YEZ4R.js")).proxyCommand(args, io);
704
- var initCommand = async (args, io) => (await import("./init-CWROGV5I.js")).initCommand(args, io);
705
- var toolsCommand = async (args, io) => (await import("./tools-3LLDG3XQ.js")).toolsCommand(args, io);
706
- var auditCommand = async (args, io) => (await import("./audit-2YCMHMCP.js")).auditCommand(args, io);
707
- var HELP = `agentguard \u2014 MCP policy proxy for agents that touch production
719
+ var proxyCommand = async (args, io) => (await import("./proxy-6GP63TLD.js")).proxyCommand(args, io);
720
+ var initCommand = async (args, io) => (await import("./init-MKPQU2JG.js")).initCommand(args, io);
721
+ var toolsCommand = async (args, io) => (await import("./tools-XS7PMTLT.js")).toolsCommand(args, io);
722
+ var auditCommand = async (args, io) => (await import("./audit-5LUDXZLG.js")).auditCommand(args, io);
723
+ var HELP = `okgate \u2014 MCP policy proxy for agents that touch production
708
724
 
709
- npx @agentwares/agentguard init read your MCP config, write agentguard.yaml (dry-run), route every server through the proxy
710
- agentguard report [--run id|--all] what this run did / would have destroyed / spent, where it was halted
711
- agentguard diff [--run id] record-by-record mutation diff from a dry run
712
- agentguard verify [audit.jsonl] prove the hash-chained audit log was not edited
713
- agentguard connect <key> [--write] point this machine at your hosted proxy (paid tiers)
725
+ ${INSTALL} init
726
+ read your MCP config, write okgate.yaml (dry-run), route every server through the proxy
727
+ okgate report [--run id|--all] what this run did / would have destroyed / spent, where it was halted
728
+ okgate diff [--run id] record-by-record mutation diff from a dry run
729
+ okgate verify [audit.jsonl] prove the hash-chained audit log was not edited
730
+ okgate connect <key> [--write] point this machine at your hosted proxy (paid tiers)
714
731
 
715
- agentguard hooks install [--project|--user] [--client claude|codex|gemini|all]
716
- check a coding agent's own shell commands and file edits against agentguard.yaml (dry-run first);
732
+ okgate hooks install [--project|--user] [--client claude|codex|gemini|all]
733
+ check a coding agent's own shell commands and file edits against okgate.yaml (dry-run first);
717
734
  irreversible commands (push, merge, publish, send, rm outside the repo) only on a turn a person typed
718
- agentguard hooks uninstall | status
719
- agentguard hook pre-tool-use what the installed hook runs (reads the harness's JSON on stdin)
735
+ okgate hooks uninstall | status
736
+ okgate hook pre-tool-use what the installed hook runs (reads the harness's JSON on stdin)
720
737
 
721
- agentguard audit [--since 7d|30d|all] [--client claude|codex|all] [--json]
738
+ okgate audit [--since 7d|30d|all] [--client claude|codex|all] [--json]
722
739
  which rules in CLAUDE.md / AGENTS.md / GEMINI.md / .cursor/rules your coding agents broke,
723
740
  from this machine's Claude Code and Codex sessions in this repo (nothing is sent anywhere)
724
- agentguard audit --enforce [--preview]
725
- write the checkable rules into agentguard.yaml as hook rules, in dry-run, and install the hook
741
+ okgate audit --enforce [--preview]
742
+ write the checkable rules into okgate.yaml as hook rules, in dry-run, and install the hook
726
743
 
727
- agentguard proxy [--http --port 8788] [--agent name] [--run-id id] [--mode dry-run|enforce]
728
- agentguard tools [--json] the tools your agent will see, with class and why
729
- agentguard status [--run id] counters vs caps, kill state, pending approvals
744
+ okgate proxy [--http --port 8788] [--agent name] [--run-id id] [--mode dry-run|enforce]
745
+ okgate tools [--json] the tools your agent will see, with class and why
746
+ okgate status [--run id] counters vs caps, kill state, pending approvals
730
747
 
731
- agentguard kill [reason] halt every run now (file + running HTTP proxy); agentguard resume
732
- agentguard approvals [--all] pending approvals; agentguard approve <id> | deny <id> [--note text]
733
- agentguard key create <agent> [--allow 'crm_get_*']... [--deny p] [--writes n] [--spend n] [--mode m]
734
- agentguard key list | revoke <agent>
735
- agentguard permission-diff [--base ref] [--head ref] [--paths a,b] [--format markdown|json] [--fail-on-widen]
748
+ okgate kill [reason] halt every run now (file + running HTTP proxy); okgate resume
749
+ okgate approvals [--all] pending approvals; okgate approve <id> | deny <id> [--note text]
750
+ okgate key create <agent> [--allow 'crm_get_*']... [--deny p] [--writes n] [--spend n] [--mode m]
751
+ okgate key list | revoke <agent>
752
+ okgate permission-diff [--base ref] [--head ref] [--paths a,b] [--format markdown|json] [--fail-on-widen]
736
753
 
737
- Options: --config <agentguard.yaml> (or AGENTGUARD_CONFIG), --json, --help, --version
754
+ Options: --config <okgate.yaml> (or OKGATE_CONFIG), --json, --help, --version
755
+ Renamed from agentguard: agentguard.yaml, .agentguard/, AGENTGUARD_* and the agentguard bin keep working.
738
756
  Docs: https://github.com/agentwares/agentguard/tree/main/apps/agentguard-cli`;
739
757
  async function main(argv, io = defaultIo()) {
740
758
  const args = parseArgs(argv);
@@ -805,7 +823,8 @@ async function main(argv, io = defaultIo()) {
805
823
  return 1;
806
824
  }
807
825
  }
808
- var isMain = process.argv[1] !== void 0 && /(^|\/)(cli\.[cm]?[jt]s|agentguard)$/.test(process.argv[1]);
826
+ var embedded = globalThis[/* @__PURE__ */ Symbol.for("okgate.cli.embedded")] === true;
827
+ var isMain = !embedded && process.argv[1] !== void 0 && /(^|[\\/])(cli\.[cm]?[jt]s|okgate|agentguard)$/.test(process.argv[1]);
809
828
  if (isMain) {
810
829
  main(process.argv.slice(2)).then(
811
830
  (code) => {
@@ -825,4 +844,4 @@ export {
825
844
  HELP,
826
845
  main
827
846
  };
828
- //# sourceMappingURL=chunk-6TUQD666.js.map
847
+ //# sourceMappingURL=chunk-ZG4LGUJE.js.map