@catp-protocol/cli 0.1.0

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 (45) hide show
  1. package/dist/audit/logger.d.ts +8 -0
  2. package/dist/audit/logger.d.ts.map +1 -0
  3. package/dist/audit/logger.js +56 -0
  4. package/dist/audit/logger.js.map +1 -0
  5. package/dist/audit/verifier.d.ts +8 -0
  6. package/dist/audit/verifier.d.ts.map +1 -0
  7. package/dist/audit/verifier.js +42 -0
  8. package/dist/audit/verifier.js.map +1 -0
  9. package/dist/cli.d.ts +3 -0
  10. package/dist/cli.d.ts.map +1 -0
  11. package/dist/cli.js +47 -0
  12. package/dist/cli.js.map +1 -0
  13. package/dist/commands/init.d.ts +2 -0
  14. package/dist/commands/init.d.ts.map +1 -0
  15. package/dist/commands/init.js +42 -0
  16. package/dist/commands/init.js.map +1 -0
  17. package/dist/commands/log.d.ts +8 -0
  18. package/dist/commands/log.d.ts.map +1 -0
  19. package/dist/commands/log.js +64 -0
  20. package/dist/commands/log.js.map +1 -0
  21. package/dist/commands/validate.d.ts +4 -0
  22. package/dist/commands/validate.d.ts.map +1 -0
  23. package/dist/commands/validate.js +17 -0
  24. package/dist/commands/validate.js.map +1 -0
  25. package/dist/hook/post.d.ts +2 -0
  26. package/dist/hook/post.d.ts.map +1 -0
  27. package/dist/hook/post.js +42 -0
  28. package/dist/hook/post.js.map +1 -0
  29. package/dist/hook/pre.d.ts +2 -0
  30. package/dist/hook/pre.d.ts.map +1 -0
  31. package/dist/hook/pre.js +52 -0
  32. package/dist/hook/pre.js.map +1 -0
  33. package/dist/policy/engine.d.ts +8 -0
  34. package/dist/policy/engine.d.ts.map +1 -0
  35. package/dist/policy/engine.js +52 -0
  36. package/dist/policy/engine.js.map +1 -0
  37. package/dist/policy/loader.d.ts +4 -0
  38. package/dist/policy/loader.d.ts.map +1 -0
  39. package/dist/policy/loader.js +69 -0
  40. package/dist/policy/loader.js.map +1 -0
  41. package/dist/policy/types.d.ts +30 -0
  42. package/dist/policy/types.d.ts.map +1 -0
  43. package/dist/policy/types.js +2 -0
  44. package/dist/policy/types.js.map +1 -0
  45. package/package.json +39 -0
