failproofai 1.0.2-beta.3 → 1.0.2-beta.5

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 (210) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/build-manifest.json +6 -6
  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/build-manifest.json +3 -3
  6. package/.next/standalone/.next/server/app/_global-error/page/server-reference-manifest.json +1 -1
  7. package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
  8. package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  9. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  10. package/.next/standalone/.next/server/app/_global-error.rsc +7 -7
  11. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +6 -6
  12. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
  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/build-manifest.json +3 -3
  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 +1 -1
  19. package/.next/standalone/.next/server/app/_not-found.rsc +14 -14
  20. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +14 -14
  21. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +13 -13
  22. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  23. package/.next/standalone/.next/server/app/api/audit/invite/route.js +2 -3
  24. package/.next/standalone/.next/server/app/api/audit/invite/route.js.nft.json +1 -1
  25. package/.next/standalone/.next/server/app/api/audit/run/route.js +5 -6
  26. package/.next/standalone/.next/server/app/api/audit/run/route.js.nft.json +1 -1
  27. package/.next/standalone/.next/server/app/api/audit/status/route.js.nft.json +1 -1
  28. package/.next/standalone/.next/server/app/api/auth/login-request/route.js +2 -2
  29. package/.next/standalone/.next/server/app/api/auth/login-request/route.js.nft.json +1 -1
  30. package/.next/standalone/.next/server/app/api/auth/login-verify/route.js +3 -4
  31. package/.next/standalone/.next/server/app/api/auth/login-verify/route.js.nft.json +1 -1
  32. package/.next/standalone/.next/server/app/api/auth/logout/route.js +4 -4
  33. package/.next/standalone/.next/server/app/api/auth/logout/route.js.nft.json +1 -1
  34. package/.next/standalone/.next/server/app/api/auth/status/route.js +4 -4
  35. package/.next/standalone/.next/server/app/api/auth/status/route.js.nft.json +1 -1
  36. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js +1 -1
  37. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js.nft.json +1 -1
  38. package/.next/standalone/.next/server/app/audit/page/build-manifest.json +3 -3
  39. package/.next/standalone/.next/server/app/audit/page/server-reference-manifest.json +2 -2
  40. package/.next/standalone/.next/server/app/audit/page.js.nft.json +1 -1
  41. package/.next/standalone/.next/server/app/audit/page_client-reference-manifest.js +1 -1
  42. package/.next/standalone/.next/server/app/index.html +1 -1
  43. package/.next/standalone/.next/server/app/index.rsc +14 -14
  44. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +13 -13
  45. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +14 -14
  46. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  47. package/.next/standalone/.next/server/app/page/build-manifest.json +3 -3
  48. package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
  49. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  50. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  51. package/.next/standalone/.next/server/app/policies/page/build-manifest.json +3 -3
  52. package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +14 -14
  53. package/.next/standalone/.next/server/app/policies/page.js +2 -2
  54. package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
  55. package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
  56. package/.next/standalone/.next/server/app/project/[name]/page/build-manifest.json +3 -3
  57. package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
  58. package/.next/standalone/.next/server/app/project/[name]/page.js +2 -2
  59. package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
  60. package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
  61. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/build-manifest.json +3 -3
  62. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
  63. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
  64. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js +2 -2
  65. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
  66. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
  67. package/.next/standalone/.next/server/app/projects/page/build-manifest.json +3 -3
  68. package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
  69. package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
  70. package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  71. package/.next/standalone/.next/server/app/settings/page/build-manifest.json +3 -3
  72. package/.next/standalone/.next/server/app/settings/page/server-reference-manifest.json +4 -4
  73. package/.next/standalone/.next/server/app/settings/page.js.nft.json +1 -1
  74. package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  75. package/.next/standalone/.next/server/chunks/{[externals]__0e32-7c._.js → [externals]__1qzqcio._.js} +1 -1
  76. package/.next/standalone/.next/server/chunks/[root-of-the-server]__03r-lqq._.js +3 -0
  77. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0_usx0j._.js +3 -0
  78. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0_zk340._.js +3 -0
  79. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0o07qi9._.js +1 -1
  80. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0oy4kxb._.js +3 -0
  81. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0zf034w._.js +3 -0
  82. package/.next/standalone/.next/server/chunks/[root-of-the-server]__12021ot._.js +3 -0
  83. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1le9jqc._.js +3 -0
  84. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0igxt32._.js → [root-of-the-server]__1p8poxd._.js} +2 -2
  85. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1zkek3z._.js +3 -0
  86. package/.next/standalone/.next/server/chunks/_0lxbzdq._.js +3 -0
  87. package/.next/standalone/.next/server/chunks/_12moi5-._.js +3 -0
  88. package/.next/standalone/.next/server/chunks/_1ek68ln._.js +6 -5
  89. package/.next/standalone/.next/server/chunks/_1zuiiy3._.js +3 -0
  90. package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_01r25oi._.js +2 -2
  91. package/.next/standalone/.next/server/chunks/{node_modules_posthog-node_dist_entrypoints_index_node_mjs_04op_ou._.js → node_modules_posthog-node_dist_entrypoints_index_node_mjs_09d5c79._.js} +1 -1
  92. package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_09z9-p7._.js +2 -2
  93. package/.next/standalone/.next/server/chunks/{node_modules_posthog-node_dist_entrypoints_index_node_mjs_0dr20uz._.js → node_modules_posthog-node_dist_entrypoints_index_node_mjs_1d2g73o._.js} +1 -1
  94. package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_1nxcc4v._.js +1 -1
  95. package/.next/standalone/.next/server/chunks/src_hooks_fp-home_ts_09kv0bn._.js +1 -1
  96. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__1m84s36._.js → [root-of-the-server]__00-s7h8._.js} +1 -1
  97. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__013jr2b._.js +2 -2
  98. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__01wy8d-._.js +2 -2
  99. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__02npjtd._.js +2 -2
  100. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__07gm3zl._.js +4 -4
  101. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0da85px._.js +2 -2
  102. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0ftmoxc._.js +2 -2
  103. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0oa1lav._.js +1 -1
  104. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0p-5p8u._.js +2 -2
  105. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0s740oi._.js +2 -2
  106. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__08zpry-._.js → [root-of-the-server]__0stn0gx._.js} +2 -2
  107. package/.next/standalone/.next/server/chunks/ssr/{src_hooks_08o7bqo._.js → [root-of-the-server]__15r6r7w._.js} +2 -2
  108. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0jzbk4_._.js → [root-of-the-server]__190won8._.js} +1 -1
  109. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1ctpynv._.js +1 -1
  110. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1p2otjt._.js +2 -2
  111. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0rsd3ll._.js → [root-of-the-server]__1sc84bb._.js} +2 -2
  112. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1tag8_-._.js +5 -0
  113. package/.next/standalone/.next/server/chunks/ssr/_08x1r5t._.js +1 -1
  114. package/.next/standalone/.next/server/chunks/ssr/_1ddpc5g._.js +1 -1
  115. package/.next/standalone/.next/server/chunks/ssr/{_1db3-8n._.js → _1if9ixi._.js} +2 -2
  116. package/.next/standalone/.next/server/chunks/ssr/{_11opd9e._.js → _1kesqs-._.js} +2 -2
  117. package/.next/standalone/.next/server/chunks/ssr/{_15xtekm._.js → _1km9-gn._.js} +1 -1
  118. package/.next/standalone/.next/server/chunks/ssr/_1u8-lu2._.js +1 -1
  119. package/.next/standalone/.next/server/chunks/ssr/_1zopuov._.js +1 -1
  120. package/.next/standalone/.next/server/chunks/ssr/app_audit__components_audit-dashboard_tsx_0p9ud47._.js +1 -1
  121. package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_1kp6l3x._.js +1 -1
  122. package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_19dqvpc._.js +1 -1
  123. package/.next/standalone/.next/server/chunks/ssr/app_settings_settings-client_tsx_20lq-mq._.js +1 -1
  124. package/.next/standalone/.next/server/chunks/ssr/lib_1cf5ya2._.js +3 -0
  125. package/.next/standalone/.next/server/chunks/ssr/lib_opencode-projects_ts_15bjxkm._.js +1 -1
  126. package/.next/standalone/.next/server/chunks/ssr/node_modules_13n822a._.js +1 -1
  127. package/.next/standalone/.next/server/chunks/ssr/node_modules_posthog-node_dist_entrypoints_index_node_mjs_11bnuzn._.js +2 -2
  128. package/.next/standalone/.next/server/middleware-build-manifest.js +6 -6
  129. package/.next/standalone/.next/server/middleware.js +1 -1
  130. package/.next/standalone/.next/server/pages/404.html +1 -1
  131. package/.next/standalone/.next/server/pages/500.html +1 -1
  132. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  133. package/.next/standalone/.next/server/server-reference-manifest.json +19 -19
  134. package/.next/standalone/.next/static/chunks/0tyt-3a5rtzy8.js +1 -0
  135. package/.next/standalone/.next/static/chunks/{1mk3vmmc673hu.js → 21r7iw3rmixf5.js} +1 -1
  136. package/.next/standalone/.next/static/chunks/{10pok-mrqv426.js → 26lfjhb2kzzgb.js} +1 -1
  137. package/.next/standalone/.next/static/chunks/2_27jraat038x.js +1 -0
  138. package/.next/standalone/.next/static/chunks/2hwc8e923g5df.js +1 -0
  139. package/.next/standalone/.next/static/chunks/{3cs_rf5p765v0.js → 33np9nrh1mvj9.js} +1 -1
  140. package/.next/standalone/.next/static/chunks/{1oml7c7env4-g.js → 354-n7p7labpn.js} +1 -1
  141. package/.next/standalone/.next/static/chunks/36-8i_vbkh85w.js +1 -0
  142. package/.next/standalone/.next/static/chunks/{2jsomd79g7kn0.js → 391tpdqcas7rq.js} +1 -1
  143. package/.next/standalone/.next/static/chunks/{1yywl_a87108w.js → 3_b73tc78jwsq.js} +2 -2
  144. package/.next/standalone/.next/static/chunks/{1za08zjcctyil.js → 3i8rg2fv9nd6e.js} +2 -2
  145. package/.next/standalone/.next/static/chunks/{2ey_ih6j6cm15.js → 3jqm8ubpv3i-4.js} +1 -1
  146. package/.next/standalone/.next/static/chunks/turbopack-2x-o099q64i8h.js +1 -0
  147. package/.next/standalone/SECURITY.md +18 -3
  148. package/.next/standalone/fp-cloud-cli/CHANGELOG.md +7 -0
  149. package/.next/standalone/fp-cloud-cli/uv.lock +6 -6
  150. package/.next/standalone/lib/opencode-db.ts +77 -0
  151. package/.next/standalone/lib/opencode-projects.ts +37 -41
  152. package/.next/standalone/lib/opencode-sessions.ts +59 -36
  153. package/.next/standalone/node_modules/@next/env/package.json +1 -1
  154. package/.next/standalone/node_modules/next/dist/build/swc/index.js +1 -1
  155. package/.next/standalone/node_modules/next/dist/client/components/segment-cache/cache.js +23 -34
  156. package/.next/standalone/node_modules/next/dist/compiled/next-server/app-page-turbo-experimental.runtime.prod.js +1 -1
  157. package/.next/standalone/node_modules/next/dist/compiled/next-server/app-page-turbo.runtime.prod.js +1 -1
  158. package/.next/standalone/node_modules/next/dist/compiled/next-server/pages-turbo.runtime.prod.js +1 -1
  159. package/.next/standalone/node_modules/next/dist/lib/patch-incorrect-lockfile.js +3 -3
  160. package/.next/standalone/node_modules/next/dist/server/config.js +1 -1
  161. package/.next/standalone/node_modules/next/dist/server/dev/hot-reloader-turbopack.js +2 -2
  162. package/.next/standalone/node_modules/next/dist/server/dev/hot-reloader-webpack.js +1 -1
  163. package/.next/standalone/node_modules/next/dist/server/lib/app-info-log.js +1 -1
  164. package/.next/standalone/node_modules/next/dist/server/lib/start-server.js +1 -1
  165. package/.next/standalone/node_modules/next/dist/telemetry/anonymous-meta.js +1 -1
  166. package/.next/standalone/node_modules/next/dist/telemetry/events/swc-load-failure.js +1 -1
  167. package/.next/standalone/node_modules/next/dist/telemetry/events/version.js +2 -2
  168. package/.next/standalone/node_modules/next/package.json +10 -10
  169. package/.next/standalone/package.json +19 -19
  170. package/.next/standalone/sdk/python/CHANGELOG.md +7 -0
  171. package/.next/standalone/sdk/python/uv.lock +23 -23
  172. package/.next/standalone/server.js +1 -1
  173. package/bin/failproofai.mjs +151 -60
  174. package/dist/cli.mjs +3670 -3005
  175. package/dist/worker.mjs +189 -164
  176. package/lib/opencode-db.ts +77 -0
  177. package/lib/opencode-projects.ts +37 -41
  178. package/lib/opencode-sessions.ts +59 -36
  179. package/package.json +19 -19
  180. package/src/audit/cache.ts +201 -40
  181. package/src/audit/cli-adapters/claude.ts +111 -1
  182. package/src/audit/cli-adapters/index.ts +31 -1
  183. package/src/audit/index.ts +131 -11
  184. package/src/audit/replay.ts +15 -91
  185. package/src/hooks/configure-wizard.ts +16 -48
  186. package/src/hooks/handler.ts +8 -1
  187. package/src/hooks/manager.ts +72 -3
  188. package/src/hooks/pack-cli.ts +793 -45
  189. package/src/hooks/pack-manifest.ts +28 -0
  190. package/src/hooks/pack-store.ts +8 -25
  191. package/.next/standalone/.next/server/chunks/[root-of-the-server]__01eqny5._.js +0 -3
  192. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0neqlu-._.js +0 -3
  193. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0t9oqnn._.js +0 -3
  194. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1l-khtb._.js +0 -3
  195. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1mhmdzs._.js +0 -3
  196. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1qxztj-._.js +0 -3
  197. package/.next/standalone/.next/server/chunks/_0bs-v8p._.js +0 -3
  198. package/.next/standalone/.next/server/chunks/_0tovk6q._.js +0 -3
  199. package/.next/standalone/.next/server/chunks/_0trp3yc._.js +0 -3
  200. package/.next/standalone/.next/server/chunks/_185gyk9._.js +0 -3
  201. package/.next/standalone/.next/server/chunks/src_hooks_0xbw3bu._.js +0 -12
  202. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__192nhvh._.js +0 -5
  203. package/.next/standalone/.next/static/chunks/01nuy-aqshahr.js +0 -1
  204. package/.next/standalone/.next/static/chunks/1pl7h8vllvoi2.js +0 -1
  205. package/.next/standalone/.next/static/chunks/2efnffq2ipgr_.js +0 -1
  206. package/.next/standalone/.next/static/chunks/2gd07pinz0i7f.js +0 -1
  207. package/.next/standalone/.next/static/chunks/turbopack-3kjgdgwci4tqf.js +0 -1
  208. /package/.next/standalone/.next/static/{G-faMkpZioETgewZ4X4wX → 59jsH11LoyXu9UBoHvgGM}/_buildManifest.js +0 -0
  209. /package/.next/standalone/.next/static/{G-faMkpZioETgewZ4X4wX → 59jsH11LoyXu9UBoHvgGM}/_clientMiddlewareManifest.js +0 -0
  210. /package/.next/standalone/.next/static/{G-faMkpZioETgewZ4X4wX → 59jsH11LoyXu9UBoHvgGM}/_ssgManifest.js +0 -0
