failproofai 0.0.1 → 0.0.2-beta.2

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 (111) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/build-manifest.json +3 -3
  3. package/.next/standalone/.next/prerender-manifest.json +3 -3
  4. package/.next/standalone/.next/server/app/_global-error/page/server-reference-manifest.json +1 -1
  5. package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
  6. package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  7. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  8. package/.next/standalone/.next/server/app/_global-error.rsc +7 -7
  9. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +2 -2
  10. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
  11. package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +3 -3
  12. package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +3 -3
  13. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  14. package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  15. package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  16. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  17. package/.next/standalone/.next/server/app/_not-found.html +2 -2
  18. package/.next/standalone/.next/server/app/_not-found.rsc +15 -15
  19. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +15 -15
  20. package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +4 -4
  21. package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +10 -10
  22. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
  23. package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
  24. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  25. package/.next/standalone/.next/server/app/index.html +1 -1
  26. package/.next/standalone/.next/server/app/index.rsc +15 -15
  27. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  28. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +15 -15
  29. package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +4 -4
  30. package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +10 -10
  31. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  32. package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
  33. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  34. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  35. package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +8 -8
  36. package/.next/standalone/.next/server/app/policies/page.js +1 -1
  37. package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
  38. package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
  39. package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
  40. package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
  41. package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
  42. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
  43. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
  44. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
  45. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
  46. package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
  47. package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
  48. package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  49. package/.next/standalone/.next/server/chunks/[root-of-the-server]__02nt~6d._.js +1 -1
  50. package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_0z7w.hh._.js +1 -1
  51. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0jvf9jj._.js → [root-of-the-server]__0103jwf._.js} +2 -2
  52. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__092s1ta._.js +2 -2
  53. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__09icjsf._.js +2 -2
  54. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__09z7o2x._.js +2 -2
  55. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0g.lg8b._.js +2 -2
  56. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0h..k-e._.js +2 -2
  57. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0osi8nq._.js → [root-of-the-server]__0okos0k._.js} +3 -3
  58. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0~7bzp~._.js → [root-of-the-server]__0ovwjau._.js} +2 -2
  59. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0w6l33k._.js +4 -3
  60. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__11pa2ra._.js +2 -2
  61. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__12t-wym._.js +2 -2
  62. package/.next/standalone/.next/server/chunks/ssr/_10lm7or._.js +1 -1
  63. package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_0xerkr6._.js +1 -1
  64. package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_0q-m0y-._.js +1 -1
  65. package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
  66. package/.next/standalone/.next/server/pages/404.html +2 -2
  67. package/.next/standalone/.next/server/pages/500.html +1 -1
  68. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  69. package/.next/standalone/.next/server/server-reference-manifest.json +9 -9
  70. package/.next/standalone/.next/static/chunks/{0eh2hq9~6bf53.js → 001k0zayn2o.s.js} +1 -1
  71. package/.next/standalone/.next/static/chunks/{056c865hodfe7.js → 0jrzwsyo7wo26.js} +1 -1
  72. package/.next/standalone/.next/static/chunks/{0wmsi.tszy~9y.js → 0pdd7~yp8ytu6.js} +1 -1
  73. package/.next/standalone/.next/static/chunks/{15lp0u9f5fwae.js → 0sm1iqi3m~xiz.js} +1 -1
  74. package/.next/standalone/.next/static/chunks/{0o04-obbhh9.s.js → 0tbr0o7vwc~-s.js} +1 -1
  75. package/.next/standalone/.next/static/chunks/{0nwr.y4dwla00.js → 0tl2f-3yc.rqc.js} +1 -1
  76. package/.next/standalone/.next/static/chunks/{066e8ajzl234v.js → 0uftmw5od9kdz.js} +1 -1
  77. package/.next/standalone/.next/static/chunks/{17q_c2.bbcoh1.js → 0wtcha31~i7rm.js} +1 -1
  78. package/.next/standalone/README.md +18 -10
  79. package/.next/standalone/bin/failproofai.mjs +221 -128
  80. package/.next/standalone/dist/cli.mjs +3005 -0
  81. package/.next/standalone/docs/architecture.md +5 -1
  82. package/.next/standalone/docs/built-in-policies.md +5 -1
  83. package/.next/standalone/docs/cli-reference.md +5 -1
  84. package/.next/standalone/docs/configuration.md +5 -1
  85. package/.next/standalone/docs/custom-hooks.md +5 -1
  86. package/.next/standalone/docs/dashboard.md +5 -1
  87. package/.next/standalone/docs/docs.json +83 -0
  88. package/.next/standalone/docs/favicon.ico +0 -0
  89. package/.next/standalone/docs/getting-started.md +8 -2
  90. package/.next/standalone/docs/introduction.md +47 -0
  91. package/.next/standalone/docs/logo/exosphere-dark.png +0 -0
  92. package/.next/standalone/docs/logo/exosphere-light.png +0 -0
  93. package/.next/standalone/docs/package-aliases.md +7 -1
  94. package/.next/standalone/docs/testing.md +5 -1
  95. package/.next/standalone/package.json +6 -5
  96. package/.next/standalone/scripts/launch.ts +1 -1
  97. package/.next/standalone/scripts/postinstall.mjs +11 -0
  98. package/.next/standalone/src/cli-error.ts +18 -0
  99. package/.next/standalone/src/hooks/manager.ts +17 -3
  100. package/README.md +18 -10
  101. package/bin/failproofai.mjs +221 -128
  102. package/dist/cli.mjs +3005 -0
  103. package/package.json +6 -5
  104. package/scripts/launch.ts +1 -1
  105. package/scripts/postinstall.mjs +11 -0
  106. package/src/cli-error.ts +18 -0
  107. package/src/hooks/manager.ts +17 -3
  108. package/.next/standalone/docs/index.md +0 -48
  109. /package/.next/standalone/.next/static/{odPaRK23IkTvoPxqrn_8P → JksWDLwDoPy6bcczVWlff}/_buildManifest.js +0 -0
  110. /package/.next/standalone/.next/static/{odPaRK23IkTvoPxqrn_8P → JksWDLwDoPy6bcczVWlff}/_clientMiddlewareManifest.js +0 -0
  111. /package/.next/standalone/.next/static/{odPaRK23IkTvoPxqrn_8P → JksWDLwDoPy6bcczVWlff}/_ssgManifest.js +0 -0
