failproofai 1.0.0-beta.2 → 1.0.0-beta.21

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 (381) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/app-path-routes-manifest.json +2 -1
  3. package/.next/standalone/.next/build-manifest.json +6 -6
  4. package/.next/standalone/.next/prerender-manifest.json +3 -3
  5. package/.next/standalone/.next/required-server-files.json +1 -1
  6. package/.next/standalone/.next/routes-manifest.json +6 -0
  7. package/.next/standalone/.next/server/app/_global-error/page/build-manifest.json +3 -3
  8. package/.next/standalone/.next/server/app/_global-error/page/server-reference-manifest.json +1 -1
  9. package/.next/standalone/.next/server/app/_global-error/page.js +3 -1
  10. package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
  11. package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  12. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  13. package/.next/standalone/.next/server/app/_global-error.rsc +7 -7
  14. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +2 -2
  15. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
  16. package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +3 -3
  17. package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +3 -3
  18. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  19. package/.next/standalone/.next/server/app/_not-found/page/build-manifest.json +3 -3
  20. package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  21. package/.next/standalone/.next/server/app/_not-found/page.js +3 -1
  22. package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  23. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  24. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  25. package/.next/standalone/.next/server/app/_not-found.rsc +15 -15
  26. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +15 -15
  27. package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +4 -4
  28. package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +10 -10
  29. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
  30. package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
  31. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  32. package/.next/standalone/.next/server/app/api/audit/invite/route.js +3 -2
  33. package/.next/standalone/.next/server/app/api/audit/invite/route.js.nft.json +1 -1
  34. package/.next/standalone/.next/server/app/api/audit/run/route.js +4 -3
  35. package/.next/standalone/.next/server/app/api/audit/run/route.js.nft.json +1 -1
  36. package/.next/standalone/.next/server/app/api/audit/status/route.js +1 -1
  37. package/.next/standalone/.next/server/app/api/audit/status/route.js.nft.json +1 -1
  38. package/.next/standalone/.next/server/app/api/auth/login-request/route.js +3 -1
  39. package/.next/standalone/.next/server/app/api/auth/login-request/route.js.nft.json +1 -1
  40. package/.next/standalone/.next/server/app/api/auth/login-verify/route.js +3 -2
  41. package/.next/standalone/.next/server/app/api/auth/login-verify/route.js.nft.json +1 -1
  42. package/.next/standalone/.next/server/app/api/auth/logout/route.js +3 -2
  43. package/.next/standalone/.next/server/app/api/auth/logout/route.js.nft.json +1 -1
  44. package/.next/standalone/.next/server/app/api/auth/reminder/route.js +3 -2
  45. package/.next/standalone/.next/server/app/api/auth/reminder/route.js.nft.json +1 -1
  46. package/.next/standalone/.next/server/app/api/auth/status/route.js +3 -2
  47. package/.next/standalone/.next/server/app/api/auth/status/route.js.nft.json +1 -1
  48. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js +1 -1
  49. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js.nft.json +1 -1
  50. package/.next/standalone/.next/server/app/audit/page/build-manifest.json +3 -3
  51. package/.next/standalone/.next/server/app/audit/page/server-reference-manifest.json +2 -2
  52. package/.next/standalone/.next/server/app/audit/page.js +5 -3
  53. package/.next/standalone/.next/server/app/audit/page.js.nft.json +1 -1
  54. package/.next/standalone/.next/server/app/audit/page_client-reference-manifest.js +1 -1
  55. package/.next/standalone/.next/server/app/index.html +1 -1
  56. package/.next/standalone/.next/server/app/index.rsc +15 -15
  57. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  58. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +15 -15
  59. package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +4 -4
  60. package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +10 -10
  61. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  62. package/.next/standalone/.next/server/app/page/build-manifest.json +3 -3
  63. package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
  64. package/.next/standalone/.next/server/app/page.js +3 -1
  65. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  66. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  67. package/.next/standalone/.next/server/app/policies/page/build-manifest.json +3 -3
  68. package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +30 -18
  69. package/.next/standalone/.next/server/app/policies/page.js +5 -3
  70. package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
  71. package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
  72. package/.next/standalone/.next/server/app/project/[name]/page/build-manifest.json +3 -3
  73. package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
  74. package/.next/standalone/.next/server/app/project/[name]/page.js +4 -2
  75. package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
  76. package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
  77. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/build-manifest.json +3 -3
  78. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
  79. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
  80. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js +6 -4
  81. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
  82. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
  83. package/.next/standalone/.next/server/app/projects/page/build-manifest.json +3 -3
  84. package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
  85. package/.next/standalone/.next/server/app/projects/page.js +4 -2
  86. package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
  87. package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  88. package/.next/standalone/.next/server/app/settings/page/app-paths-manifest.json +3 -0
  89. package/.next/standalone/.next/server/app/settings/page/build-manifest.json +18 -0
  90. package/.next/standalone/.next/server/app/settings/page/next-font-manifest.json +6 -0
  91. package/.next/standalone/.next/server/app/settings/page/react-loadable-manifest.json +1 -0
  92. package/.next/standalone/.next/server/app/settings/page/server-reference-manifest.json +53 -0
  93. package/.next/standalone/.next/server/app/settings/page.js +18 -0
  94. package/.next/standalone/.next/server/app/settings/page.js.map +5 -0
  95. package/.next/standalone/.next/server/app/settings/page.js.nft.json +1 -0
  96. package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +3 -0
  97. package/.next/standalone/.next/server/app-paths-manifest.json +2 -1
  98. package/.next/standalone/.next/server/chunks/[externals]__0h9_83k._.js +3 -0
  99. package/.next/standalone/.next/server/chunks/{[externals]__1nl3dvw._.js → [externals]__0r-zamh._.js} +2 -2
  100. package/.next/standalone/.next/server/chunks/[externals]__1ifpkx-._.js +3 -0
  101. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0l4vuqm._.js → [root-of-the-server]__00ni9za._.js} +2 -2
  102. package/.next/standalone/.next/server/chunks/[root-of-the-server]__06hexd0._.js +3 -0
  103. package/.next/standalone/.next/server/chunks/[root-of-the-server]__08y94xv._.js +3 -0
  104. package/.next/standalone/.next/server/chunks/[root-of-the-server]__094p1f1._.js +3 -0
  105. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0_0xu5z._.js +1 -1
  106. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0ed01_d._.js +3 -0
  107. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0-dh5jy._.js → [root-of-the-server]__0effm9m._.js} +2 -2
  108. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0g0vcwt._.js +3 -0
  109. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__18d-9oi._.js → [root-of-the-server]__0ix8gm7._.js} +2 -2
  110. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0h3lfmp._.js → [root-of-the-server]__0ji11a-._.js} +2 -2
  111. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__10oa-v9._.js → [root-of-the-server]__0ojwjxl._.js} +2 -2
  112. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__16le-kd._.js → [root-of-the-server]__0pbp9fe._.js} +2 -2
  113. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0q-v9z2._.js +1 -1
  114. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0vb5fl2._.js +3 -0
  115. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0sb_5m8._.js → [root-of-the-server]__131ebum._.js} +4 -4
  116. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1ibjy5x._.js +3 -0
  117. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1tvn4wf._.js +1 -1
  118. package/.next/standalone/.next/server/chunks/[root-of-the-server]__20d06rh._.js +3 -0
  119. package/.next/standalone/.next/server/chunks/_0lxbzdq._.js +3 -0
  120. package/.next/standalone/.next/server/chunks/_1zuiiy3._.js +3 -0
  121. package/.next/standalone/.next/server/chunks/lib_telemetry_ts_0dctyyw._.js +3 -0
  122. package/.next/standalone/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_17k9e3w.js +5 -5
  123. package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_01r25oi._.js +2 -1
  124. package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_09z9-p7._.js +2 -1
  125. package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_1nxcc4v._.js +1 -1
  126. package/.next/standalone/.next/server/chunks/ssr/[externals]__1aq139v._.js +3 -0
  127. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0-wfhrp._.js +3 -0
  128. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__06bp_fg._.js +5 -0
  129. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__074qmkp._.js +3 -0
  130. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__1apb7k_._.js → [root-of-the-server]__0_1tiya._.js} +2 -2
  131. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__170799-._.js → [root-of-the-server]__0spkm68._.js} +11 -11
  132. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0t281d4._.js +3 -0
  133. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__17itmx-._.js +5 -0
  134. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__01od0m6._.js → [root-of-the-server]__1n2vcv4._.js} +2 -2
  135. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1qapotl._.js +1 -1
  136. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1rv-sc9._.js +3 -0
  137. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1tlvv9a._.js +3 -0
  138. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1u-wx42._.js +4 -0
  139. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1v185mo._.js +3 -0
  140. package/.next/standalone/.next/server/chunks/ssr/_0-yi74u._.js +3 -0
  141. package/.next/standalone/.next/server/chunks/ssr/_0rjgfln._.js +3 -0
  142. package/.next/standalone/.next/server/chunks/ssr/_0vo2qyt._.js +3 -0
  143. package/.next/standalone/.next/server/chunks/ssr/_0xej-0e._.js +3 -0
  144. package/.next/standalone/.next/server/chunks/ssr/_10399ge._.js +3 -0
  145. package/.next/standalone/.next/server/chunks/ssr/_11_p9y8._.js +1 -1
  146. package/.next/standalone/.next/server/chunks/ssr/_149k9oy._.js +3 -0
  147. package/.next/standalone/.next/server/chunks/ssr/_1_hwp06._.js +3 -0
  148. package/.next/standalone/.next/server/chunks/ssr/_1ctse6u._.js +3 -0
  149. package/.next/standalone/.next/server/chunks/ssr/_1e19atl._.js +1 -1
  150. package/.next/standalone/.next/server/chunks/ssr/_1mnhi_r._.js +3 -0
  151. package/.next/standalone/.next/server/chunks/ssr/_1ror7k9._.js +3 -0
  152. package/.next/standalone/.next/server/chunks/ssr/_1sdgprl._.js +5 -0
  153. package/.next/standalone/.next/server/chunks/ssr/app_audit__components_audit-dashboard_tsx_0p9ud47._.js +2 -2
  154. package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_1kp6l3x._.js +1 -1
  155. package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_19dqvpc._.js +2 -2
  156. package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0dwo94s.js +4 -0
  157. package/.next/standalone/.next/server/chunks/ssr/node_modules_posthog-node_dist_entrypoints_index_node_mjs_11bnuzn._.js +2 -1
  158. package/.next/standalone/.next/server/chunks/ssr/src_hooks_builtin-policies_ts_09j2ndl._.js +3 -0
  159. package/.next/standalone/.next/server/chunks/ssr/src_hooks_fp-config_ts_04t589g._.js +4 -0
  160. package/.next/standalone/.next/server/middleware-build-manifest.js +6 -6
  161. package/.next/standalone/.next/server/middleware.js +2 -2
  162. package/.next/standalone/.next/server/pages/404.html +1 -1
  163. package/.next/standalone/.next/server/pages/500.html +1 -1
  164. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  165. package/.next/standalone/.next/server/server-reference-manifest.json +74 -20
  166. package/.next/standalone/.next/static/chunks/{03fmihek9n986.js → 06zgzyh3wv1ig.js} +1 -1
  167. package/.next/standalone/.next/static/chunks/0km-jn9o5xyqs.css +2 -0
  168. package/.next/standalone/.next/static/chunks/{1hdhteui932bq.js → 0qmo2t50kpb30.js} +1 -1
  169. package/.next/standalone/.next/static/chunks/{2sbelanzvxvv0.js → 113g8wtal6_c4.js} +22 -22
  170. package/.next/standalone/.next/static/chunks/16p68cybetr31.js +1 -0
  171. package/.next/standalone/.next/static/chunks/18wqn0_3mzylf.js +1 -0
  172. package/.next/standalone/.next/static/chunks/1v1gqvpjk62jm.js +1 -0
  173. package/.next/standalone/.next/static/chunks/{0fi645si-uiiq.js → 1xq1m8h14tnlj.js} +1 -1
  174. package/.next/standalone/.next/static/chunks/{3hp8ulqknybil.js → 1y3vwogqb88dx.js} +1 -1
  175. package/.next/standalone/.next/static/chunks/{3vs4ay36tjds_.js → 1zmh-b0ulrqu7.js} +1 -1
  176. package/.next/standalone/.next/static/chunks/23kev26by1e4f.js +1 -0
  177. package/.next/standalone/.next/static/chunks/299lhw60e8gr6.js +1 -0
  178. package/.next/standalone/.next/static/chunks/{18rvdw5v72364.js → 2adbpdaxp5ygq.js} +1 -1
  179. package/.next/standalone/.next/static/chunks/{2j94uwkb4s3qr.js → 2kbqcw-6swmav.js} +1 -1
  180. package/.next/standalone/.next/static/chunks/2n9n5m0963pdg.js +6 -0
  181. package/.next/standalone/.next/static/chunks/2uvhw57mf9lg_.css +2 -0
  182. package/.next/standalone/.next/static/chunks/{31feojxhjyjpl.js → 30nrrpwymht5m.js} +1 -1
  183. package/.next/standalone/.next/static/chunks/31coz11ia5vc4.js +1 -0
  184. package/.next/standalone/.next/static/chunks/{turbopack-1lsv92x7klwrn.js → turbopack-3diub4ctvn1n0.js} +1 -1
  185. package/.next/standalone/SECURITY.md +8 -2
  186. package/.next/standalone/app/actions/get-active-pauses.ts +16 -0
  187. package/.next/standalone/app/actions/get-hooks-config.ts +2 -2
  188. package/.next/standalone/app/actions/get-scheduled-audit.ts +70 -0
  189. package/.next/standalone/app/actions/update-scheduled-audit.ts +44 -0
  190. package/.next/standalone/app/api/audit/run/route.ts +28 -0
  191. package/.next/standalone/app/api/audit/status/route.ts +13 -1
  192. package/.next/standalone/app/api/auth/status/route.ts +1 -1
  193. package/.next/standalone/app/audit/_components/audit-dashboard.tsx +1 -3
  194. package/.next/standalone/app/audit/_components/audit-progress-strip.tsx +1 -1
  195. package/.next/standalone/app/audit/_components/auth-dialog.css +159 -0
  196. package/.next/standalone/app/audit/_components/auth-dialog.tsx +3 -0
  197. package/.next/standalone/app/audit/_components/come-back-better-section.tsx +1 -1
  198. package/.next/standalone/app/audit/_components/empty-state.tsx +0 -1
  199. package/.next/standalone/app/audit/_components/how-to-improve-section.tsx +1 -1
  200. package/.next/standalone/app/audit/_components/quirks-section.tsx +0 -1
  201. package/.next/standalone/app/audit/_components/report-footer.tsx +0 -2
  202. package/.next/standalone/app/audit/_components/run-progress.tsx +1 -1
  203. package/.next/standalone/app/audit/_components/strengths-section.tsx +0 -1
  204. package/.next/standalone/app/audit/audit-styles.css +6 -149
  205. package/.next/standalone/app/components/pause-notices.tsx +111 -0
  206. package/.next/standalone/app/components/raw-log-viewer.tsx +1 -1
  207. package/.next/standalone/app/components/toast.tsx +1 -1
  208. package/.next/standalone/app/policies/hooks-client.tsx +84 -8
  209. package/.next/standalone/app/settings/page.tsx +31 -0
  210. package/.next/standalone/app/settings/settings-client.tsx +487 -0
  211. package/.next/standalone/components/navbar.tsx +2 -0
  212. package/.next/standalone/lib/auth/api-server-client.ts +2 -3
  213. package/.next/standalone/lib/auth/auth-store.ts +4 -5
  214. package/.next/standalone/lib/codex-sessions.ts +2 -1
  215. package/.next/standalone/lib/dashboard-host.ts +101 -0
  216. package/.next/standalone/lib/install-check.ts +22 -7
  217. package/.next/standalone/lib/pi-sessions.ts +99 -14
  218. package/.next/standalone/lib/telemetry-enabled.ts +54 -0
  219. package/.next/standalone/lib/telemetry-id.ts +52 -1
  220. package/.next/standalone/lib/telemetry.ts +8 -4
  221. package/.next/standalone/node_modules/react/cjs/react.development.js +1 -1
  222. package/.next/standalone/node_modules/react/cjs/react.production.js +1 -1
  223. package/.next/standalone/node_modules/react/package.json +3 -3
  224. package/.next/standalone/node_modules/react-dom/cjs/react-dom-server-legacy.browser.production.js +1 -1
  225. package/.next/standalone/node_modules/react-dom/cjs/react-dom-server-legacy.node.production.js +1 -1
  226. package/.next/standalone/node_modules/react-dom/cjs/react-dom-server.browser.production.js +3 -3
  227. package/.next/standalone/node_modules/react-dom/cjs/react-dom-server.edge.production.js +3 -3
  228. package/.next/standalone/node_modules/react-dom/cjs/react-dom-server.node.production.js +3 -3
  229. package/.next/standalone/node_modules/react-dom/cjs/react-dom.production.js +1 -1
  230. package/.next/standalone/node_modules/react-dom/package.json +4 -4
  231. package/.next/standalone/package.json +23 -12
  232. package/.next/standalone/proxy.ts +111 -1
  233. package/.next/standalone/server.js +1 -1
  234. package/bin/failproofai-worker.mjs +1 -1
  235. package/bin/failproofai.mjs +1041 -81
  236. package/bin/failproofaid-shim.mjs +4 -4
  237. package/dist/cli.mjs +18513 -10474
  238. package/dist/worker.mjs +1223 -299
  239. package/lib/auth/api-server-client.ts +2 -3
  240. package/lib/auth/auth-store.ts +4 -5
  241. package/lib/codex-sessions.ts +2 -1
  242. package/lib/dashboard-host.ts +101 -0
  243. package/lib/install-check.ts +22 -7
  244. package/lib/pi-sessions.ts +99 -14
  245. package/lib/telemetry-enabled.ts +54 -0
  246. package/lib/telemetry-id.ts +52 -1
  247. package/lib/telemetry.ts +8 -4
  248. package/package.json +23 -12
  249. package/scripts/build-daemon-packages.mjs +247 -0
  250. package/scripts/daemon-platforms.mjs +42 -0
  251. package/scripts/dev-hook.mjs +46 -5
  252. package/scripts/install-telemetry.mjs +8 -1
  253. package/scripts/launch.ts +25 -3
  254. package/scripts/parse-script-args.ts +27 -1
  255. package/scripts/prune-standalone.mjs +26 -0
  256. package/scripts/publish-aliases.mjs +62 -41
  257. package/scripts/repro-npm-install.sh +155 -0
  258. package/scripts/translate-docs/cache.ts +1 -1
  259. package/scripts/translate-docs/cli.ts +2 -2
  260. package/scripts/translate-docs/mintlify-nav.ts +1 -1
  261. package/scripts/translate-docs/readme-translator.ts +163 -4
  262. package/scripts/validate-mdx.ts +153 -13
  263. package/src/audit/audit-lock.ts +285 -0
  264. package/src/audit/audit-schedule.ts +111 -0
  265. package/src/audit/cache.ts +18 -5
  266. package/src/audit/cli-adapters/goose.ts +2 -1
  267. package/src/audit/cli-adapters/hermes.ts +28 -10
  268. package/src/audit/cli.ts +191 -35
  269. package/src/audit/dashboard-cache.ts +2 -3
  270. package/src/audit/report.ts +0 -1
  271. package/src/hooks/backfill-cli.ts +247 -0
  272. package/src/hooks/builtin-policies.ts +391 -3
  273. package/src/hooks/cloud-connection.ts +354 -0
  274. package/src/hooks/cloud-enrollment-cli.ts +439 -0
  275. package/src/hooks/cloud-enrollment.ts +284 -0
  276. package/src/hooks/cloud-introspect.ts +147 -0
  277. package/src/hooks/cloud-managed-policies.ts +206 -0
  278. package/src/hooks/collector-config.ts +218 -0
  279. package/src/hooks/configure-wizard.ts +1211 -233
  280. package/src/hooks/custom-hooks-loader.ts +243 -37
  281. package/src/hooks/daemon-client.ts +136 -33
  282. package/src/hooks/daemon-download.ts +264 -31
  283. package/src/hooks/daemon-service.ts +1124 -76
  284. package/src/hooks/first-run-gate.ts +50 -0
  285. package/src/hooks/flush-cli.ts +180 -0
  286. package/src/hooks/fp-config.ts +835 -0
  287. package/src/hooks/fp-home.ts +714 -0
  288. package/src/hooks/fp-reset.ts +1363 -0
  289. package/src/hooks/handler.ts +185 -6
  290. package/src/hooks/harness-cli.ts +386 -0
  291. package/src/hooks/hook-activity-store.ts +171 -24
  292. package/src/hooks/hook-logger.ts +2 -2
  293. package/src/hooks/hook-telemetry.ts +5 -1
  294. package/src/hooks/hooks-config.ts +4 -3
  295. package/src/hooks/integrations.ts +0 -1
  296. package/src/hooks/loader-utils.ts +172 -9
  297. package/src/hooks/manager.ts +41 -5
  298. package/src/hooks/migrations.ts +450 -0
  299. package/src/hooks/onboarding-attempt.ts +195 -0
  300. package/src/hooks/onboarding-lock.ts +118 -0
  301. package/src/hooks/policy-types.ts +28 -0
  302. package/src/hooks/session-pause-cli.ts +159 -0
  303. package/src/hooks/session-pause.ts +267 -0
  304. package/src/hooks/setup-state.ts +256 -0
  305. package/src/hooks/tui.ts +209 -9
  306. package/src/hooks/uninstall-cli.ts +418 -0
  307. package/src/hooks/worker-server.ts +134 -15
  308. package/.next/standalone/.next/server/chunks/[externals]__14odj07._.js +0 -3
  309. package/.next/standalone/.next/server/chunks/[externals]__1s61mel._.js +0 -3
  310. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0id_xf7._.js +0 -3
  311. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0longh-._.js +0 -3
  312. package/.next/standalone/.next/server/chunks/[root-of-the-server]__17g9wh7._.js +0 -3
  313. package/.next/standalone/.next/server/chunks/[root-of-the-server]__19120tr._.js +0 -3
  314. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1fwl2mz._.js +0 -3
  315. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1myjm-d._.js +0 -3
  316. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1rhmvod._.js +0 -3
  317. package/.next/standalone/.next/server/chunks/ssr/[externals]__1_g_b3t._.js +0 -3
  318. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0114ewg._.js +0 -4
  319. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__02r5bgf._.js +0 -4
  320. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0e8sjqm._.js +0 -4
  321. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0lkzqax._.js +0 -4
  322. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0nb0syg._.js +0 -3
  323. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0qucxyj._.js +0 -4
  324. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0u02miy._.js +0 -4
  325. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0uno39i._.js +0 -3
  326. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__14dd6h8._.js +0 -3
  327. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1ath6v_._.js +0 -4
  328. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1psjybo._.js +0 -3
  329. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1zqz4v8._.js +0 -4
  330. package/.next/standalone/.next/server/chunks/ssr/_1m_p7pi._.js +0 -3
  331. package/.next/standalone/.next/server/chunks/ssr/node_modules_html-to-image_es_index_0oy_-36.js +0 -3
  332. package/.next/standalone/.next/server/chunks/ssr/src_hooks_1ezd2jf._.js +0 -5
  333. package/.next/standalone/.next/server/chunks/ssr/src_hooks_1tnuifj._.js +0 -5
  334. package/.next/standalone/.next/static/chunks/0h7auy7hzjyhw.js +0 -1
  335. package/.next/standalone/.next/static/chunks/0zbxssxh53n-3.js +0 -1
  336. package/.next/standalone/.next/static/chunks/2mazwb1qmur1p.js +0 -1
  337. package/.next/standalone/.next/static/chunks/2pujpnfx4pws6.css +0 -2
  338. package/.next/standalone/.next/static/chunks/33u59vf_8xpd-.js +0 -1
  339. package/.next/standalone/.next/static/chunks/3i27c3hcriawq.css +0 -1
  340. package/.next/standalone/.next/static/chunks/3s7myk_co0gbh.js +0 -1
  341. package/.next/standalone/.next/static/chunks/40k1_v4os4cw6.js +0 -6
  342. package/.next/standalone/Cargo.lock +0 -428
  343. package/.next/standalone/Cargo.toml +0 -9
  344. package/.next/standalone/crates/PROTOCOL.md +0 -122
  345. package/.next/standalone/crates/failproofaid/Cargo.toml +0 -18
  346. package/.next/standalone/crates/failproofaid/src/lock.rs +0 -81
  347. package/.next/standalone/crates/failproofaid/src/main.rs +0 -83
  348. package/.next/standalone/crates/failproofaid/src/paths.rs +0 -172
  349. package/.next/standalone/crates/failproofaid/src/server.rs +0 -502
  350. package/.next/standalone/crates/failproofaid/src/worker.rs +0 -400
  351. package/.next/standalone/crates/failproofaid/tests/daemon_e2e.rs +0 -241
  352. package/.next/standalone/crates/fpai-ipc/Cargo.toml +0 -16
  353. package/.next/standalone/crates/fpai-ipc/src/envelope.rs +0 -175
  354. package/.next/standalone/crates/fpai-ipc/src/framing.rs +0 -177
  355. package/.next/standalone/crates/fpai-ipc/src/lib.rs +0 -10
  356. package/.next/standalone/crates/fpai-ipc/src/peer.rs +0 -80
  357. package/.next/standalone/docker-hook-sync/Dockerfile +0 -79
  358. package/.next/standalone/docker-hook-sync/entrypoint.sh +0 -109
  359. package/.next/standalone/integration-suite/Dockerfile +0 -47
  360. package/.next/standalone/integration-suite/README.md +0 -129
  361. package/.next/standalone/integration-suite/canary-policies.mjs +0 -45
  362. package/.next/standalone/integration-suite/capture-tokens.sh +0 -48
  363. package/.next/standalone/integration-suite/ci-entrypoint.sh +0 -179
  364. package/.next/standalone/integration-suite/inject-tokens.sh +0 -44
  365. package/.next/standalone/integration-suite/install-clis.sh +0 -136
  366. package/.next/standalone/integration-suite/probe-cli.sh +0 -248
  367. package/.next/standalone/integration-suite/report.js +0 -120
  368. package/.next/standalone/integration-suite/run.sh +0 -159
  369. package/.next/standalone/openclaw-plugin/index.js +0 -223
  370. package/.next/standalone/openclaw-plugin/openclaw.plugin.json +0 -6
  371. package/.next/standalone/openclaw-plugin/package.json +0 -12
  372. package/.next/standalone/osv-scanner.toml +0 -17
  373. package/.next/standalone/pi-extension/index.ts +0 -524
  374. package/.next/standalone/pi-extension/package.json +0 -12
  375. package/.next/standalone/postcss.config.mjs +0 -8
  376. package/.next/standalone/readme-arch-hq.gif +0 -0
  377. package/.next/standalone/rust-toolchain.toml +0 -4
  378. package/src/auth/cli.ts +0 -371
  379. /package/.next/standalone/.next/static/{NWAjs0tHFyzk97gRGG09r → VjEdIL6W5uBsvEzknXqV9}/_buildManifest.js +0 -0
  380. /package/.next/standalone/.next/static/{NWAjs0tHFyzk97gRGG09r → VjEdIL6W5uBsvEzknXqV9}/_clientMiddlewareManifest.js +0 -0
  381. /package/.next/standalone/.next/static/{NWAjs0tHFyzk97gRGG09r → VjEdIL6W5uBsvEzknXqV9}/_ssgManifest.js +0 -0