@@ -369,34 +369,62 @@ see docs.befailproof.ai. Denials are reported to the agent, never to you.
369
369
  if (extraArgs.length > 0) {
370
370
  throw new CliError(`Unexpected argument: ${extraArgs[0]}\nRun \`failproofai help\` for usage.`);
371
371
  }
372
- console.log(`
373
- failproofai v${version} -v version -h this screen
374
- Usage failproofai <command> [options] Detail failproofai help <command>
375
- ━━ 1 GET IT RUNNING ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
376
- config, setup Interactive setup: agents, daemon, cloud
377
- update Finish an npm upgrade: migrate home, match daemon
378
- ━━ 2 CHOOSE WHAT IT ENFORCES ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
379
- policies Every policy on this machine, and whether it is on
380
- policies add Pick from a list, or name one: <policy> or <owner>/<repo>
381
- policies remove Turn one policy off, or uninstall a whole pack
382
- policies show What a pack contains, before you install it
383
- policies -i / -u Wire failproofai into your agent CLIs
384
- publish Ship your own policies as a pack anyone can install
385
- ━━ 3 SEE WHAT IT CAUGHT ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
386
- (no args) Open the policy dashboard on localhost:8020
387
- audit Scan your agents' history, then open the audit view
388
- config --status Cloud connection, daemon version, pause state
389
- harness Extra paths to capture agent sessions from
390
- ━━ 4 PUT IT RIGHT ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
391
- config --pause Pause enforcement for one session (30m; max 8h)
392
- flush Deliver everything already spooled, right now
393
- backfill Re-send history the collector already read past
394
- migrate Run pending ~/.failproofai layout migrations
395
- uninstall Remove hooks and daemon, BEFORE npm rm -g failproofai
396
-
397
- Docs docs.befailproof.ai Code github.com/failproofai/failproofai
398
- Chat discord.befailproof.ai Forum reddit.com/r/failproofai
399
- `.trimStart());
372
+ // Built row by row rather than as one literal, so the command column can be
373
+ // painted without the escape sequences becoming part of the layout. Colour
374
+ // is decoration here and never meaning: the column position already says
375
+ // which half is a command, so this reads identically under NO_COLOR, piped
376
+ // to a file, or on a terminal that has never heard of 24-bit.
377
+ const { brandAnsi, ANSI_RESET, ANSI_BOLD, ANSI_DIM, colorsEnabled } =
378
+ await import("../src/hooks/tui");
379
+ const tint = colorsEnabled(process.stdout);
380
+ const pink = (t) => (tint ? `${brandAnsi("pink")}${t}${ANSI_RESET}` : t);
381
+ const mint = (t) => (tint ? `${brandAnsi("guide")}${t}${ANSI_RESET}` : t);
382
+ const dim = (t) => (tint ? `${ANSI_DIM}${t}${ANSI_RESET}` : t);
383
+ const bold = (t) => (tint ? `${ANSI_BOLD}${t}${ANSI_RESET}` : t);
384
+
385
+ // Padded BEFORE painting: an escape sequence has no width, so padding a
386
+ // coloured string right-aligns nothing and the description column drifts.
387
+ const row = (cmd, desc) => ` ${pink(cmd.padEnd(18))}${desc}`;
388
+ // 78 visible columns, matching the body. Computed from the VISIBLE prefix —
389
+ // `" \u2501\u2501 "` is 5, the label is `${n} ${title}`, then one space — because the
390
+ // painted string's length counts escape bytes and would shorten every rule
391
+ // by however many the terminal happened to need.
392
+ const section = (n, title) => {
393
+ const label = `${n} ${title}`;
394
+ const fill = 78 - (5 + label.length + 1);
395
+ return dim(" \u2501\u2501 ") + bold(label) + " " + dim("\u2501".repeat(Math.max(0, fill)));
396
+ };
397
+
398
+ console.log([
399
+ `${bold("fa")}${pink("il")}${bold("proofai")} v${version}` +
400
+ `${" ".repeat(23)}${dim("-v version -h this screen")}`,
401
+ ` ${dim("Usage")} failproofai <command> [options] ${dim("Detail")} failproofai help <command>`,
402
+ section(1, "GET IT RUNNING"),
403
+ row("config, setup", "Interactive setup: agents, daemon, cloud"),
404
+ row("config --connect", "Connect to Cloud with no prompts: --token <key>"),
405
+ row("update", "Finish an npm upgrade: migrate home, match daemon"),
406
+ section(2, "CHOOSE WHAT IT ENFORCES"),
407
+ row("policies", "Every policy on this machine, and whether it is on"),
408
+ row("policies add", "Pick from a list, or name one: <policy> or <owner>/<repo>"),
409
+ row("policies remove", "Turn one policy off, or uninstall a whole pack"),
410
+ row("policies show", "What a pack contains, before you install it"),
411
+ row("publish", "Ship your own policies as a pack anyone can install"),
412
+ section(3, "SEE WHAT IT CAUGHT"),
413
+ row("(no args)", "Open the policy dashboard on localhost:8020"),
414
+ row("audit", "Scan your agents' history, then open the audit view"),
415
+ row("config --status", "Cloud connection, daemon version, pause state"),
416
+ row("harness", "Extra paths to capture agent sessions from"),
417
+ section(4, "PUT IT RIGHT"),
418
+ row("config --pause", "Pause enforcement for one session (30m; max 8h)"),
419
+ row("flush --wait", "Send everything spooled now, and block until it lands"),
420
+ row("backfill --since", "Re-send history already read past: 30d, 6m, YYYY-MM-DD"),
421
+ row("policies -i / -u", "Wire failproofai into your agent CLIs, or unwire"),
422
+ row("migrate", "Run pending ~/.failproofai layout migrations"),
423
+ row("uninstall", "Remove hooks and daemon, BEFORE npm rm -g failproofai"),
424
+ "",
425
+ ` ${dim("Docs")} ${mint("docs.befailproof.ai")} ${dim("Code")} github.com/failproofai/failproofai`,
426
+ ` ${dim("Chat")} ${mint("discord.befailproof.ai")} ${dim("Forum")} reddit.com/r/failproofai`,
427
+ ].join("\n"));
400
428
  process.exit(0);
