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,354 @@
1
+ /**
2
+ * One connection to Failproof Cloud, with two capabilities.
3
+ *
4
+ * # Why this exists
5
+ *
6
+ * Enrolment (#632) and collection (#640) were built independently and each
7
+ * arrived with its own credential file, its own URL and its own setup step:
8
+ *
9
+ * pull policy -> ~/.failproofai/cloud.json <base>/enforcement/v1/...
10
+ * push events -> ~/.failproofai/ingest.json <base>/events
11
+ *
12
+ * Same server, same organisation, usually the same key. Asked twice, a user
13
+ * who connects for policy sees an empty dashboard and reasonably concludes the
14
+ * product is broken — the second setup step is invisible until someone goes
15
+ * looking for it.
16
+ *
17
+ * So the URL and token are asked for ONCE and both capabilities are configured
18
+ * from them. The two files stay separate on disk — that is a real security
19
+ * boundary, since `cloud.json` and `ingest.json` can hold different keys with
20
+ * different permissions, and the daemon reads them independently — but nothing
21
+ * above this module has to know that.
22
+ *
23
+ * # Capabilities are verified and reported INDEPENDENTLY
24
+ *
25
+ * A key may carry `policies:pull` and not `events:add`, or the reverse. The
26
+ * honest outcome is then a partial connection with a precise reason, not an
27
+ * all-or-nothing failure: refusing to enrol for policy because the dashboard
28
+ * would be empty protects nothing, and silently skipping ingest reproduces the
29
+ * exact confusion this module removes.
30
+ */
31
+ import {
32
+ cloudCredentialPath,
33
+ validateCloudUrl,
34
+ verifyCloudCredentials,
35
+ writeCloudCredentials,
36
+ type CloudCredentials,
37
+ } from "./cloud-enrollment";
38
+ import { updateConfig, readCredentials, writeCredentials } from "./fp-config";
39
+ import {
40
+ introspectKey,
41
+ hasPermission,
42
+ describeOrg,
43
+ PERMISSION_EVENTS,
44
+ PERMISSION_POLICIES,
45
+ } from "./cloud-introspect";
46
+ import {
47
+ ingestPath,
48
+ validateIngestKey,
49
+ writeCollectorSettings,
50
+ writeIngestCredential,
51
+ type CollectorSettings,
52
+ } from "./collector-config";
53
+
54
+ /**
55
+ * The path ingest is served on, appended to the cloud base URL.
56
+ *
57
+ * `/v1/events` rather than `/events`, and the difference is load-bearing for
58
+ * the hosted deployment. The server mounts its route list TWICE — flat at `/`
59
+ * and nested under `/v1` — so both reach the same handler when you talk to the
60
+ * server directly. But on the dashboard hostname a reverse proxy routes only
61
+ * `/v1/*` and `/enforcement/v1/*` to the server and sends EVERYTHING ELSE to
62
+ * the Next.js app. So `https://app.befailproof.ai/events` does not reach ingest
63
+ * at all; it reaches a web app that will happily answer.
64
+ *
65
+ * `/v1/events` is therefore the only path that works on all three shapes: the
66
+ * dashboard hostname, the server hostname, and a Compose deployment with no
67
+ * proxy at all. That is what lets one `--connect <origin>` configure BOTH
68
+ * capabilities from a single URL.
69
+ */
70
+ export const INGEST_PATH = "/v1/events";
71
+
72
+ /**
73
+ * The ingest endpoint for a cloud base URL.
74
+ *
75
+ * Ingest wants a COMPLETE endpoint while enrolment wants a base, which is the
76
+ * whole reason two URLs were being asked for. One is derivable from the other,
77
+ * so only the base is ever asked for.
78
+ */
79
+ export function ingestUrlFor(baseUrl: string): string {
80
+ return `${baseUrl.replace(/\/$/, "")}${INGEST_PATH}`;
81
+ }
82
+
83
+ /**
84
+ * The cloud base for whatever URL someone actually typed.
85
+ *
86
+ * Accepts either form. People paste the ingest endpoint — it is what the older
87
+ * prompt asked for, and what any existing runbook or `ingest.json` contains —
88
+ * and rejecting it as "not a base URL" would be pedantry about a URL we can
89
+ * read perfectly well.
90
+ */
91
+ export function cloudBaseFor(url: string): string {
92
+ const trimmed = url.replace(/\/$/, "");
93
+ // Strip either ingest path. People paste what an older setup asked for, what
94
+ // is already in their config, or what a colleague sent them — and `/events`
95
+ // was the documented value for the whole life of the product before `/v1`.
96
+ // Refusing a URL we can read perfectly well is pedantry; silently treating
97
+ // `https://host/events` as an ORIGIN would be worse, because every derived
98
+ // URL would then carry a stray `/events` segment.
99
+ for (const suffix of [INGEST_PATH, "/events"]) {
100
+ if (trimmed.endsWith(suffix)) return trimmed.slice(0, -suffix.length);
101
+ }
102
+ return trimmed;
103
+ }
104
+
105
+ export interface ConnectInput {
106
+ /**
107
+ * Cloud base URL. Re-validated with `validateCloudUrl` on entry rather than
108
+ * trusted — this used to say "already validated by `validateCloudUrl`", and
109
+ * the wizard did not.
110
+ */
111
+ url: string;
112
+ token: string;
113
+ machineId: string;
114
+ /** Human-facing display name for this machine. Defaults to the hostname. */
115
+ machineLabel?: string;
116
+ /**
117
+ * Send session transcripts.
118
+ *
119
+ * Both callers — the wizard and `--connect` — now pass `true` unless the
120
+ * user opts out, because transcripts are what makes a dashboard worth
121
+ * connecting to. This function itself still requires it EXPLICITLY and
122
+ * treats `undefined` as off: a library that silently opts a caller into
123
+ * shipping prompts and file contents is the wrong default at this layer,
124
+ * whatever the product default above it happens to be.
125
+ */
126
+ sessions?: boolean;
127
+ environment?: string;
128
+ /** Injected by tests so nothing reaches the network. */
129
+ verifyPolicy?: typeof verifyCloudCredentials;
130
+ verifyIngest?: typeof validateIngestKey;
131
+ introspect?: typeof introspectKey;
132
+ }
133
+
134
+ export interface CapabilityOutcome {
135
+ ok: boolean;
136
+ reason?: string;
137
+ }
138
+
139
+ export interface ConnectOutcome {
140
+ policy: CapabilityOutcome & { policyCount?: number; deployment?: number };
141
+ ingest: CapabilityOutcome;
142
+ /** Which organisation the key belongs to. Absent on a pre-introspect server. */
143
+ org?: { id?: string; slug?: string; name?: string };
144
+ /** True when at least one capability was configured. */
145
+ anyConfigured: boolean;
146
+ }
147
+
148
+ /**
149
+ * Verify both capabilities, then write only what actually works.
150
+ *
151
+ * Verification happens BEFORE any write, per capability. A credential file that
152
+ * does not work is worse than none, because `--status` then reports a
153
+ * connection the machine does not have.
154
+ */
155
+ export async function connectToCloud(input: ConnectInput): Promise<ConnectOutcome> {
156
+ // Checked HERE, not only at the call sites. `ConnectInput.url` is documented
157
+ // as "already validated by `validateCloudUrl`", and that was true of exactly
158
+ // one of the two callers: `--connect` validated, and the interactive wizard —
159
+ // the documented primary path — matched `/^https?:\/\//` and handed the raw
160
+ // string straight to `validateIngestKey` and then to here. So the flow most
161
+ // people use sent the machine's bearer token to any `http://` host in clear.
162
+ // A precondition worth stating in a docstring is worth enforcing at the
163
+ // boundary that depends on it.
164
+ const checked = validateCloudUrl(input.url);
165
+ if (!checked.ok) {
166
+ return {
167
+ policy: { ok: false, reason: checked.reason },
168
+ ingest: { ok: false, reason: checked.reason },
169
+ anyConfigured: false,
170
+ };
171
+ }
172
+
173
+ const creds: CloudCredentials = {
174
+ url: input.url,
175
+ machineId: input.machineId,
176
+ token: input.token,
177
+ machineLabel: input.machineLabel,
178
+ };
179
+
180
+ const verifyPolicy = input.verifyPolicy ?? verifyCloudCredentials;
181
+ const verifyIngest = input.verifyIngest ?? validateIngestKey;
182
+ const introspect = input.introspect ?? introspectKey;
183
+ const ingestUrl = ingestUrlFor(input.url);
184
+
185
+ // ── Ask the key what it is, before using it for anything ──────────────────
186
+ //
187
+ // One request answers three questions that are otherwise indistinguishable
188
+ // until much later: is the key accepted, which ORG does it report into, and
189
+ // does it carry the permissions this machine needs. Probing the endpoints
190
+ // (below) can only ever answer the first, and only by inference.
191
+ //
192
+ // A rejected key stops here — probing two more endpoints with a credential
193
+ // the server has already refused tells us nothing and costs two more
194
+ // unauthenticated database lookups on a surface with no rate limiting.
195
+ const identity = await introspect(input.url, input.token);
196
+ if (identity.kind === "rejected") {
197
+ return {
198
+ policy: { ok: false, reason: "the server did not accept that key" },
199
+ ingest: { ok: false, reason: "the server did not accept that key" },
200
+ anyConfigured: false,
201
+ };
202
+ }
203
+
204
+ // `unsupported` — an AgentEye older than the introspect endpoint. Fall
205
+ // through to probing, which is what every release before this one did. The
206
+ // CLI ships independently of whatever server a customer runs, so a good key
207
+ // on an older deployment must still connect.
208
+ const known = identity.kind === "ok" ? identity.identity : null;
209
+
210
+ // Skip a probe the key provably cannot pass. This is not an optimisation: a
211
+ // permission failure surfaces from `/events` as a 403 whose message reads
212
+ // like a server problem, where introspect can say exactly which permission is
213
+ // missing and for which org.
214
+ const canIngest = known ? hasPermission(known, PERMISSION_EVENTS) : true;
215
+ const canPolicy = known ? hasPermission(known, PERMISSION_POLICIES) : true;
216
+
217
+ const missing = (permission: string) =>
218
+ `that key does not carry \`${permission}\`` +
219
+ (known ? ` (it is valid for ${describeOrg(known)})` : "");
220
+
221
+ // Both checks run regardless of the other's result: reporting "cannot pull
222
+ // policy" while staying silent about ingest would send someone to fix one
223
+ // permission and hit the next one afterwards.
224
+ const [policyResult, ingestResult] = await Promise.all([
225
+ canPolicy
226
+ ? verifyPolicy(creds)
227
+ : Promise.resolve({ ok: false as const, reason: missing(PERMISSION_POLICIES) }),
228
+ canIngest
229
+ ? verifyIngest({ url: ingestUrl, key: input.token })
230
+ : Promise.resolve({ ok: false as const, reason: missing(PERMISSION_EVENTS) }),
231
+ ]);
232
+
233
+ const outcome: ConnectOutcome = {
234
+ policy: policyResult.ok
235
+ ? { ok: true, policyCount: policyResult.policyCount, deployment: policyResult.deployment }
236
+ : { ok: false, reason: policyResult.reason },
237
+ ingest: ingestResult.ok ? { ok: true } : { ok: false, reason: ingestResult.reason },
238
+ anyConfigured: false,
239
+ org: known
240
+ ? { id: known.orgId, slug: known.orgSlug, name: known.orgName }
241
+ : undefined,
242
+ };
243
+
244
+ if (policyResult.ok) {
245
+ writeCloudCredentials(creds);
246
+ outcome.anyConfigured = true;
247
+ }
248
+
249
+ // Mode is the hard gate, set only once a capability actually verified.
250
+ // "cloud" is never inferred from a token merely being present: a machine
251
+ // that has not proven it can reach the server must stay provably silent.
252
+ if (policyResult.ok || ingestResult.ok) {
253
+ updateConfig({ mode: "cloud" });
254
+ }
255
+
256
+ if (ingestResult.ok) {
257
+ writeIngestCredential({ url: ingestUrl, key: input.token });
258
+ const settings: CollectorSettings = {
259
+ // Hook activity is what makes the dashboard show anything at all, and it
260
+ // carries decisions and tool names — never file contents.
261
+ hooks: true,
262
+ // Explicit only — see the `sessions` doc on ConnectInput. Callers decide
263
+ // the product default; this layer never infers one.
264
+ sessions: input.sessions === true,
265
+ environment: input.environment,
266
+ // So the daemon stamps this machine's id on every collected event and the
267
+ // dashboard groups by machine, not by per-project agent_id.
268
+ machineId: input.machineId,
269
+ };
270
+ writeCollectorSettings(settings);
271
+ outcome.anyConfigured = true;
272
+ }
273
+
274
+ // Last, and only once something actually configured: recording an org for a
275
+ // machine that connected to nothing would be a claim about where data goes
276
+ // from a machine that sends none. Merged into whatever the two writers above
277
+ // just wrote, so it cannot race them.
278
+ if (outcome.anyConfigured && known && (known.orgId || known.orgSlug || known.orgName)) {
279
+ writeCredentials({
280
+ ...readCredentials(),
281
+ org: { id: known.orgId, slug: known.orgSlug, name: known.orgName },
282
+ });
283
+ }
284
+
285
+ return outcome;
286
+ }
287
+
288
+ /**
289
+ * How to describe the outcome to someone at a terminal.
290
+ *
291
+ * The partial cases are the ones worth wording carefully: each names the
292
+ * missing permission, because "connected, but the dashboard will stay empty"
293
+ * without a cause is the message that sends people to support.
294
+ */
295
+ export function describeOutcome(outcome: ConnectOutcome, machineId: string, url: string): string[] {
296
+ const lines: string[] = [];
297
+
298
+ // Named on every branch that connected, including the partial ones. A key
299
+ // pasted from the wrong organisation authenticates perfectly and reports into
300
+ // somewhere the user is not looking; the org is the only thing on screen that
301
+ // makes that visible, and it is worth nothing if it only prints on success.
302
+ const org = outcome.org
303
+ ? outcome.org.name && outcome.org.slug
304
+ ? `${outcome.org.name} (${outcome.org.slug})`
305
+ : (outcome.org.name ?? outcome.org.slug ?? outcome.org.id)
306
+ : undefined;
307
+ const into = org ? ` into ${org}` : "";
308
+
309
+ if (outcome.policy.ok && outcome.ingest.ok) {
310
+ lines.push(`Connected to ${url} as ${machineId}${into}.`);
311
+ const n = outcome.policy.policyCount ?? 0;
312
+ lines.push(` Policy ${n} polic${n === 1 ? "y" : "ies"} assigned (deployment ${outcome.policy.deployment ?? 0}).`);
313
+ lines.push(` Dashboard hook activity will be sent to ${ingestUrlFor(url)}.`);
314
+ return lines;
315
+ }
316
+
317
+ if (outcome.policy.ok && !outcome.ingest.ok) {
318
+ const n = outcome.policy.policyCount ?? 0;
319
+ lines.push(`Connected to ${url} as ${machineId}${into}, for policy only.`);
320
+ lines.push(` Policy ${n} polic${n === 1 ? "y" : "ies"} assigned (deployment ${outcome.policy.deployment ?? 0}).`);
321
+ lines.push(` Dashboard NOT configured: ${outcome.ingest.reason}`);
322
+ lines.push("");
323
+ lines.push(" Enforcement works. Nothing will appear in the dashboard until this");
324
+ lines.push(" key also carries `events:add`, or you re-run --connect with one that does.");
325
+ return lines;
326
+ }
327
+
328
+ if (!outcome.policy.ok && outcome.ingest.ok) {
329
+ lines.push(`Connected to ${url} as ${machineId}${into}, for dashboard reporting only.`);
330
+ lines.push(` Dashboard hook activity will be sent to ${ingestUrlFor(url)}.`);
331
+ lines.push(` Cloud policy NOT configured: ${outcome.policy.reason}`);
332
+ lines.push("");
333
+ lines.push(" This machine keeps enforcing its LOCAL policies and will report what");
334
+ lines.push(" they decide, but will not receive centrally-managed ones.");
335
+ return lines;
336
+ }
337
+
338
+ lines.push(`Could not connect to ${url}.`);
339
+ lines.push(` Policy: ${outcome.policy.reason}`);
340
+ lines.push(` Dashboard: ${outcome.ingest.reason}`);
341
+ return lines;
342
+ }
343
+
344
+ /** Paths written, for a closing note. Only those that exist. */
345
+ export function configuredPaths(outcome: ConnectOutcome): string[] {
346
+ const paths: string[] = [];
347
+ if (outcome.policy.ok) paths.push(cloudCredentialPath());
348
+ if (outcome.ingest.ok) paths.push(ingestPath());
349
+ // Deduplicated because layout 2 consolidated both credentials into
350
+ // `credentials.toml`, so the two capabilities now name the SAME file and the
351
+ // closing note read "stored in <path> and <path>" — the same path, twice.
352
+ // They stay two entries above because the JSON override can still split them.
353
+ return [...new Set(paths)];
354
+ }