@@ -0,0 +1,8 @@
1
+ import type { AuditEntry, HookInput } from "../policy/types.js";
2
+ export declare function computeCommitment(tool: string, decision: "allow" | "deny", ts: string, prev?: string): string;
3
+ export declare function summarizeInput(input: HookInput): string;
4
+ export declare function auditDir(agentId: string): string;
5
+ export declare function getLastCommitment(agentId: string): string;
6
+ export declare function appendAuditEntry(agentId: string, entry: AuditEntry): void;
7
+ export declare function buildEntry(input: HookInput, decision: "allow" | "deny", ruleMatched: string | null, prevCommitment?: string): AuditEntry;
8
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/audit/logger.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAMhE,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,OAAO,GAAG,MAAM,EAC1B,EAAE,EAAE,MAAM,EACV,IAAI,GAAE,MAAY,GACjB,MAAM,CAOR;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAGvD;AAED,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAGhD;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAYzD;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,IAAI,CAIzE;AAED,wBAAgB,UAAU,CACxB,KAAK,EAAE,SAAS,EAChB,QAAQ,EAAE,OAAO,GAAG,MAAM,EAC1B,WAAW,EAAE,MAAM,GAAG,IAAI,EAC1B,cAAc,GAAE,MAAY,GAC3B,UAAU,CAUZ"}
@@ -0,0 +1,56 @@
1
+ import { createHash } from "node:crypto";
2
+ import { appendFileSync, mkdirSync, readFileSync } from "node:fs";
3
+ import { join } from "node:path";
4
+ import { homedir } from "node:os";
5
+ // Phase 0: SHA-256 commitment placeholder.
6
+ // Chains on fields stored in the log (tool, decision, ts, prev) so the chain
7
+ // is verifiable from the JSONL file alone without replaying tool_input.
8
+ // Phase 1 replaces this with a Poseidon hash over the full action witness via WASM.
9
+ export function computeCommitment(tool, decision, ts, prev = "0") {
10
+ return createHash("sha256")
11
+ .update(tool)
12
+ .update(decision)
13
+ .update(ts)
14
+ .update(prev)
15
+ .digest("hex");
16
+ }
17
+ export function summarizeInput(input) {
18
+ const raw = JSON.stringify(input.tool_input);
19
+ return raw.length > 200 ? raw.slice(0, 200) + "…" : raw;
20
+ }
21
+ export function auditDir(agentId) {
22
+ const date = new Date().toISOString().slice(0, 10);
23
+ return join(homedir(), ".catp", "audit", agentId, date);
24
+ }
25
+ export function getLastCommitment(agentId) {
26
+ const dir = auditDir(agentId);
27
+ const file = join(dir, "actions.jsonl");
28
+ try {
29
+ const content = readFileSync(file, "utf8").trimEnd();
30
+ if (!content)
31
+ return "0";
32
+ const lastLine = content.split("\n").pop() ?? "";
33
+ const entry = JSON.parse(lastLine);
34
+ return entry.commitment;
35
+ }
36
+ catch {
37
+ return "0";
38
+ }
39
+ }
40
+ export function appendAuditEntry(agentId, entry) {
41
+ const dir = auditDir(agentId);
42
+ mkdirSync(dir, { recursive: true });
43
+ appendFileSync(join(dir, "actions.jsonl"), JSON.stringify(entry) + "\n", "utf8");
44
+ }
45
+ export function buildEntry(input, decision, ruleMatched, prevCommitment = "0") {
46
+ const ts = new Date().toISOString();
47
+ return {
48
+ ts,
49
+ tool: input.tool_name,
50
+ decision,
51
+ rule_matched: ruleMatched,
52
+ commitment: computeCommitment(input.tool_name, decision, ts, prevCommitment),
53
+ input_summary: summarizeInput(input),
54
+ };
55
+ }
56
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/audit/logger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export interface VerifyResult {
2
+ ok: boolean;
3
+ checked: number;
4
+ broken_at: number | null;
5
+ message: string;
6
+ }
7
+ export declare function verifyChain(logFile: string): Promise<VerifyResult>;
8
+ //# sourceMappingURL=verifier.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verifier.d.ts","sourceRoot":"","sources":["../../src/audit/verifier.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CA6BxE"}
@@ -0,0 +1,42 @@
1
+ import { createReadStream } from "node:fs";
2
+ import { createInterface } from "node:readline";
3
+ import { computeCommitment } from "./logger.js";
4
+ export async function verifyChain(logFile) {
5
+ const lines = await readLines(logFile);
6
+ if (lines.length === 0) {
7
+ return { ok: true, checked: 0, broken_at: null, message: "empty log" };
8
+ }
9
+ let prev = "0";
10
+ for (let i = 0; i < lines.length; i++) {
11
+ let entry;
12
+ try {
13
+ entry = JSON.parse(lines[i]);
14
+ }
15
+ catch {
16
+ return { ok: false, checked: i, broken_at: i, message: `line ${i + 1}: invalid JSON` };
17
+ }
18
+ const decision = entry.decision;
19
+ const expected = computeCommitment(entry.tool, decision, entry.ts, prev);
20
+ if (entry.commitment !== expected) {
21
+ return {
22
+ ok: false,
23
+ checked: i,
24
+ broken_at: i,
25
+ message: `line ${i + 1}: commitment mismatch (chain broken or tampered)`,
26
+ };
27
+ }
28
+ prev = entry.commitment;
29
+ }
30
+ return { ok: true, checked: lines.length, broken_at: null, message: "chain intact" };
31
+ }
32
+ async function readLines(file) {
33
+ return new Promise((resolve, reject) => {
34
+ const lines = [];
35
+ const rl = createInterface({ input: createReadStream(file), crlfDelay: Infinity });
36
+ rl.on("line", (l) => { if (l.trim())
37
+ lines.push(l); });
38
+ rl.on("close", () => resolve(lines));
39
+ rl.on("error", reject);
40
+ });
41
+ }
42
+ //# sourceMappingURL=verifier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verifier.js","sourceRoot":"","sources":["../../src/audit/verifier.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAUhD,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAAe;IAC/C,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,CAAC;IACvC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC;IACzE,CAAC;IAED,IAAI,IAAI,GAAG,GAAG,CAAC;IACf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,IAAI,KAAiB,CAAC;QACtB,IAAI,CAAC;YACH,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAe,CAAC;QAC7C,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QACzF,CAAC;QAED,MAAM,QAAQ,GAAG,KAAK,CAAC,QAA4B,CAAC;QACpD,MAAM,QAAQ,GAAG,iBAAiB,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QACzE,IAAI,KAAK,CAAC,UAAU,KAAK,QAAQ,EAAE,CAAC;YAClC,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,OAAO,EAAE,CAAC;gBACV,SAAS,EAAE,CAAC;gBACZ,OAAO,EAAE,QAAQ,CAAC,GAAG,CAAC,kDAAkD;aACzE,CAAC;QACJ,CAAC;QACD,IAAI,GAAG,KAAK,CAAC,UAAU,CAAC;IAC1B,CAAC;IAED,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC;AACvF,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,IAAY;IACnC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,gBAAgB,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC;QACnF,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC,IAAI,EAAE;YAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACvD,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;QACrC,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACzB,CAAC,CAAC,CAAC;AACL,CAAC"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from "commander";
3
+ import { runPreHook } from "./hook/pre.js";
4
+ import { runPostHook } from "./hook/post.js";
5
+ import { cmdInit } from "./commands/init.js";
6
+ import { cmdValidate } from "./commands/validate.js";
7
+ import { cmdLogShow, cmdLogVerify } from "./commands/log.js";
8
+ const program = new Command();
9
+ program
10
+ .name("catp")
11
+ .description("CATP enforcement plugin — policy enforcement and audit for AI agents")
12
+ .version("0.1.0");
13
+ program
14
+ .command("init")
15
+ .description("Scaffold a catp-policy.toml in the current directory")
16
+ .action(cmdInit);
17
+ program
18
+ .command("validate")
19
+ .description("Validate catp-policy.toml syntax")
20
+ .option("-f, --file <path>", "path to policy file (default: auto-discover)")
21
+ .action(cmdValidate);
22
+ const hook = program.command("hook").description("Hook handlers called by agent frameworks");
23
+ hook
24
+ .command("pre")
25
+ .description("PreToolUse handler — reads stdin JSON, allows or blocks")
26
+ .action(() => { runPreHook().catch(() => process.exit(0)); });
27
+ hook
28
+ .command("post")
29
+ .description("PostToolUse handler — reads stdin JSON, records to audit log")
30
+ .action(() => { runPostHook().catch(() => process.exit(0)); });
31
+ const log = program.command("log").description("Audit log commands");
32
+ log
33
+ .command("show")
34
+ .description("Display recent audit log entries")
35
+ .option("-n, --lines <n>", "number of lines to show", "50")
36
+ .option("--agent <id>", "agent id (default: from policy file)")
37
+ .action(cmdLogShow);
38
+ log
39
+ .command("verify")
40
+ .description("Verify commitment chain integrity")
41
+ .option("--agent <id>", "agent id (default: from policy file)")
42
+ .action(cmdLogVerify);
43
+ program.parseAsync(process.argv).catch((err) => {
44
+ process.stderr.write(`catp: ${err.message}\n`);
45
+ process.exit(1);
46
+ });
47
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAE7D,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,MAAM,CAAC;KACZ,WAAW,CAAC,sEAAsE,CAAC;KACnF,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,sDAAsD,CAAC;KACnE,MAAM,CAAC,OAAO,CAAC,CAAC;AAEnB,OAAO;KACJ,OAAO,CAAC,UAAU,CAAC;KACnB,WAAW,CAAC,kCAAkC,CAAC;KAC/C,MAAM,CAAC,mBAAmB,EAAE,8CAA8C,CAAC;KAC3E,MAAM,CAAC,WAAW,CAAC,CAAC;AAEvB,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC,0CAA0C,CAAC,CAAC;AAE7F,IAAI;KACD,OAAO,CAAC,KAAK,CAAC;KACd,WAAW,CAAC,yDAAyD,CAAC;KACtE,MAAM,CAAC,GAAG,EAAE,GAAG,UAAU,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAEhE,IAAI;KACD,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,8DAA8D,CAAC;KAC3E,MAAM,CAAC,GAAG,EAAE,GAAG,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAEjE,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,oBAAoB,CAAC,CAAC;AAErE,GAAG;KACA,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,kCAAkC,CAAC;KAC/C,MAAM,CAAC,iBAAiB,EAAE,yBAAyB,EAAE,IAAI,CAAC;KAC1D,MAAM,CAAC,cAAc,EAAE,sCAAsC,CAAC;KAC9D,MAAM,CAAC,UAAU,CAAC,CAAC;AAEtB,GAAG;KACA,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,mCAAmC,CAAC;KAChD,MAAM,CAAC,cAAc,EAAE,sCAAsC,CAAC;KAC9D,MAAM,CAAC,YAAY,CAAC,CAAC;AAExB,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IAC7C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,SAAU,GAAa,CAAC,OAAO,IAAI,CAAC,CAAC;IAC1D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function cmdInit(): void;
2
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AA+BA,wBAAgB,OAAO,IAAI,IAAI,CAa9B"}
@@ -0,0 +1,42 @@
1
+ import { writeFileSync, existsSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ const TEMPLATE = `[agent]
4
+ id = "my-agent"
5
+ version = "1"
6
+
7
+ # Rules are evaluated top-to-bottom; first match wins.
8
+ # Omit pattern/path fields to match any invocation of that tool.
9
+
10
+ [[rules]]
11
+ tool = "Bash"
12
+ allow = false
13
+ pattern = ["rm -rf*", "*--force*", "*git push*prod*"]
14
+ reason = "Destructive or production-affecting shell commands are blocked"
15
+
16
+ [[rules]]
17
+ tool = "Bash"
18
+ allow = true
19
+
20
+ [[rules]]
21
+ tool = "Write"
22
+ allow = true
23
+ path_allowlist = ["./src/**", "./tests/**", "./docs/**"]
24
+
25
+ [[rules]]
26
+ tool = "WebFetch"
27
+ allow = false
28
+ reason = "External network calls require explicit approval"
29
+ `;
30
+ export function cmdInit() {
31
+ const dest = join(process.cwd(), "catp-policy.toml");
32
+ if (existsSync(dest)) {
33
+ process.stdout.write("catp-policy.toml already exists — skipping.\n");
34
+ return;
35
+ }
36
+ writeFileSync(dest, TEMPLATE, "utf8");
37
+ process.stdout.write("Created catp-policy.toml\n\nNext steps:\n" +
38
+ " 1. Edit catp-policy.toml to match your agent's requirements\n" +
39
+ " 2. Run: catp validate\n" +
40
+ " 3. Add CATP hooks to ~/.claude/settings.json (see README)\n");
41
+ }
42
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,QAAQ,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;CA0BhB,CAAC;AAEF,MAAM,UAAU,OAAO;IACrB,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,kBAAkB,CAAC,CAAC;IACrD,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACrB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,+CAA+C,CAAC,CAAC;QACtE,OAAO;IACT,CAAC;IACD,aAAa,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;IACtC,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,2CAA2C;QAC3C,iEAAiE;QACjE,2BAA2B;QAC3B,+DAA+D,CAChE,CAAC;AACJ,CAAC"}
@@ -0,0 +1,8 @@
1
+ export declare function cmdLogShow(opts: {
2
+ lines: string;
3
+ agent?: string;
4
+ }): void;
5
+ export declare function cmdLogVerify(opts: {
6
+ agent?: string;
7
+ }): Promise<void>;
8
+ //# sourceMappingURL=log.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../../src/commands/log.ts"],"names":[],"mappings":"AAyBA,wBAAgB,UAAU,CAAC,IAAI,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAuBxE;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAe1E"}
@@ -0,0 +1,64 @@
1
+ import { readFileSync, readdirSync, existsSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { homedir } from "node:os";
4
+ import { findPolicyFile, loadPolicy } from "../policy/loader.js";
5
+ import { verifyChain } from "../audit/verifier.js";
6
+ function resolveAgentId(opts) {
7
+ if (opts.agent)
8
+ return opts.agent;
9
+ const policyPath = findPolicyFile();
10
+ if (!policyPath) {
11
+ process.stderr.write("catp: no --agent id and no catp-policy.toml found\n");
12
+ process.exit(1);
13
+ }
14
+ return loadPolicy(policyPath).agent.id;
15
+ }
16
+ function latestLogFile(agentId) {
17
+ const base = join(homedir(), ".catp", "audit", agentId);
18
+ if (!existsSync(base))
19
+ return null;
20
+ const dates = readdirSync(base).sort().reverse();
21
+ if (dates.length === 0)
22
+ return null;
23
+ return join(base, dates[0], "actions.jsonl");
24
+ }
25
+ export function cmdLogShow(opts) {
26
+ const agentId = resolveAgentId(opts);
27
+ const logFile = latestLogFile(agentId);
28
+ if (!logFile || !existsSync(logFile)) {
29
+ process.stdout.write(`No audit log found for agent "${agentId}"\n`);
30
+ return;
31
+ }
32
+ const lines = readFileSync(logFile, "utf8").trim().split("\n").filter(Boolean);
33
+ const n = Math.min(parseInt(opts.lines, 10) || 50, lines.length);
34
+ const recent = lines.slice(-n);
35
+ for (const line of recent) {
36
+ try {
37
+ const e = JSON.parse(line);
38
+ const icon = e.decision === "allow" ? "✓" : "✗";
39
+ const rule = e.rule_matched ? ` [${e.rule_matched}]` : "";
40
+ process.stdout.write(`${icon} ${e.ts} ${e.tool}${rule}\n ${e.input_summary}\n`);
41
+ }
42
+ catch {
43
+ process.stdout.write(`? ${line}\n`);
44
+ }
45
+ }
46
+ process.stdout.write(`\n${recent.length} entries from ${logFile}\n`);
47
+ }
48
+ export async function cmdLogVerify(opts) {
49
+ const agentId = resolveAgentId(opts);
50
+ const logFile = latestLogFile(agentId);
51
+ if (!logFile || !existsSync(logFile)) {
52
+ process.stdout.write(`No audit log found for agent "${agentId}"\n`);
53
+ return;
54
+ }
55
+ const result = await verifyChain(logFile);
56
+ if (result.ok) {
57
+ process.stdout.write(`✓ Chain intact — ${result.checked} entries verified\n`);
58
+ }
59
+ else {
60
+ process.stderr.write(`✗ Chain broken at entry ${result.broken_at}: ${result.message}\n`);
61
+ process.exit(1);
62
+ }
63
+ }
64
+ //# sourceMappingURL=log.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log.js","sourceRoot":"","sources":["../../src/commands/log.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export declare function cmdValidate(opts: {
2
+ file?: string;
3
+ }): void;
4
+ //# sourceMappingURL=validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"AAEA,wBAAgB,WAAW,CAAC,IAAI,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAgBzD"}
@@ -0,0 +1,17 @@
1
+ import { findPolicyFile, loadPolicy } from "../policy/loader.js";
2
+ export function cmdValidate(opts) {
3
+ const policyPath = opts.file ?? findPolicyFile();
4
+ if (!policyPath) {
5
+ process.stderr.write("catp: no catp-policy.toml found in current directory or any parent\n");
6
+ process.exit(1);
7
+ }
8
+ try {
9
+ const policy = loadPolicy(policyPath);
10
+ process.stdout.write(`✓ ${policyPath}\n agent: ${policy.agent.id} v${policy.agent.version}\n rules: ${policy.rules.length}\n`);
11
+ }
12
+ catch (err) {
13
+ process.stderr.write(`✗ ${policyPath}\n ${err.message}\n`);
14
+ process.exit(1);
15
+ }
16
+ }
17
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjE,MAAM,UAAU,WAAW,CAAC,IAAuB;IACjD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,IAAI,cAAc,EAAE,CAAC;IACjD,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,sEAAsE,CAAC,CAAC;QAC7F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC;QACtC,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,KAAK,UAAU,cAAc,MAAM,CAAC,KAAK,CAAC,EAAE,KAAK,MAAM,CAAC,KAAK,CAAC,OAAO,cAAc,MAAM,CAAC,KAAK,CAAC,MAAM,IAAI,CAC3G,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,UAAU,OAAQ,GAAa,CAAC,OAAO,IAAI,CAAC,CAAC;QACvE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function runPostHook(): Promise<void>;
2
+ //# sourceMappingURL=post.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"post.d.ts","sourceRoot":"","sources":["../../src/hook/post.ts"],"names":[],"mappings":"AAIA,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CA6BjD"}
@@ -0,0 +1,42 @@
1
+ import { findPolicyFile, loadPolicy } from "../policy/loader.js";
2
+ import { buildEntry, appendAuditEntry, getLastCommitment } from "../audit/logger.js";
3
+ export async function runPostHook() {
4
+ const raw = await readStdin();
5
+ let input;
6
+ try {
7
+ input = JSON.parse(raw);
8
+ }
9
+ catch {
10
+ process.exit(0);
11
+ }
12
+ const policyPath = findPolicyFile();
13
+ if (!policyPath)
14
+ process.exit(0);
15
+ let policy;
16
+ try {
17
+ policy = loadPolicy(policyPath);
18
+ }
19
+ catch {
20
+ process.exit(0);
21
+ }
22
+ // PostToolUse always records allow — the action already executed
23
+ const prev = getLastCommitment(policy.agent.id);
24
+ const entry = buildEntry(input, "allow", null, prev);
25
+ try {
26
+ appendAuditEntry(policy.agent.id, entry);
27
+ }
28
+ catch {
29
+ // Audit log failure must not block the agent
30
+ }
31
+ process.exit(0);
32
+ }
33
+ async function readStdin() {
34
+ return new Promise((resolve) => {
35
+ let data = "";
36
+ process.stdin.setEncoding("utf8");
37
+ process.stdin.on("data", (chunk) => { data += chunk; });
38
+ process.stdin.on("end", () => resolve(data));
39
+ process.stdin.on("error", () => resolve(""));
40
+ });
41
+ }
42
+ //# sourceMappingURL=post.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"post.js","sourceRoot":"","sources":["../../src/hook/post.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAGrF,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,MAAM,GAAG,GAAG,MAAM,SAAS,EAAE,CAAC;IAC9B,IAAI,KAAgB,CAAC;IACrB,IAAI,CAAC;QACH,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAc,CAAC;IACvC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,UAAU,GAAG,cAAc,EAAE,CAAC;IACpC,IAAI,CAAC,UAAU;QAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAEjC,IAAI,MAAM,CAAC;IACX,IAAI,CAAC;QACH,MAAM,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC;IAClC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,iEAAiE;IACjE,MAAM,IAAI,GAAG,iBAAiB,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAChD,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IACrD,IAAI,CAAC;QACH,gBAAgB,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;IAC3C,CAAC;IAAC,MAAM,CAAC;QACP,6CAA6C;IAC/C,CAAC;IAED,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,KAAK,UAAU,SAAS;IACtB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,IAAI,IAAI,GAAG,EAAE,CAAC;QACd,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAClC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,GAAG,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACxD,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QAC7C,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function runPreHook(): Promise<void>;
2
+ //# sourceMappingURL=pre.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pre.d.ts","sourceRoot":"","sources":["../../src/hook/pre.ts"],"names":[],"mappings":"AAKA,wBAAsB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CA2ChD"}
@@ -0,0 +1,52 @@
1
+ import { findPolicyFile, loadPolicy } from "../policy/loader.js";
2
+ import { evaluate } from "../policy/engine.js";
3
+ import { buildEntry, appendAuditEntry, getLastCommitment } from "../audit/logger.js";
4
+ export async function runPreHook() {
5
+ const raw = await readStdin();
6
+ let input;
7
+ try {
8
+ input = JSON.parse(raw);
9
+ }
10
+ catch {
11
+ process.exit(0);
12
+ }
13
+ const policyPath = findPolicyFile();
14
+ if (!policyPath) {
15
+ process.exit(0);
16
+ }
17
+ let policy;
18
+ try {
19
+ policy = loadPolicy(policyPath);
20
+ }
21
+ catch (err) {
22
+ process.stderr.write(`catp: policy error: ${err.message}\n`);
23
+ process.exit(0);
24
+ }
25
+ const decision = evaluate(policy, input);
26
+ const ruleName = decision.rule
27
+ ? `${decision.rule.tool}:${decision.rule.allow ? "allow" : "deny"}`
28
+ : null;
29
+ const prev = getLastCommitment(policy.agent.id);
30
+ const entry = buildEntry(input, decision.allow ? "allow" : "deny", ruleName, prev);
31
+ try {
32
+ appendAuditEntry(policy.agent.id, entry);
33
+ }
34
+ catch {
35
+ // Audit log failure must not block the agent
36
+ }
37
+ if (!decision.allow) {
38
+ process.stdout.write(JSON.stringify({ decision: "block", reason: decision.reason }) + "\n");
39
+ process.exit(2);
40
+ }
41
+ process.exit(0);
42
+ }
43
+ async function readStdin() {
44
+ return new Promise((resolve) => {
45
+ let data = "";
46
+ process.stdin.setEncoding("utf8");
47
+ process.stdin.on("data", (chunk) => { data += chunk; });
48
+ process.stdin.on("end", () => resolve(data));
49
+ process.stdin.on("error", () => resolve(""));
50
+ });
51
+ }
52
+ //# sourceMappingURL=pre.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pre.js","sourceRoot":"","sources":["../../src/hook/pre.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { CatpPolicy, Rule, HookInput } from "./types.js";
2
+ export interface Decision {
3
+ allow: boolean;
4
+ rule: Rule | null;
5
+ reason: string;
6
+ }
7
+ export declare function evaluate(policy: CatpPolicy, input: HookInput): Decision;
8
+ //# sourceMappingURL=engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/policy/engine.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE9D,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,OAAO,CAAC;IACf,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,QAAQ,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,SAAS,GAAG,QAAQ,CAiBvE"}
@@ -0,0 +1,52 @@
1
+ import micromatch from "micromatch";
2
+ export function evaluate(policy, input) {
3
+ const toolRules = policy.rules.filter((r) => r.tool === "*" || r.tool === input.tool_name);
4
+ for (const rule of toolRules) {
5
+ if (matchesRule(rule, input)) {
6
+ return {
7
+ allow: rule.allow,
8
+ rule,
9
+ reason: rule.reason ?? (rule.allow ? "allowed by policy" : "denied by policy"),
10
+ };
11
+ }
12
+ }
13
+ // Default allow if no rule matches
14
+ return { allow: true, rule: null, reason: "no matching rule — default allow" };
15
+ }
16
+ function matchesRule(rule, input) {
17
+ if (rule.pattern && rule.pattern.length > 0) {
18
+ const command = extractCommand(input);
19
+ if (command === null)
20
+ return false;
21
+ return rule.pattern.some((p) => micromatch.isMatch(command, p) || command.includes(p));
22
+ }
23
+ if (rule.path_allowlist || rule.path_denylist) {
24
+ const filePath = extractPath(input);
25
+ if (filePath === null)
26
+ return false;
27
+ if (rule.path_denylist && rule.path_denylist.length > 0) {
28
+ if (micromatch.isMatch(filePath, rule.path_denylist))
29
+ return true;
30
+ }
31
+ if (rule.path_allowlist && rule.path_allowlist.length > 0) {
32
+ return !micromatch.isMatch(filePath, rule.path_allowlist);
33
+ }
34
+ // path condition present but file didn't match denylist and no allowlist — no match
35
+ return false;
36
+ }
37
+ // No pattern/path conditions — matches any invocation of this tool
38
+ return true;
39
+ }
40
+ function extractCommand(input) {
41
+ const cmd = input.tool_input["command"];
42
+ return typeof cmd === "string" ? cmd : null;
43
+ }
44
+ function extractPath(input) {
45
+ for (const key of ["file_path", "path", "filePath"]) {
46
+ const v = input.tool_input[key];
47
+ if (typeof v === "string")
48
+ return v;
49
+ }
50
+ return null;
51
+ }
52
+ //# sourceMappingURL=engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/policy/engine.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,YAAY,CAAC;AASpC,MAAM,UAAU,QAAQ,CAAC,MAAkB,EAAE,KAAgB;IAC3D,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CACnC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,GAAG,IAAI,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,SAAS,CACpD,CAAC;IAEF,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;QAC7B,IAAI,WAAW,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC;YAC7B,OAAO;gBACL,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,IAAI;gBACJ,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,kBAAkB,CAAC;aAC/E,CAAC;QACJ,CAAC;IACH,CAAC;IAED,mCAAmC;IACnC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,kCAAkC,EAAE,CAAC;AACjF,CAAC;AAED,SAAS,WAAW,CAAC,IAAU,EAAE,KAAgB;IAC/C,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5C,MAAM,OAAO,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;QACtC,IAAI,OAAO,KAAK,IAAI;YAAE,OAAO,KAAK,CAAC;QACnC,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IACzF,CAAC;IAED,IAAI,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;QAC9C,MAAM,QAAQ,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;QACpC,IAAI,QAAQ,KAAK,IAAI;YAAE,OAAO,KAAK,CAAC;QAEpC,IAAI,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxD,IAAI,UAAU,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,aAAa,CAAC;gBAAE,OAAO,IAAI,CAAC;QACpE,CAAC;QACD,IAAI,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1D,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QAC5D,CAAC;QACD,oFAAoF;QACpF,OAAO,KAAK,CAAC;IACf,CAAC;IAED,mEAAmE;IACnE,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,cAAc,CAAC,KAAgB;IACtC,MAAM,GAAG,GAAG,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IACxC,OAAO,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;AAC9C,CAAC;AAED,SAAS,WAAW,CAAC,KAAgB;IACnC,KAAK,MAAM,GAAG,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,CAAC;QACpD,MAAM,CAAC,GAAG,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QAChC,IAAI,OAAO,CAAC,KAAK,QAAQ;YAAE,OAAO,CAAC,CAAC;IACtC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { CatpPolicy } from "./types.js";
2
+ export declare function findPolicyFile(startDir?: string): string | null;
3
+ export declare function loadPolicy(policyPath: string): CatpPolicy;
4
+ //# sourceMappingURL=loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/policy/loader.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAI7C,wBAAgB,cAAc,CAAC,QAAQ,GAAE,MAAsB,GAAG,MAAM,GAAG,IAAI,CAS9E;AAED,wBAAgB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU,CAIzD"}
@@ -0,0 +1,69 @@
1
+ import { readFileSync, existsSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { parse } from "smol-toml";
4
+ const POLICY_FILENAME = "catp-policy.toml";
5
+ export function findPolicyFile(startDir = process.cwd()) {
6
+ let dir = startDir;
7
+ while (true) {
8
+ const candidate = join(dir, POLICY_FILENAME);
9
+ if (existsSync(candidate))
10
+ return candidate;
11
+ const parent = join(dir, "..");
12
+ if (parent === dir)
13
+ return null;
14
+ dir = parent;
15
+ }
16
+ }
17
+ export function loadPolicy(policyPath) {
18
+ const raw = readFileSync(policyPath, "utf8");
19
+ const parsed = parse(raw);
20
+ return validate(parsed, policyPath);
21
+ }
22
+ function validate(raw, path) {
23
+ if (typeof raw !== "object" || raw === null) {
24
+ throw new Error(`${path}: policy must be a TOML object`);
25
+ }
26
+ const obj = raw;
27
+ if (!obj.agent || typeof obj.agent !== "object") {
28
+ throw new Error(`${path}: missing [agent] section`);
29
+ }
30
+ const agent = obj.agent;
31
+ if (typeof agent.id !== "string" || !agent.id) {
32
+ throw new Error(`${path}: agent.id must be a non-empty string`);
33
+ }
34
+ if (typeof agent.version !== "string" || !agent.version) {
35
+ throw new Error(`${path}: agent.version must be a non-empty string`);
36
+ }
37
+ if (!Array.isArray(obj.rules)) {
38
+ throw new Error(`${path}: [[rules]] must be an array`);
39
+ }
40
+ const rules = obj.rules.map((r, i) => {
41
+ if (typeof r !== "object" || r === null) {
42
+ throw new Error(`${path}: rules[${i}] must be an object`);
43
+ }
44
+ const rule = r;
45
+ if (typeof rule.tool !== "string" || !rule.tool) {
46
+ throw new Error(`${path}: rules[${i}].tool must be a non-empty string`);
47
+ }
48
+ if (typeof rule.allow !== "boolean") {
49
+ throw new Error(`${path}: rules[${i}].allow must be a boolean`);
50
+ }
51
+ return {
52
+ tool: rule.tool,
53
+ allow: rule.allow,
54
+ pattern: toStringArray(rule.pattern),
55
+ path_allowlist: toStringArray(rule.path_allowlist),
56
+ path_denylist: toStringArray(rule.path_denylist),
57
+ reason: typeof rule.reason === "string" ? rule.reason : undefined,
58
+ };
59
+ });
60
+ return { agent: { id: agent.id, version: agent.version }, rules };
61
+ }
62
+ function toStringArray(v) {
63
+ if (v === undefined || v === null)
64
+ return undefined;
65
+ if (!Array.isArray(v))
66
+ return undefined;
67
+ return v.filter((x) => typeof x === "string");
68
+ }
69
+ //# sourceMappingURL=loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/policy/loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ export interface AgentMeta {
2
+ id: string;
3
+ version: string;
4
+ }
5
+ export interface Rule {
6
+ tool: string;
7
+ allow: boolean;
8
+ pattern?: string[];
9
+ path_allowlist?: string[];
10
+ path_denylist?: string[];
11
+ reason?: string;
12
+ }
13
+ export interface CatpPolicy {
14
+ agent: AgentMeta;
15
+ rules: Rule[];
16
+ }
17
+ export interface HookInput {
18
+ session_id?: string;
19
+ tool_name: string;
20
+ tool_input: Record<string, unknown>;
21
+ }
22
+ export interface AuditEntry {
23
+ ts: string;
24
+ tool: string;
25
+ decision: "allow" | "deny";
26
+ rule_matched: string | null;
27
+ commitment: string;
28
+ input_summary: string;
29
+ }
30
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/policy/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,IAAI;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,SAAS,CAAC;IACjB,KAAK,EAAE,IAAI,EAAE,CAAC;CACf;AAED,MAAM,WAAW,SAAS;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,GAAG,MAAM,CAAC;IAC3B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;CACvB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/policy/types.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "@catp-protocol/cli",
3
+ "version": "0.1.0",
4
+ "description": "Cryptographic Agent Trust Protocol — local enforcement plugin for Claude Code with TOML policy and tamper-evident audit log",
5
+ "keywords": ["claude-code", "ai-agents", "policy", "audit", "hooks", "trust", "zk"],
6
+ "license": "MIT",
7
+ "homepage": "https://github.com/lfzkoala/catp#readme",
8
+ "bugs": "https://github.com/lfzkoala/catp/issues",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "https://github.com/lfzkoala/catp.git"
12
+ },
13
+ "type": "module",
14
+ "bin": {
15
+ "catp": "./dist/cli.js"
16
+ },
17
+ "files": ["dist"],
18
+ "engines": {
19
+ "node": ">=20"
20
+ },
21
+ "scripts": {
22
+ "build": "tsc",
23
+ "typecheck": "tsc --noEmit",
24
+ "test": "node --experimental-vm-modules node_modules/.bin/jest",
25
+ "test:coverage": "node --experimental-vm-modules node_modules/.bin/jest --coverage --ci"
26
+ },
27
+ "dependencies": {
28
+ "commander": "^12.0.0",
29
+ "micromatch": "^4.0.5",
30
+ "smol-toml": "^1.3.0"
31
+ },
32
+ "devDependencies": {
33
+ "@types/micromatch": "^4.0.6",
34
+ "@types/node": "^20.0.0",
35
+ "jest": "^29.0.0",
36
+ "ts-jest": "^29.0.0",
37
+ "typescript": "^5.4.0"
38
+ }
39
+ }