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
package/package.json CHANGED
@@ -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",
package/scripts/launch.ts CHANGED
@@ -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.
@@ -1,48 +0,0 @@
1
- # Failproof AI — Documentation
2
-
3
- Open-source hooks, policies, and session visualization for **Claude Code** and the **Agents SDK**. Runs entirely locally — no data leaves your machine.
4
-
5
- ---
6
-
7
- ## Documentation
8
-
9
- | Guide | Description |
10
- |-------|-------------|
11
- | [Getting Started](./getting-started.md) | Install failproofai, enable policies, and take it for a spin |
12
- | [CLI Reference](./cli-reference.md) | All commands, flags, and environment variables |
13
- | [Configuration](./configuration.md) | Config file format, three-scope system, and merge rules |
14
- | [Built-in Policies](./built-in-policies.md) | All 35+ policies with descriptions and parameters |
15
- | [Custom Hooks](./custom-hooks.md) | Write your own policies in JavaScript |
16
- | [Dashboard](./dashboard.md) | Session viewer, policy management, and activity log |
17
- | [Architecture](./architecture.md) | How the hook handler, config loading, and policy evaluation work |
18
- | [Testing](./testing.md) | Unit tests, E2E tests, and test helpers |
19
- | [Package Aliases](./package-aliases.md) | Registered typosquat-prevention aliases and how they work |
20
-
21
- ---
22
-
23
- ## Quick reference
24
-
25
- **Install:**
26
- ```bash
27
- npm install -g failproofai
28
- ```
29
-
30
- **Enable policies globally:**
31
- ```bash
32
- failproofai --install-policies
33
- ```
34
-
35
- **Launch dashboard:**
36
- ```bash
37
- failproofai
38
- ```
39
-
40
- **List active policies:**
41
- ```bash
42
- failproofai --list-policies
43
- ```
44
-
45
- **Add a custom policy file:**
46
- ```bash
47
- failproofai --install-policies --custom ./my-policies.js
48
- ```