401
429
  }
402
430
 
@@ -1192,50 +1220,113 @@ WHY THIS EXISTS
1192
1220
  // ever ship a pack. `pack build` is canonicalized into this above.
1193
1221
  if (args[0] === "publish") {
1194
1222
  const subArgs = args.slice(1);
1195
- if (subArgs.includes("--help") || subArgs.includes("-h") || subArgs.length === 0) {
1223
+ // NOT `subArgs.length === 0`. A bare `failproofai publish` is the headline
1224
+ // of the help this used to print instead — "TWO COMMANDS, FROM NOTHING:
1225
+ // --init to start, publish to ship it" — and every argument it needs is
1226
+ // worked out from the directory and the git remote. Printing help there
1227
+ // made the one documented command the only one that did nothing.
1228
+ if (subArgs.includes("--help") || subArgs.includes("-h")) {
1196
1229
  console.log(`
1197
1230
  failproofai publish — ship your policies as a pack anyone can install
1198
1231
 
1199
- USAGE
1200
- failproofai publish <entry.mjs> --repo <owner>/<repo> --version <version>
1232
+ TWO COMMANDS, FROM NOTHING
1201
1233
 
1202
- WHAT IT DOES
1203
- Validates the file with the loader's own rules, writes the three release
1204
- assets, creates (or reuses) the release, and attaches them. One command.
1234
+ failproofai publish --init write a policy to start from
1235
+ failproofai publish ship it
1205
1236
 
1206
- Only the release matters. Installs read
1207
- releases/download/<tag>/<asset> and never touch your git tree — pushing the
1208
- source is for humans reading it, not for the install to work.
1237
+ Write your policies in a git repo, run publish, answer one question, done.
1238
+ It asks WHERE only when nothing tells it — no remote to read — and works
1239
+ the rest out: which files hold policies, what version is next, who you are.
1209
1240
 
1210
- OPTIONS
1211
- --repo <owner>/<repo> Where to release it. Omit to build the assets only.
1212
- --version <version> The pack version. Also the tag, unless --tag says otherwise.
1213
- --id <publisher/name> The pack's id. Defaults to --repo.
1214
- --tag <tag> Release tag. Defaults to --version; a leading v is fine.
1215
- --notes <text> Release notes.
1216
- --out <dir> Where to write the assets (default: dist-pack)
1217
- --effect enforce|observe observe records and blocks nothing (default: enforce)
1218
- --dry-run Build the assets, publish nothing.
1241
+ Every flag below overrides something it would otherwise decide for you.
1242
+ None of them is required, and on a pipe or in CI the flags are all there
1243
+ is: nothing prompts where nobody can answer.
1244
+
1245
+ WHAT --init DOES
1246
+ Asks what the pack is called, writes <name>.mjs, and stops. No network, no
1247
+ git, nothing published.
1248
+
1249
+ The file is not a template with blanks — it is one policy that already
1250
+ blocks git push --force. So the first thing you do is edit something that
1251
+ works. Refuses rather than overwriting a file that already exists.
1252
+
1253
+ Then try it on THIS machine, before anyone else can see it:
1254
+
1255
+ failproofai policies -i -c ./<name>.mjs
1219
1256
 
1220
- CREDENTIAL
1221
- GITHUB_TOKEN or GH_TOKEN, else whatever \`gh auth login\` stored. It needs
1222
- write access to releases on that repository and nothing else. The token is
1223
- never printed.
1257
+ That enforces the file right now — any path, any filename. Ask your agent to
1258
+ do the thing you blocked and watch it get refused. Iterate here; nothing is
1259
+ published and nobody else is affected.
1260
+
1261
+ WHAT publish DOES
1262
+ In order, and it stops before touching GitHub if anything is wrong:
1263
+
1264
+ 1 Finds the policy file here, by CONTENT — one that imports failproofai
1265
+ and calls customPolicies.add — not by filename. So it finds guards.mjs
1266
+ and ignores an unrelated policies.mjs. Not recursive: publishing a
1267
+ fixture is worse than being asked. Two candidates and it lists them.
1268
+ 2 Reads the repo from git remote get-url origin, in the FILE's directory
1269
+ rather than yours — a policy in another checkout is normal.
1270
+ 3 Decides the version (see below).
1271
+ 4 Finds your credential: GITHUB_TOKEN, GH_TOKEN, or gh auth login. Needs
1272
+ release-write and nothing else. Never printed.
1273
+ 5 Creates the repository if it does not exist. Public — see below.
1274
+ 6 Builds the three assets, validating with the LOADER's own rules: the code
1275
+ that decides what may install on a stranger's machine. A pack that could
1276
+ never install fails here, where you can fix it.
1277
+ 7 Creates or reuses the release, and uploads the assets — replacing any of
1278
+ the same name, because the install URL is built from fixed names and a
1279
+ stale copy is what somebody would fetch.
1280
+
1281
+ HOW THE VERSION IS DECIDED
1282
+ --version if you pass one. Otherwise a tag on HEAD — someone who tagged
1283
+ v1.2.0 has SAID what this release is. Otherwise one past the highest version
1284
+ the repository has already published: 1.0.0, then 1.0.1, and so on.
1285
+
1286
+ Counted from the repository's own releases, not anything local, so a fresh
1287
+ clone still gets the right number and two people cannot both mint 1.0.1.
1288
+ Releases that are not semver (nightly) are ignored rather than guessed at.
1289
+
1290
+ A tag names a COMMIT, so it is refused when the file has uncommitted changes:
1291
+ those bytes are not in that commit, and two packs would claim one version. A
1292
+ counted version names no commit and has no such problem.
1224
1293
 
1225
1294
  THE REPO MUST BE PUBLIC
1226
1295
  Installs are anonymous HTTPS with no credential to offer, so a private
1227
- repository publishes to nobody. This warns you if it is.
1296
+ repository publishes to nobody. A repo created here is public for that
1297
+ reason; an existing private one still publishes, and warns.
1298
+
1299
+ Only the release matters. Installs read releases/download/<tag>/<asset> and
1300
+ never touch your git tree — pushing the source is for humans reading it.
1228
1301
 
1229
- YOUR ENTRY FILE
1230
- One file, no relative imports — only the entry is digest-pinned, so a pack
1231
- importing siblings could not honestly claim to be verified. Bundle first
1232
- (esbuild, bun build, rollup) if yours is split. Each policy may carry
1233
- \`category\` and \`defaultEnabled\` alongside the usual fields.
1302
+ YOUR POLICY FILES
1303
+ Write as many as you like — one per category reads well. Every file here
1304
+ that registers policies is found and bundled into the single artifact a
1305
+ pack has to be, because only the entry is digest-pinned and a pack
1306
+ importing siblings could not honestly claim to be verified. Bundling needs
1307
+ bun; without it, name one self-contained file.
1308
+
1309
+ Each policy may carry category and defaultEnabled alongside the usual
1310
+ fields. category is what --category selects on; defaultEnabled is what a
1311
+ bare 'policies add' switches on, and it defaults to false.
1312
+
1313
+ OPTIONS
1314
+ --init [file] Write a starter policy and stop.
1315
+ --repo <owner>/<repo> Where to release it, created if missing.
1316
+ --version <version> Skip the counting and say which version this is.
1317
+ --id <publisher/name> The pack's id. Defaults to --repo.
1318
+ --tag <tag> Release tag. Defaults to the version; v prefix ok.
1319
+ --notes <text> Release notes.
1320
+ --out <dir> Where to write the assets (default: dist-pack)
1321
+ --effect enforce|observe
1322
+ observe records and blocks nothing (default: enforce)
1323
+ --dry-run Build the assets, publish nothing. No credential.
1234
1324
 
1235
1325
  EXAMPLES
1236
- failproofai publish ./deploy-guard.mjs --repo me/deploy-guard --version 1.0.0
1237
- failproofai publish ./deploy-guard.mjs --version 1.0.1 --dry-run
1238
- failproofai publish ./x.mjs --repo me/x --version 2.0.0 --effect observe
1326
+ failproofai publish --init
1327
+ failproofai publish
1328
+ failproofai publish --dry-run
1329
+ failproofai publish ./guards.mjs --repo me/guards --version 2.0.0
1239
1330
  `.trimStart());
1240
1331
  process.exit(0);
1241
1332
  }
@@ -1280,7 +1371,7 @@ USAGE
1280
1371
  failproofai policies add Pick from what is installed here
1281
1372
  failproofai policies add <name> Turn one policy on
1282
1373
  failproofai policies add <owner>/<repo> Install someone's pack
1283
- failproofai policies add core Our pack, from this package, offline
1374
+ failproofai policies add core Our pack, fetched like any other
1284
1375
  failproofai policies remove <name> Turn one policy off
1285
1376
  failproofai policies remove <pack-id> Uninstall a pack
1286
1377
  failproofai policies show <owner>/<repo> What a pack contains, before you take it