failproofai 0.0.1-beta.9 → 0.0.2-beta.1

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 (118) 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/required-server-files.json +1 -1
  5. package/.next/standalone/.next/server/app/_global-error/page/server-reference-manifest.json +1 -1
  6. package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
  7. package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  8. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  9. package/.next/standalone/.next/server/app/_global-error.rsc +7 -7
  10. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +2 -2
  11. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
  12. package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +3 -3
  13. package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +3 -3
  14. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  15. package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  16. package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  17. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  18. package/.next/standalone/.next/server/app/_not-found.html +2 -2
  19. package/.next/standalone/.next/server/app/_not-found.rsc +15 -15
  20. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +15 -15
  21. package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +4 -4
  22. package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +10 -10
  23. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
  24. package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
  25. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  26. package/.next/standalone/.next/server/app/index.html +1 -1
  27. package/.next/standalone/.next/server/app/index.rsc +15 -15
  28. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  29. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +15 -15
  30. package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +4 -4
  31. package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +10 -10
  32. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  33. package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
  34. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  35. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  36. package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +8 -8
  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]__092s1ta._.js +2 -2
  52. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__09icjsf._.js +2 -2
  53. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__09z7o2x._.js +2 -2
  54. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0su5_t~._.js → [root-of-the-server]__0a3kr67._.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 +2 -2
  58. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0yhzo9v._.js → [root-of-the-server]__0rbuarm._.js} +2 -2
  59. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0w6l33k._.js +2 -2
  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/chunks/ssr/node_modules_next_0rd0oc-._.js +1 -1
  66. package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
  67. package/.next/standalone/.next/server/pages/404.html +2 -2
  68. package/.next/standalone/.next/server/pages/500.html +1 -1
  69. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  70. package/.next/standalone/.next/server/server-reference-manifest.json +9 -9
  71. package/.next/standalone/.next/static/chunks/{124wu0bxsexm6.js → 0a08gn8709y98.js} +1 -1
  72. package/.next/standalone/.next/static/chunks/{12olt9p45z-lq.js → 0gcz-jqgqz~9m.js} +1 -1
  73. package/.next/standalone/.next/static/chunks/{0pc9pc_pilpi9.js → 0jhw8ofx.5g_e.js} +1 -1
  74. package/.next/standalone/.next/static/chunks/{0.aencsvb-yev.js → 0kob_5.phc~sk.js} +1 -1
  75. package/.next/standalone/.next/static/chunks/{0frzv~pmu0hsf.js → 0mjc3aq2wxvlt.js} +1 -1
  76. package/.next/standalone/.next/static/chunks/{0nygnut7i45jn.js → 0mr-jhx402yci.js} +1 -1
  77. package/.next/standalone/.next/static/chunks/{0qjjki0j187__.js → 0q7z97izctgrw.js} +1 -1
  78. package/.next/standalone/.next/static/chunks/{14xe0g0rgwk18.js → 0qvj8bhl661lq.js} +1 -1
  79. package/.next/standalone/AGENTS.md +80 -0
  80. package/.next/standalone/CLAUDE.md +137 -0
  81. package/.next/standalone/README.md +9 -1
  82. package/.next/standalone/bin/failproofai.mjs +12 -1
  83. package/.next/standalone/dist/cli.mjs +2891 -0
  84. package/.next/standalone/dist/index.js +80 -0
  85. package/.next/standalone/docs/architecture.md +5 -1
  86. package/.next/standalone/docs/built-in-policies.md +5 -1
  87. package/.next/standalone/docs/cli-reference.md +5 -1
  88. package/.next/standalone/docs/configuration.md +5 -1
  89. package/.next/standalone/docs/custom-hooks.md +5 -1
  90. package/.next/standalone/docs/dashboard.md +5 -1
  91. package/.next/standalone/docs/docs.json +83 -0
  92. package/.next/standalone/docs/favicon.ico +0 -0
  93. package/.next/standalone/docs/getting-started.md +8 -2
  94. package/.next/standalone/docs/introduction.md +47 -0
  95. package/.next/standalone/docs/logo/exosphere-dark.png +0 -0
  96. package/.next/standalone/docs/logo/exosphere-light.png +0 -0
  97. package/.next/standalone/docs/package-aliases.md +32 -26
  98. package/.next/standalone/docs/testing.md +5 -1
  99. package/.next/standalone/examples/policies-notification.js +77 -32
  100. package/.next/standalone/package.json +7 -5
  101. package/.next/standalone/scripts/launch.ts +1 -1
  102. package/.next/standalone/scripts/postinstall.mjs +11 -0
  103. package/.next/standalone/scripts/sync-hook-events-prompt.md +60 -0
  104. package/.next/standalone/server.js +1 -1
  105. package/.next/standalone/src/hooks/types.ts +11 -2
  106. package/README.md +9 -1
  107. package/bin/failproofai.mjs +12 -1
  108. package/dist/cli.mjs +2891 -0
  109. package/dist/index.js +80 -0
  110. package/package.json +7 -5
  111. package/scripts/launch.ts +1 -1
  112. package/scripts/postinstall.mjs +11 -0
  113. package/scripts/sync-hook-events-prompt.md +60 -0
  114. package/src/hooks/types.ts +11 -2
  115. package/.next/standalone/docs/index.md +0 -48
  116. /package/.next/standalone/.next/static/{o1smiVYETTvcMet_AU8oi → Dnk96sbMPjYOx1pdLdOH0}/_buildManifest.js +0 -0
  117. /package/.next/standalone/.next/static/{o1smiVYETTvcMet_AU8oi → Dnk96sbMPjYOx1pdLdOH0}/_clientMiddlewareManifest.js +0 -0
  118. /package/.next/standalone/.next/static/{o1smiVYETTvcMet_AU8oi → Dnk96sbMPjYOx1pdLdOH0}/_ssgManifest.js +0 -0