@@ -1,4 +1,8 @@
1
- # Architecture
1
+ ---
2
+ title: Architecture
3
+ description: "How the hook handler, config loading, and policy evaluation work internally"
4
+ icon: sitemap
5
+ ---
2
6
 
3
7
  This document explains how failproofai works internally: how the hook system processes events, how configuration is loaded and merged, how policies are evaluated, and how the dashboard fits in.
4
8
 
@@ -1,4 +1,8 @@
1
- # Built-in Policies
1
+ ---
2
+ title: Built-in Policies
3
+ description: "All 35+ security policies with descriptions and parameters"
4
+ icon: shield
5
+ ---
2
6
 
3
7
  failproofai ships with 35+ built-in security policies. Each policy fires on a specific hook event type and tool name. Eight policies accept parameters that let you tune their behavior without writing code.
4
8
 
@@ -1,4 +1,8 @@
1
- # CLI Reference
1
+ ---
2
+ title: CLI Reference
3
+ description: "All commands, flags, and environment variables for the failproofai CLI"
4
+ icon: terminal
5
+ ---
2
6
 
3
7
  All commands are invoked via the `failproofai` binary.
4
8
 
@@ -1,4 +1,8 @@
1
- # Configuration
1
+ ---
2
+ title: Configuration
3
+ description: "Config file format, three-scope system, and merge rules"
4
+ icon: gear
5
+ ---
2
6
 
3
7
  failproofai uses JSON configuration files to control which policies are active, how they behave, and where custom hooks are loaded from.
4
8
 
@@ -1,4 +1,8 @@
1
- # Custom Hooks
1
+ ---
2
+ title: Custom Hooks
3
+ description: "Write your own policies in JavaScript with allow, deny, and instruct decisions"
4
+ icon: code
5
+ ---
2
6
 
3
7
  Custom hooks let you write your own policies in JavaScript. They integrate with the same hook event system as built-in policies and support the same `allow`, `deny`, and `instruct` decisions.
4
8
 
@@ -1,4 +1,8 @@
1
- # Dashboard
1
+ ---
2
+ title: Dashboard
3
+ description: "Session viewer, policy management, and activity log"
4
+ icon: chart-line
5
+ ---
2
6
 
3
7
  The failproofai dashboard is a local web application for browsing Claude Code sessions and managing security policies.
4
8
 