@@ -0,0 +1,439 @@
1
+ /**
2
+ * `failproofai config --connect | --disconnect`, and the connection half of
3
+ * `--status`.
4
+ */
5
+ import {
6
+ clearCloudCredentials,
7
+ maskToken,
8
+ readCloudCredentials,
9
+ writeCloudCredentials,
10
+ resolveMachineId,
11
+ resolveMachineLabel,
12
+ validateCloudUrl,
13
+ verifyCloudCredentials,
14
+ cloudCredentialPath,
15
+ } from "./cloud-enrollment";
16
+ import {
17
+ daemonRestartCommand,
18
+ daemonServiceStatus,
19
+ daemonStatusCommand,
20
+ daemonVersionSkew,
21
+ } from "./daemon-service";
22
+ import { clearActiveCloudManagedPolicies } from "./cloud-managed-policies";
23
+ import { readVersionFile, readCredentials } from "./fp-config";
24
+ import { version as cliVersion } from "../../package.json";
25
+ import { daemonSocketPresent } from "./daemon-client";
26
+ import {
27
+ cloudBaseFor,
28
+ configuredPaths,
29
+ connectToCloud,
30
+ describeOutcome,
31
+ } from "./cloud-connection";
32
+ import {
33
+ clearIngestCredential,
34
+ hasIngestCredential,
35
+ readIngestCredential,
36
+ validateIngestKey,
37
+ } from "./collector-config";
38
+ import { updateConfig } from "./fp-config";
39
+ import type { introspectKey } from "./cloud-introspect";
40
+
41
+ export interface ConnectOptions {
42
+ url?: string;
43
+ token?: string;
44
+ machineId?: string;
45
+ /** Human-facing display name for this machine. Defaults to the hostname. */
46
+ machineLabel?: string;
47
+ /**
48
+ * The hostname, passed in by the caller (and injected by tests). Used as the
49
+ * default machine *label*, no longer as the machine id — the id now mints or
50
+ * reuses a stable key so two hosts with the same hostname never merge.
51
+ */
52
+ defaultMachineId?: string;
53
+ /**
54
+ * Send full session transcripts as well as hook decisions.
55
+ *
56
+ * DEFAULTS ON. A transcript carries prompts, file contents and whatever was
57
+ * pasted into a terminal — which is precisely what makes a dashboard worth
58
+ * connecting to, so hiding it behind an opt-in produced the empty-dashboard
59
+ * problem in a different costume. `false` is the explicit opt-out; the
60
+ * disclosure is printed either way.
61
+ */
62
+ sessions?: boolean;
63
+ environment?: string;
64
+ /**
65
+ * Injected for tests so nothing reaches the network.
66
+ *
67
+ * All THREE must be here, and a new network call added below has to gain its
68
+ * seam in the same commit: `introspect` was added without one, so every test
69
+ * in `cloud-enrollment-cli.test.ts` silently began making a real request to
70
+ * `be.failproof.ai`. It usually failed fast enough to pass, which is the worst
71
+ * available outcome — the suite went intermittently red on network timing
72
+ * rather than on anything a change had broken.
73
+ */
74
+ verify?: typeof verifyCloudCredentials;
75
+ verifyIngest?: typeof validateIngestKey;
76
+ introspect?: typeof introspectKey;
77
+ daemonStatus?: () => ReturnType<typeof daemonServiceStatus>;
78
+ }
79
+
80
+ export interface CommandResult {
81
+ exitCode: number;
82
+ lines: string[];
83
+ }
84
+
85
+ /**
86
+ * How a machine is named in CLI output: the human label, plus enough of the id to
87
+ * tell two machines apart.
88
+ *
89
+ * The full uuid used to be printed in every status line — `Mac.localdomain
90
+ * (dde01f39-afba-40eb-bf1a-815d9f17ac2d)` — which is 36 characters of noise for
91
+ * the one reader who cannot use them, and it made the id look like the machine's
92
+ * name. The id still has to appear: labels default to the hostname and are free to
93
+ * collide, so the label alone cannot identify a machine. Eight hex characters
94
+ * distinguish any realistic fleet while staying readable.
95
+ *
96
+ * `failproofai config --status --verbose` prints the full id for support.
97
+ */
98
+ export function describeMachine(
99
+ machineId: string,
100
+ machineLabel?: string,
101
+ full = false,
102
+ ): string {
103
+ if (!machineLabel || machineLabel === machineId) return machineId;
104
+ return full ? `${machineLabel} (${machineId})` : `${machineLabel} (${machineId.slice(0, 8)})`;
105
+ }
106
+
107
+ /**
108
+ * Warn rather than refuse when there is no daemon.
109
+ *
110
+ * Cloud policy is evaluated by failproofaid, so credentials alone pull
111
+ * nothing — but refusing would break baking a machine image where the daemon
112
+ * is installed later, and enrolment is genuinely independent of it. Say so
113
+ * loudly instead of failing.
114
+ */
115
+ function daemonWarning(status: ReturnType<typeof daemonServiceStatus>): string[] {
116
+ if (status === "running") return [];
117
+ // "I could not tell", NOT "it is not a service". This has its own branch, and it
118
+ // is ahead of the socket check, because on macOS it is the COMMON case rather
119
+ // than an edge one: a LaunchDaemon lives in launchd's system domain, so
120
+ // `daemonServiceStatus()` needs elevation to read it and returns "unknown"
121
+ // whenever `sudo -n` finds no cached credential — which is most of the time, for
122
+ // a normal user running a read-only status command.
123
+ //
124
+ // With no branch of its own it fell through to the socket check below and
125
+ // announced that the daemon was "running outside the service manager", which is
126
+ // flatly false for a correctly installed service, and told the user to install
127
+ // something they already had. Linux never showed it, because `systemctl
128
+ // is-active` needs no privileges — that asymmetry was the whole of the bug.
129
+ if (status === "unknown") {
130
+ const check = daemonStatusCommand();
131
+ return [
132
+ "",
133
+ ...(daemonSocketPresent()
134
+ ? [" A daemon is running and policy is being pulled."]
135
+ : ["! No daemon is answering, so nothing is being pulled right now."]),
136
+ " Its service state needs elevation to read, so it is not shown above.",
137
+ ...(check ? [` Check it with: sudo ${check}`] : []),
138
+ ];
139
+ }
140
+ // A daemon started by hand is invisible to the service manager but is
141
+ // running and pulling. Telling someone whose machine is actively enforcing
142
+ // that "nothing will be pulled" is false, and it is exactly the state a
143
+ // developer testing locally is in.
144
+ if (daemonSocketPresent()) {
145
+ return [
146
+ "",
147
+ " A daemon is running outside the service manager, so policy is being pulled.",
148
+ " Install it as a service to survive reboot and logout: failproofai config",
149
+ ];
150
+ }
151
+ if (status === "unsupported-platform") {
152
+ return [
153
+ "",
154
+ "! failproofaid does not run on this platform yet, so nothing will be pulled.",
155
+ " The credentials are stored and will work on a supported machine.",
156
+ ];
157
+ }
158
+ if (status === "not-installed") {
159
+ // "as a service", not "at all": this reads the service manager, so a daemon
160
+ // someone is running by hand during development is reported as absent. The
161
+ // wording has to be true in both cases.
162
+ return [
163
+ "",
164
+ "! failproofaid is not installed as a service, so nothing will be pulled yet.",
165
+ " Install it with: failproofai config",
166
+ ];
167
+ }
168
+ return [
169
+ "",
170
+ "! failproofaid is installed but not running, so nothing will be pulled yet.",
171
+ " Check it with: failproofai config --status",
172
+ ];
173
+ }
174
+
175
+ export async function runConnectCommand(opts: ConnectOptions): Promise<CommandResult> {
176
+ if (!opts.url) return { exitCode: 1, lines: ["--connect needs a URL, e.g. --connect https://be.failproof.ai"] };
177
+ if (!opts.token) {
178
+ return {
179
+ exitCode: 1,
180
+ lines: [
181
+ "--connect needs a machine token: --token <key>",
182
+ "",
183
+ "Create an API key carrying only the `policies:pull` permission for this",
184
+ "machine. Do not use an admin key.",
185
+ ],
186
+ };
187
+ }
188
+
189
+ // Accepts the ingest endpoint too. People paste what the older setup asked
190
+ // for, or what is already in their `ingest.json`, and refusing a URL we can
191
+ // read perfectly well is pedantry.
192
+ const validated = validateCloudUrl(cloudBaseFor(opts.url));
193
+ if (!validated.ok) return { exitCode: 1, lines: [validated.reason] };
194
+
195
+ // The stable key: an explicit --machine-id wins, else the id already enrolled
196
+ // here is reused (idempotent re-connect), else a fresh one is minted. Never
197
+ // the hostname — that is the label, so same-hostname hosts do not merge.
198
+ const machineId = resolveMachineId(opts.machineId);
199
+ const machineLabel = resolveMachineLabel(opts.machineLabel ?? opts.defaultMachineId);
200
+ // Humans read the label; the id is shown in parentheses only when it differs,
201
+ // so an operator who set an explicit --machine-id still sees it.
202
+ const shownAs = describeMachine(machineId, machineLabel);
203
+
204
+ // ONE connection, both capabilities. Each is verified before anything is
205
+ // written and reported on its own, because a key can carry `policies:pull`
206
+ // without `events:add` and the useful message names which one is missing.
207
+ const outcome = await connectToCloud({
208
+ url: validated.url,
209
+ token: opts.token,
210
+ machineId,
211
+ machineLabel,
212
+ sessions: opts.sessions,
213
+ environment: opts.environment,
214
+ verifyPolicy: opts.verify,
215
+ verifyIngest: opts.verifyIngest,
216
+ introspect: opts.introspect,
217
+ });
218
+
219
+ if (!outcome.anyConfigured) {
220
+ return { exitCode: 1, lines: describeOutcome(outcome, shownAs, validated.url) };
221
+ }
222
+
223
+ // The exit code tracks the PRIMARY purpose — enrolling this machine for
224
+ // cloud-managed policy. Configuring the dashboard is worth doing and worth
225
+ // reporting, but it must not turn a failed enrolment into a success: a fleet
226
+ // provisioning script running `--connect … && …` has to stop when the machine
227
+ // will not receive policy. The ingest credential still gets written, because
228
+ // it works and discarding it helps nobody.
229
+ const exitCode = outcome.policy.ok ? 0 : 1;
230
+
231
+ const status = (opts.daemonStatus ?? daemonServiceStatus)();
232
+ const paths = configuredPaths(outcome);
233
+ const lines = [
234
+ ...describeOutcome(outcome, shownAs, validated.url),
235
+ ` Token ${maskToken(opts.token)} stored in ${paths.join(" and ")} (owner-only).`,
236
+ ];
237
+ if (outcome.ingest.ok) {
238
+ // Stated on BOTH branches, never only on the surprising one. Connecting
239
+ // sends transcripts by default — prompts, file contents, command output —
240
+ // and a default that carries that much is one the user has to be told
241
+ // about at the moment it takes effect, not left to find in --help.
242
+ lines.push(
243
+ opts.sessions === false
244
+ ? " Session transcripts are NOT being sent (--no-transcripts). Decisions only."
245
+ : " Sending policy decisions AND full session transcripts (prompts, file\n" +
246
+ " contents, command output). Use --no-transcripts for decisions only.",
247
+ );
248
+ }
249
+ lines.push(...daemonWarning(status));
250
+
251
+ return { exitCode, lines };
252
+ }
253
+
254
+ /**
255
+ * Rename this machine without re-enrolling it.
256
+ *
257
+ * `--machine-label` was accepted only alongside `--connect`, so the sole way to
258
+ * change a name was to re-run enrolment with the URL and token again — which reads
259
+ * as a destructive operation for what is a display change, and which nobody with a
260
+ * machine token to hand is going to do casually. The hostname default is a
261
+ * suggestion (`resolveMachineLabel`), so renaming is the expected path, not an
262
+ * exception.
263
+ *
264
+ * The label rides the desired-state request (`&label=`), which is also the check
265
+ * that the credentials still work — so a rename verifies as a side effect. A
266
+ * server that cannot be reached is NOT treated as failure: the label is stored
267
+ * locally first and the daemon sends it on its next poll. Refusing to rename a
268
+ * machine because the network is down would make this useless exactly when someone
269
+ * is trying to label a machine they are debugging.
270
+ */
271
+ export async function runRenameCommand(
272
+ label: string | undefined,
273
+ deps: { verify?: typeof verifyCloudCredentials } = {},
274
+ ): Promise<CommandResult> {
275
+ const trimmed = label?.trim();
276
+ if (!trimmed) {
277
+ return { exitCode: 1, lines: ["--machine-label needs a name, e.g. --machine-label \"Nikita's Mac\""] };
278
+ }
279
+ const creds = readCloudCredentials();
280
+ if (!creds) {
281
+ return {
282
+ exitCode: 1,
283
+ lines: [
284
+ "This machine is not connected to Failproof Cloud, so it has no name to change.",
285
+ "Connect it first: failproofai config --connect <url> --token <key>",
286
+ ],
287
+ };
288
+ }
289
+ if (creds.machineLabel === trimmed) {
290
+ return { exitCode: 0, lines: [`This machine is already named ${describeMachine(creds.machineId, trimmed)}.`] };
291
+ }
292
+
293
+ const previous = creds.machineLabel;
294
+ // Stored BEFORE the push, so a rename survives an unreachable server.
295
+ writeCloudCredentials({ ...creds, machineLabel: trimmed });
296
+
297
+ const verify = deps.verify ?? verifyCloudCredentials;
298
+ const result = await verify({ ...creds, machineLabel: trimmed });
299
+
300
+ const lines = [
301
+ previous
302
+ ? `Renamed ${previous} to ${describeMachine(creds.machineId, trimmed)}.`
303
+ : `Named this machine ${describeMachine(creds.machineId, trimmed)}.`,
304
+ ];
305
+ if (!result.ok) {
306
+ lines.push(
307
+ "",
308
+ `! The new name is stored but ${creds.url} could not be told: ${result.reason}`,
309
+ " The daemon sends it on its next poll, so the dashboard catches up on its own.",
310
+ );
311
+ }
312
+ // Exit 0 either way: the rename DID happen locally, and reporting failure for a
313
+ // stored change would send the user round again to redo something that is done.
314
+ return { exitCode: 0, lines };
315
+ }
316
+
317
+ export function runDisconnectCommand(): CommandResult {
318
+ const existing = readCloudCredentials();
319
+ const hadIngest = hasIngestCredential();
320
+ const removed = clearCloudCredentials();
321
+ // Disconnect means disconnect. Clearing only the policy credential would
322
+ // leave the machine still shipping activity to a cloud the user believes
323
+ // they have left — the one outcome nobody expects from this command.
324
+ const removedIngest = clearIngestCredential();
325
+ // Stop ENFORCING them too, not merely refreshing them. Clearing the
326
+ // credential ends the daemon's polling; every artifact already on disk stayed
327
+ // referenced by `active.json` and kept being loaded on every tool call — so a
328
+ // machine that had deliberately left its organisation went on being governed
329
+ // by whatever deployment was current when it left, indefinitely, while
330
+ // `--status` reported it as unconnected.
331
+ const stoppedManaged = clearActiveCloudManagedPolicies();
332
+ // Back to OSS. Leaving mode = "cloud" with no credentials would describe a
333
+ // machine that does not exist, and every cloud code path keys off this flag
334
+ // rather than off "is a token lying around" precisely so that a disconnected
335
+ // machine is provably silent instead of silent-by-happenstance.
336
+ updateConfig({ mode: "oss" });
337
+
338
+ if (!removed && !existing && !hadIngest && !stoppedManaged) {
339
+ return { exitCode: 0, lines: ["This machine is not connected to Failproof Cloud."] };
340
+ }
341
+
342
+ const lines = [
343
+ "Disconnected from Failproof Cloud.",
344
+ "",
345
+ stoppedManaged
346
+ ? " Cloud-managed policies stop being enforced and stop being refreshed.\n" +
347
+ " Local builtin, custom and convention policies are unaffected."
348
+ : " Local builtin, custom and convention policies are unaffected.",
349
+ ];
350
+ if (removedIngest) {
351
+ // Named honestly. The collector manager starts once for the daemon's
352
+ // lifetime (`main.rs`) and the uploader caches its bearer key at
353
+ // construction, so nothing already running notices this file disappear —
354
+ // "stop being sent" was true only of the NEXT daemon start. Telling the
355
+ // user the step that makes it true beats a claim that quietly is not.
356
+ lines.push(
357
+ " No new hook activity or transcripts will be queued. A running failproofaid",
358
+ " keeps the key it started with, so restart it to stop the current process",
359
+ ` sending: ${daemonRestartCommand() ?? "restart failproofaid"}`,
360
+ );
361
+ }
362
+ return { exitCode: 0, lines };
363
+ }
364
+
365
+ /** The connection half of `--status`. Never prints the token. */
366
+ /**
367
+ * The version line for `--status`.
368
+ *
369
+ * First thing worth knowing in a bug report, and the only place a user can
370
+ * currently find out which daemon they are running without listing a directory.
371
+ */
372
+ export function versionStatusLines(): string[] {
373
+ const skew = daemonVersionSkew();
374
+ const recorded = readVersionFile();
375
+ const daemon = recorded?.daemon ?? "not installed";
376
+ return [
377
+ `CLI ${cliVersion} · daemon ${daemon}${skew ? " (STALE)" : ""} · layout ${recorded?.layout ?? "-"}`,
378
+ ...(skew ? [" Run `failproofai config` to update the daemon."] : []),
379
+ ];
380
+ }
381
+
382
+ export function connectionStatusLines(
383
+ daemonStatus = daemonServiceStatus,
384
+ /** Print the full machine id rather than a short prefix. */
385
+ verbose = false,
386
+ ): string[] {
387
+ const envUrl = process.env.FAILPROOFAI_CLOUD_URL;
388
+ if (envUrl) {
389
+ // Env wins over the file in the daemon, so reporting the file here would
390
+ // describe a configuration that is not in effect.
391
+ return [
392
+ `Cloud: configured by environment (${envUrl}), which takes precedence over ${cloudCredentialPath()}.`,
393
+ ];
394
+ }
395
+ const creds = readCloudCredentials();
396
+ const ingest = readIngestCredential();
397
+
398
+ // Reported as ONE connection with two capabilities. A machine sending
399
+ // activity but pulling no policy, or the reverse, is a state worth seeing at
400
+ // a glance — it is exactly the half-configured case this command exists to
401
+ // catch, and two unrelated lines made it easy to miss.
402
+ if (!creds && !ingest) return ["Cloud: not connected."];
403
+
404
+ // Recorded at connect time from the server's own answer, never guessed from
405
+ // the URL: one deployment hosts many orgs, so the host says nothing about
406
+ // which one this machine's data lands in. Absent against a server with no
407
+ // introspect endpoint, and on credentials written before this was recorded —
408
+ // in both cases the line is simply omitted rather than guessed at.
409
+ const org = readCredentials().org;
410
+ const orgLine = org
411
+ ? org.name && org.slug
412
+ ? `${org.name} (${org.slug})`
413
+ : (org.name ?? org.slug ?? org.id)
414
+ : undefined;
415
+
416
+ const lines: string[] = [];
417
+ if (creds) {
418
+ // Label first, with a short id to disambiguate; the bare id is the fallback
419
+ // for credentials written before labels existed.
420
+ const shownAs = describeMachine(creds.machineId, creds.machineLabel, verbose);
421
+ lines.push(`Cloud: connected to ${creds.url} as ${shownAs} (token ${maskToken(creds.token)}).`);
422
+ lines.push(` Policy pulling centrally-managed policies.`);
423
+ } else {
424
+ lines.push(`Cloud: connected to ${cloudBaseFor(ingest!.url)} for reporting only.`);
425
+ lines.push(` Policy NOT pulling — this machine enforces only its local policies.`);
426
+ }
427
+
428
+ if (orgLine) lines.push(` Org ${orgLine}`);
429
+
430
+ if (ingest) {
431
+ lines.push(` Dashboard sending hook activity to ${ingest.url}.`);
432
+ } else {
433
+ lines.push(` Dashboard NOT sending — nothing from this machine appears in the dashboard.`);
434
+ lines.push(` Re-run: failproofai config --connect ${creds!.url} --token <key>`);
435
+ }
436
+
437
+ lines.push(...daemonWarning(daemonStatus()).map((l) => (l === "" ? "" : ` ${l.trim()}`)));
438
+ return lines;
439
+ }