package/dist/index.js ADDED
@@ -0,0 +1,80 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropNames = Object.getOwnPropertyNames;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ function __accessProp(key) {
6
+ return this[key];
7
+ }
8
+ var __toCommonJS = (from) => {
9
+ var entry = (__moduleCache ??= new WeakMap).get(from), desc;
10
+ if (entry)
11
+ return entry;
12
+ entry = __defProp({}, "__esModule", { value: true });
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (var key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(entry, key))
16
+ __defProp(entry, key, {
17
+ get: __accessProp.bind(from, key),
18
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
19
+ });
20
+ }
21
+ __moduleCache.set(from, entry);
22
+ return entry;
23
+ };
24
+ var __moduleCache;
25
+ var __returnValue = (v) => v;
26
+ function __exportSetter(name, newValue) {
27
+ this[name] = __returnValue.bind(null, newValue);
28
+ }
29
+ var __export = (target, all) => {
30
+ for (var name in all)
31
+ __defProp(target, name, {
32
+ get: all[name],
33
+ enumerable: true,
34
+ configurable: true,
35
+ set: __exportSetter.bind(all, name)
36
+ });
37
+ };
38
+
39
+ // src/index.ts
40
+ var exports_src = {};
41
+ __export(exports_src, {
42
+ instruct: () => instruct,
43
+ getCustomHooks: () => getCustomHooks,
44
+ deny: () => deny,
45
+ customPolicies: () => customPolicies,
46
+ clearCustomHooks: () => clearCustomHooks,
47
+ allow: () => allow
48
+ });
49
+ module.exports = __toCommonJS(exports_src);
50
+
51
+ // src/hooks/custom-hooks-registry.ts
52
+ var REGISTRY_KEY = "__failproofai_custom_hooks__";
53
+ function getRegistry() {
54
+ const g = globalThis;
55
+ if (!Array.isArray(g[REGISTRY_KEY]))
56
+ g[REGISTRY_KEY] = [];
57
+ return g[REGISTRY_KEY];
58
+ }
59
+ var customPolicies = {
60
+ add(hook) {
61
+ getRegistry().push(hook);
62
+ }
63
+ };
64
+ function getCustomHooks() {
65
+ return getRegistry();
66
+ }
67
+ function clearCustomHooks() {
68
+ const g = globalThis;
69
+ g[REGISTRY_KEY] = [];
70
+ }
71
+ // src/hooks/policy-helpers.ts
72
+ function allow() {
73
+ return { decision: "allow" };
74
+ }
75
+ function deny(reason) {
76
+ return { decision: "deny", reason };
77
+ }
78
+ function instruct(reason) {
79
+ return { decision: "instruct", reason };
80
+ }
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "failproofai",
3
- "version": "0.0.1-beta.9",
3
+ "version": "0.0.2-beta.1",
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/",
@@ -11,6 +11,7 @@
11
11
  "scripts/",
12
12
  "lib/",
13
13
  ".next/standalone/",
14
+ "dist/",
14
15
  "README.md"
15
16
  ],
16
17
  "engines": {
@@ -18,10 +19,11 @@
18
19
  "bun": ">=1.3.0"
19
20
  },