@@ -0,0 +1,83 @@
1
+ {
2
+ "$schema": "https://mintlify.com/docs.json",
3
+ "theme": "luma",
4
+ "name": "FailproofAI",
5
+ "colors": {
6
+ "primary": "#002CA7",
7
+ "light": "#e4587d",
8
+ "dark": "#002CA7"
9
+ },
10
+ "favicon": "/favicon.ico",
11
+ "navigation": {
12
+ "tabs": [
13
+ {
14
+ "tab": "Docs",
15
+ "groups": [
16
+ {
17
+ "group": "Getting Started",
18
+ "pages": [
19
+ "introduction",
20
+ "getting-started"
21
+ ]
22
+ },
23
+ {
24
+ "group": "Core Concepts",
25
+ "pages": [
26
+ "configuration",
27
+ "built-in-policies",
28
+ "custom-hooks"
29
+ ]
30
+ },
31
+ {
32
+ "group": "Tools",
33
+ "pages": [
34
+ "cli-reference",
35
+ "dashboard"
36
+ ]
37
+ },
38
+ {
39
+ "group": "Advanced",
40
+ "pages": [
41
+ "architecture",
42
+ "testing",
43
+ "package-aliases"
44
+ ]
45
+ }
46
+ ]
47
+ }
48
+ ],
49
+ "global": {
50
+ "anchors": [
51
+ {
52
+ "anchor": "GitHub",
53
+ "href": "https://github.com/exospherehost/failproofai",
54
+ "icon": "github"
55
+ },
56
+ {
57
+ "anchor": "npm",
58
+ "href": "https://www.npmjs.com/package/failproofai",
59
+ "icon": "npm"
60
+ },
61
+ {
62
+ "anchor": "Discord",
63
+ "href": "https://discord.com/invite/zT92CAgvkj",
64
+ "icon": "discord"
65
+ }
66
+ ]
67
+ }
68
+ },
69
+ "navbar": {
70
+ "links": [],
71
+ "primary": {
72
+ "type": "button",
73
+ "label": "Get started",
74
+ "href": "/getting-started"
75
+ }
76
+ },
77
+ "footer": {
78
+ "socials": {
79
+ "github": "https://github.com/exospherehost/failproofai",
80
+ "x": "https://x.com/exospherehost"
81
+ }
82
+ }
83
+ }
@@ -1,9 +1,13 @@
1
- # Getting Started
1
+ ---
2
+ title: Getting Started
3
+ description: "Install failproofai, enable policies, and take it for a spin"
4
+ icon: rocket
5
+ ---
2
6
 
3
7
  ## Requirements
4
8
 
5
9
  - **Node.js** >= 20.9.0
6
- - **Bun** >= 1.3.0 (used as the runtime and bundler)
10
+ - **Bun** >= 1.3.0 (optional only needed for development / building from source)
7
11
 
8
12
  ---
9
13
 
@@ -11,6 +15,8 @@
11
15
 
12
16
  ```bash
13
17
  npm install -g failproofai
18
+ # or
19
+ bun add -g failproofai
14
20
  ```
15
21
 
16
22
  ---
@@ -0,0 +1,47 @@
1
+ ---
2
+ title: Introduction
3
+ description: "Open-source hooks, policies, and session visualization for Claude Code and the Agents SDK"
4
+ ---
5
+
6
+ # Failproof AI
7
+
8
+ Open-source hooks, policies, and session visualization for **Claude Code** and the **Agents SDK**. Runs entirely locally — no data leaves your machine.
9
+
10
+ ## What is Failproof AI?
11
+
12
+ Failproof AI is a security and observability toolkit that intercepts Claude Code tool calls in real time. It evaluates configurable policies — blocking dangerous commands, redacting secrets, and adding safety instructions — before Claude can act.
13
+
14
+ It also includes a local web dashboard for browsing Claude Code sessions, inspecting tool calls, and managing policies visually.
15
+
16
+ ## Key features
17
+
18
+ | Feature | Description |
19
+ |---------|-------------|
20
+ | [35+ Built-in Policies](./built-in-policies.md) | Block sudo, rm -rf, force-push, secret leaks, and more — out of the box. |
21
+ | [Custom Hooks](./custom-hooks.md) | Write your own policies in JavaScript with a simple allow/deny/instruct API. |
22
+ | [Session Dashboard](./dashboard.md) | Browse projects, inspect sessions, and review every tool call and policy decision. |
23
+ | [Three-Scope Config](./configuration.md) | Global, project, and local configuration with automatic merging. |
24
+
25
+ ## Quick start
26
+
27
+ Install globally:
28
+
29
+ ```bash
30
+ npm install -g failproofai
31
+ # or
32
+ bun add -g failproofai
33
+ ```
34
+
35
+ Enable policies:
36
+
37
+ ```bash
38
+ failproofai --install-policies
39
+ ```
40
+
41
+ Launch the dashboard:
42
+
43
+ ```bash
44
+ failproofai
45
+ ```
46
+
47
+ See the [Getting Started](./getting-started.md) guide for a full walkthrough.
@@ -1,4 +1,8 @@
1
- # Package Aliases & Typosquatting Protection
1
+ ---
2
+ title: Package Aliases
3
+ description: "Registered typosquat-prevention aliases and how they work"
4
+ icon: copy
5
+ ---
2
6
 
3
7
  ## Official package
4
8
 
@@ -6,6 +10,8 @@ The canonical npm package is **`failproofai`**:
6
10
 
7
11
  ```bash
8
12
  npm install -g failproofai
13
+ # or
14
+ bun add -g failproofai
9
15
  ```
10
16
 
11
17
  ---
@@ -1,4 +1,8 @@
1
- # Testing
1
+ ---
2
+ title: Testing
3
+ description: "Unit tests, E2E tests, and test helpers"
4
+ icon: flask-vial
5
+ ---
2
6
 
3
7
  failproofai has two test suites: **unit tests** (fast, mocked) and **end-to-end tests** (real subprocess invocations).
4
8
 
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "failproofai",
3
- "version": "0.0.1",
3
+ "version": "0.0.2-beta.2",
4
4
  "description": "Open-source hooks, policies, and project visualization for Claude Code & Agents SDK",
5
5
  "bin": {
6
- "failproofai": "./bin/failproofai.mjs"
6
+ "failproofai": "./dist/cli.mjs"
7
7
  },
8
8
  "files": [
9
9
  "bin/",
@@ -19,10 +19,11 @@
19
19
  "bun": ">=1.3.0"
20
20
  },
21
21
  "scripts": {
22
- "predev": "bun link",
22
+ "predev": "bun run build:cli && bun link",
23
23
  "dev": "FAILPROOFAI_TELEMETRY_DISABLED=1 bun scripts/dev.ts --port 8020",
24
- "build": "bun build --target=node --format=cjs --outfile=dist/index.js src/index.ts && bun --bun next build && node -e \"const {cpSync}=require('fs');cpSync('.next/static','.next/standalone/.next/static',{recursive:true});\"",
25
- "prestart": "bun link",
24
+ "build:cli": "bun build --target=node --format=esm --outfile=dist/cli.mjs bin/failproofai.mjs --external posthog-node && node -e \"const fs=require('fs');const c=fs.readFileSync('dist/cli.mjs','utf8');fs.writeFileSync('dist/cli.mjs',c.replace('#!/usr/bin/env bun','#!/usr/bin/env node').replace('// @bun\\n',''))\"",
25
+ "build": "bun build --target=node --format=cjs --outfile=dist/index.js src/index.ts && bun run build:cli && bun --bun next build && node -e \"const {cpSync}=require('fs');cpSync('.next/static','.next/standalone/.next/static',{recursive:true});\"",
26
+ "prestart": "bun run build:cli && bun link",
26
27
  "start": "FAILPROOFAI_TELEMETRY_DISABLED=1 bun scripts/start.ts",
27
28
  "test": "vitest",
28
29
  "test:run": "vitest run",
@@ -49,7 +49,7 @@ export function launch(mode: "dev" | "start"): void {
49
49
  const serverJsPath = resolve(packageRoot, ".next/standalone/server.js");
50
50
  if (!existsSync(serverJsPath)) {
51
51
  console.error(
52
- `\nError: Cannot find server binary at:\n ${serverJsPath}\n\n` +
52
+ `\nError: Cannot find server.js at:\n ${serverJsPath}\n\n` +
53
53
  `The package may be missing its build output.\n` +
54
54
  `Try reinstalling:\n npm install -g failproofai@latest\n`
55
55
  );
@@ -18,6 +18,17 @@ import { trackInstallEvent } from "./install-telemetry.mjs";
18
18
  // from process.cwd() only when we are being installed as a dependency by someone else.
19
19
  if (!process.env.INIT_CWD || process.env.INIT_CWD === process.cwd()) process.exit(0);
20
20
 
21
+ // Verify server.js exists — fail the install early if the dashboard build is missing.
22
+ const serverJsPath = resolve(process.cwd(), ".next", "standalone", "server.js");
23
+ if (!existsSync(serverJsPath)) {
24
+ console.error(
25
+ `\n[failproofai] Error: server.js not found at:\n ${serverJsPath}\n\n` +
26
+ ` The package may not have been built correctly.\n` +
27
+ ` Try reinstalling: npm install -g failproofai@latest\n`
28
+ );
29
+ process.exit(1);
30
+ }
31
+
21
32
  const FAILPROOFAI_HOOK_MARKER = "__failproofai_hook__";
22
33
  const NAMESPACE = "failproofai-telemetry-v1";
23
34
 
@@ -0,0 +1,18 @@
1
+ /**
2
+ * CliError — structured error for the failproofai CLI.
3
+ *
4
+ * Throw this for any error that should be reported to the user as a clean
5
+ * message (no stack trace). The exit code communicates the failure class:
6
+ *
7
+ * 1 — user error (bad args, unknown policy name, invalid flag)
8
+ * 2 — internal (file I/O failure, unexpected state)
9
+ */
10
+ export class CliError extends Error {
11
+ readonly exitCode: 1 | 2;
12
+
13
+ constructor(message: string, exitCode: 1 | 2 = 1) {
14
+ super(message);
15
+ this.name = "CliError";
16
+ this.exitCode = exitCode;
17
+ }
18
+ }
@@ -21,6 +21,7 @@ import { BUILTIN_POLICIES } from "./builtin-policies";
21
21
  import { loadCustomHooks } from "./custom-hooks-loader";
22
22
  import { trackHookEvent } from "./hook-telemetry";
23
23
  import { getInstanceId, hashToId } from "../../lib/telemetry-id";
24
+ import { CliError } from "../cli-error";
24
25
 
25
26
  const VALID_POLICY_NAMES = new Set(BUILTIN_POLICIES.map((p) => p.name));
26
27
 
@@ -67,7 +68,7 @@ function resolveFailproofaiBinary(): string {
67
68
  // `where` on Windows may return multiple lines; take the first
68
69
  return result.split("\n")[0].trim();
69
70
  } catch {
70
- throw new Error(
71
+ throw new CliError(
71
72
  "failproofai binary not found in PATH.\n" +
72
73
  "Install it globally first: npm install -g failproofai"
73
74
  );
@@ -85,7 +86,7 @@ function validatePolicyNames(names: string[]): void {
85
86
  const invalid = names.filter((n) => !VALID_POLICY_NAMES.has(n));
86
87
  if (invalid.length > 0) {
87
88
  const validList = [...VALID_POLICY_NAMES].join(", ");
88
- throw new Error(
89
+ throw new CliError(
89
90
  `Unknown policy name(s): ${invalid.join(", ")}\n` +
90
91
  `Valid policies: ${validList}`
91
92
  );
@@ -185,6 +186,20 @@ export async function installHooks(
185
186
  customPoliciesPath?: string,
186
187
  removeCustomHooks = false,
187
188
  ): Promise<void> {
189
+ // Validate user input first before any system checks
190
+ if (policyNames !== undefined && policyNames.length > 0) {
191
+ const nonAllNames = policyNames.filter((n) => n !== "all");
192
+ // Check unknown names first (most actionable error for the user)
193
+ if (nonAllNames.length > 0) validatePolicyNames(nonAllNames);
194
+ // Then check if "all" is mixed with valid specific names
195
+ if (policyNames.includes("all") && nonAllNames.length > 0) {
196
+ throw new CliError(
197
+ `"all" cannot be combined with specific policy names.\n` +
198
+ `Use either: --install all or --install block-sudo sanitize-jwt ...`
199
+ );
200
+ }
201
+ }
202
+
188
203
  const binaryPath = resolveFailproofaiBinary();
189
204
 
190
205
  // Capture existing config before overwriting (used for telemetry diff)
@@ -201,7 +216,6 @@ export async function installHooks(
201
216
  .filter((p) => includeBeta || !p.beta)
202
217
  .map((p) => p.name);
203
218
  } else {
204
- if (policyNames.length > 0) validatePolicyNames(policyNames);
205
219
  incoming = policyNames;
206
220
  }
207
221
  // Additive: union with whatever was already enabled, deduplicated.
package/README.md CHANGED
@@ -9,6 +9,12 @@
9
9
 
10
10
  # Failproof AI
11
11
 
12
+ [![Docs](https://img.shields.io/badge/docs-befailproof.ai-002CA7?style=flat-square)](https://befailproof.ai)
13
+ [![npm](https://img.shields.io/npm/v/failproofai?style=flat-square&color=CB3837)](https://www.npmjs.com/package/failproofai)
14
+ [![License](https://img.shields.io/badge/license-MIT%20%2B%20Commons%20Clause-blue?style=flat-square)](LICENSE)
15
+ [![CI](https://img.shields.io/github/actions/workflow/status/exospherehost/failproofai/ci.yml?branch=main&style=flat-square&label=CI)](https://github.com/exospherehost/failproofai/actions)
16
+ [![Discord](https://img.shields.io/discord/1234567890?style=flat-square&label=Discord&color=5865F2)](https://discord.com/invite/zT92CAgvkj)
17
+
12
18
  Open-source hooks, policies, and project visualization for **Claude Code** & the **Agents SDK**.
13
19
 
14
20
  - **Hooks & Policies** — 35+ built-in security policies that run as Claude Code hooks. Block dangerous commands, sanitize secrets, restrict file access, and more.
@@ -23,7 +29,7 @@ Everything runs locally — no data leaves your machine.
23
29
  ## Requirements
24
30
 
25
31
  - Node.js >= 20.9.0
26
- - Bun >= 1.3.0
32
+ - Bun >= 1.3.0 (optional — only needed for development / building from source)
27
33
 
28
34
  ---
29
35
 
@@ -31,6 +37,8 @@ Everything runs locally — no data leaves your machine.
31
37
 
32
38
  ```bash
33
39
  npm install -g failproofai
40
+ # or
41
+ bun add -g failproofai
34
42
  ```
35
43
 
36
44
  ---
@@ -40,7 +48,7 @@ npm install -g failproofai
40
48
  ### 1. Enable policies globally
41
49
 
42
50
  ```bash
43
- failproofai --install-policies
51
+ failproofai policies --install
44
52
  ```
45
53
 
46
54
  Writes hook entries into `~/.claude/settings.json`. Claude Code will now invoke failproofai before and after each tool call.
@@ -56,7 +64,7 @@ Opens `http://localhost:8020` — browse sessions, inspect logs, manage policies
56
64
  ### 3. Check what's active
57
65
 
58
66
  ```bash
59
- failproofai --list-policies
67
+ failproofai policies
60
68
  ```
61
69
 
62
70
  ---
@@ -67,22 +75,22 @@ failproofai --list-policies
67
75
 
68
76
  | Scope | Command | Where it writes |
69
77
  |-------|---------|-----------------|
70
- | Global (default) | `failproofai --install-policies` | `~/.claude/settings.json` |
71
- | Project | `failproofai --install-policies --scope project` | `.claude/settings.json` |
72
- | Local | `failproofai --install-policies --scope local` | `.claude/settings.local.json` |
78
+ | Global (default) | `failproofai policies --install` | `~/.claude/settings.json` |
79
+ | Project | `failproofai policies --install --scope project` | `.claude/settings.json` |
80
+ | Local | `failproofai policies --install --scope local` | `.claude/settings.local.json` |
73
81
 
74
82
  ### Install specific policies
75
83
 
76
84
  ```bash
77
- failproofai --install-policies block-sudo block-rm-rf sanitize-api-keys
85
+ failproofai policies --install block-sudo block-rm-rf sanitize-api-keys
78
86
  ```
79
87
 
80
88
  ### Remove policies
81
89
 
82
90
  ```bash
83
- failproofai --remove-policies
91
+ failproofai policies --uninstall
84
92
  # or for a specific scope:
85
- failproofai --remove-policies --scope project
93
+ failproofai policies --uninstall --scope project
86
94
  ```
87
95
 
88
96
  ---
@@ -182,7 +190,7 @@ customPolicies.add({
182
190
  Install with:
183
191
 
184
192
  ```bash
185
- failproofai --install-policies --custom ./my-policies.js
193
+ failproofai policies --install --custom ./my-policies.js
186
194
  ```
187
195
 
188
196
  ### Decision helpers