20
21
  "scripts": {
21
- "predev": "bun link",
22
+ "predev": "bun run build:cli && bun link",
22
23
  "dev": "FAILPROOFAI_TELEMETRY_DISABLED=1 bun scripts/dev.ts --port 8020",
23
- "build": "bun --bun next build && node -e \"const {cpSync}=require('fs');cpSync('.next/static','.next/standalone/.next/static',{recursive:true});\"",
24
- "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",
25
27
  "start": "FAILPROOFAI_TELEMETRY_DISABLED=1 bun scripts/start.ts",
26
28
  "test": "vitest",
27
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,60 @@
1
+ You are an automated agent running in GitHub Actions to keep failproofai's hook
2
+ event types in sync with the official Claude Code documentation.
3
+
4
+ ## Your task
5
+
6
+ 1. Fetch the Claude Code hooks reference pages using WebFetch:
7
+ - https://code.claude.com/docs/en/hooks (full reference — has the complete event table)
8
+ - https://code.claude.com/docs/en/hooks-guide (guide — also has a summary event table)
9
+ Extract the complete list of all hook event type names (e.g. SessionStart,
10
+ PreToolUse, PostToolUse, etc.) from the event lifecycle/trigger table.
11
+ Use both pages; union the results if they differ. Prefer the reference page.
12
+
13
+ 2. Read `src/hooks/types.ts` and extract the current `HOOK_EVENT_TYPES` array
14
+ (the TypeScript `as const` array of strings).
15
+
16
+ 3. Diff the two lists:
17
+ - **added**: event types in the docs but NOT in our array
18
+ - **removed**: event types in our array but NOT in the docs
19
+
20
+ 4. If there are NO differences:
21
+ Write the following JSON to `.sync-hook-events-output.json` in the repo root:
22
+ ```json
23
+ { "changed": false }
24
+ ```
25
+ Then stop.
26
+
27
+ 5. If there are differences:
28
+
29
+ a. Update `HOOK_EVENT_TYPES` in `src/hooks/types.ts`:
30
+ - Add new event types (append after the last existing entry, before `] as const`)
31
+ - Remove stale event types if any
32
+
33
+ b. Update `__tests__/hooks/manager.test.ts` — find the hardcoded event-type
34
+ counts and update them to the new total:
35
+ - The test description string matching `all N event types`
36
+ - The `toHaveLength(N)` assertion(s) that check `Object.keys(written.hooks)`
37
+ Search by the current count number to locate them.
38
+
39
+ c. Write the following JSON to `.sync-hook-events-output.json` in the repo root:
40
+ ```json
41
+ {
42
+ "changed": true,
43
+ "added": ["EventA", "EventB"],
44
+ "removed": ["EventC"],
45
+ "prTitle": "[auto] sync hook event types with Claude Code docs",
46
+ "prBody": "..."
47
+ }
48
+ ```
49
+ The `prBody` must be a Markdown string containing:
50
+ - List of **added** event types (or "none")
51
+ - List of **removed** event types (or "none")
52
+ - Source URLs used
53
+ - A note: "CI must pass and this PR must be reviewed before merging."
54
+
55
+ ## Constraints
56
+
57
+ - **Only edit `src/hooks/types.ts`, `__tests__/hooks/manager.test.ts`, and
58
+ `.sync-hook-events-output.json`**. No other files.
59
+ - Do NOT run any shell commands (no git, no gh, no bun).
60
+ - Do NOT modify `policy-evaluator.ts`, `manager.ts`, or any other source file.
@@ -10,19 +10,28 @@ export const HOOK_EVENT_TYPES = [
10
10
  "SessionEnd",
11
11
  "UserPromptSubmit",
12
12
  "PreToolUse",
13
+ "PermissionRequest",
14
+ "PermissionDenied",
13
15
  "PostToolUse",
14
16
  "PostToolUseFailure",
15
- "PermissionRequest",
16
17
  "Notification",
17
18
  "SubagentStart",
18
19
  "SubagentStop",
20
+ "TaskCreated",
21
+ "TaskCompleted",
19
22
  "Stop",
23
+ "StopFailure",
20
24
  "TeammateIdle",
21
- "TaskCompleted",
25
+ "InstructionsLoaded",
22
26
  "ConfigChange",
27
+ "CwdChanged",
28
+ "FileChanged",
23
29
  "WorktreeCreate",
24
30
  "WorktreeRemove",
25
31
  "PreCompact",
32
+ "PostCompact",
33
+ "Elicitation",
34
+ "ElicitationResult",
26
35
  ] as const;
27
36
 
28
37
  export type HookEventType = (typeof HOOK_EVENT_TYPES)[number];
@@ -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
- ```