@pyric/cli 0.1.0-alpha.16 → 0.1.0-alpha.17

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 (378) hide show
  1. package/README.md +13 -9
  2. package/dist/assurance/.generated/conformance-verdicts.d.ts +80 -72
  3. package/dist/assurance/.generated/conformance-verdicts.d.ts.map +1 -1
  4. package/dist/assurance/.generated/conformance-verdicts.js +80 -72
  5. package/dist/assurance/.generated/conformance-verdicts.js.map +1 -1
  6. package/dist/cli/database-rules.d.ts.map +1 -1
  7. package/dist/cli/database-rules.js +6 -4
  8. package/dist/cli/database-rules.js.map +1 -1
  9. package/dist/cli/dev-runner.d.ts +9 -0
  10. package/dist/cli/dev-runner.d.ts.map +1 -1
  11. package/dist/cli/dev-runner.js +18 -0
  12. package/dist/cli/dev-runner.js.map +1 -1
  13. package/dist/cli/serve.d.ts.map +1 -1
  14. package/dist/cli/serve.js +61 -6
  15. package/dist/cli/serve.js.map +1 -1
  16. package/dist/cli/verify.js +2 -2
  17. package/dist/cli/verify.js.map +1 -1
  18. package/dist/conformance/.generated/can-i-use-browser.d.ts.map +1 -1
  19. package/dist/conformance/.generated/can-i-use-browser.js +1 -1
  20. package/dist/conformance/.generated/can-i-use-browser.js.map +1 -1
  21. package/dist/conformance/.generated/can-i-use.d.ts.map +1 -1
  22. package/dist/conformance/.generated/can-i-use.js +1 -1
  23. package/dist/conformance/.generated/can-i-use.js.map +1 -1
  24. package/dist/conformance/.generated/conformance-docs.d.ts.map +1 -1
  25. package/dist/conformance/.generated/conformance-docs.js +1 -1
  26. package/dist/conformance/.generated/conformance-docs.js.map +1 -1
  27. package/dist/next/client-aliases.d.ts +11 -0
  28. package/dist/next/client-aliases.d.ts.map +1 -0
  29. package/dist/next/client-aliases.js +38 -0
  30. package/dist/next/client-aliases.js.map +1 -0
  31. package/dist/next/dev-rewrites.d.ts +9 -0
  32. package/dist/next/dev-rewrites.d.ts.map +1 -0
  33. package/dist/next/dev-rewrites.js +53 -0
  34. package/dist/next/dev-rewrites.js.map +1 -0
  35. package/dist/next/guard.d.ts +15 -0
  36. package/dist/next/guard.d.ts.map +1 -0
  37. package/dist/next/guard.js +52 -0
  38. package/dist/next/guard.js.map +1 -0
  39. package/dist/next/index.d.ts +12 -0
  40. package/dist/next/index.d.ts.map +1 -0
  41. package/dist/next/index.js +11 -0
  42. package/dist/next/index.js.map +1 -0
  43. package/dist/next/runtime-env.d.ts +7 -0
  44. package/dist/next/runtime-env.d.ts.map +1 -0
  45. package/dist/next/runtime-env.js +13 -0
  46. package/dist/next/runtime-env.js.map +1 -0
  47. package/dist/next/server-external-packages.d.ts +10 -0
  48. package/dist/next/server-external-packages.d.ts.map +1 -0
  49. package/dist/next/server-external-packages.js +34 -0
  50. package/dist/next/server-external-packages.js.map +1 -0
  51. package/dist/next/target-url.d.ts +11 -0
  52. package/dist/next/target-url.d.ts.map +1 -0
  53. package/dist/next/target-url.js +36 -0
  54. package/dist/next/target-url.js.map +1 -0
  55. package/dist/next/turbopack-config.d.ts +9 -0
  56. package/dist/next/turbopack-config.d.ts.map +1 -0
  57. package/dist/next/turbopack-config.js +39 -0
  58. package/dist/next/turbopack-config.js.map +1 -0
  59. package/dist/next/types.d.ts +40 -0
  60. package/dist/next/types.d.ts.map +1 -0
  61. package/dist/next/types.js +5 -0
  62. package/dist/next/types.js.map +1 -0
  63. package/dist/next/webpack-config.d.ts +11 -0
  64. package/dist/next/webpack-config.d.ts.map +1 -0
  65. package/dist/next/webpack-config.js +51 -0
  66. package/dist/next/webpack-config.js.map +1 -0
  67. package/dist/next/with-pyric.d.ts +22 -0
  68. package/dist/next/with-pyric.d.ts.map +1 -0
  69. package/dist/next/with-pyric.js +49 -0
  70. package/dist/next/with-pyric.js.map +1 -0
  71. package/dist/register/app-bridge.d.ts +9 -0
  72. package/dist/register/app-bridge.d.ts.map +1 -0
  73. package/dist/register/app-bridge.js +56 -0
  74. package/dist/register/app-bridge.js.map +1 -0
  75. package/dist/register/hooks.d.ts.map +1 -1
  76. package/dist/register/hooks.js +6 -1
  77. package/dist/register/hooks.js.map +1 -1
  78. package/dist/register/index.js +1 -1
  79. package/dist/register/index.js.map +1 -1
  80. package/dist/register/mapping.d.ts +3 -1
  81. package/dist/register/mapping.d.ts.map +1 -1
  82. package/dist/register/mapping.js +41 -5
  83. package/dist/register/mapping.js.map +1 -1
  84. package/dist/rtdb/rules-json.d.ts +12 -0
  85. package/dist/rtdb/rules-json.d.ts.map +1 -1
  86. package/dist/rtdb/rules-json.js +98 -0
  87. package/dist/rtdb/rules-json.js.map +1 -1
  88. package/dist/serve/bundler.d.ts.map +1 -1
  89. package/dist/serve/bundler.js +2 -0
  90. package/dist/serve/bundler.js.map +1 -1
  91. package/dist/serve/discovery.d.ts +4 -4
  92. package/dist/serve/discovery.d.ts.map +1 -1
  93. package/dist/serve/discovery.js +59 -38
  94. package/dist/serve/discovery.js.map +1 -1
  95. package/dist/serve/entries/app-ai-passthrough.d.ts +8 -0
  96. package/dist/serve/entries/app-ai-passthrough.d.ts.map +1 -0
  97. package/dist/serve/entries/app-ai-passthrough.js +59 -0
  98. package/dist/serve/entries/app-ai-passthrough.js.map +1 -0
  99. package/dist/serve/entries/auth-helper-core.js +9 -7
  100. package/dist/serve/entries/auth-helper-core.js.map +1 -1
  101. package/dist/serve/entries/auth.d.ts +1 -0
  102. package/dist/serve/entries/auth.d.ts.map +1 -1
  103. package/dist/serve/entries/auth.js +1 -0
  104. package/dist/serve/entries/auth.js.map +1 -1
  105. package/dist/serve/entries/bridge-url.d.ts.map +1 -1
  106. package/dist/serve/entries/bridge-url.js +7 -2
  107. package/dist/serve/entries/bridge-url.js.map +1 -1
  108. package/dist/serve/entries/database.d.ts +1 -0
  109. package/dist/serve/entries/database.d.ts.map +1 -1
  110. package/dist/serve/entries/database.js +1 -0
  111. package/dist/serve/entries/database.js.map +1 -1
  112. package/dist/serve/entries/firestore.d.ts +1 -0
  113. package/dist/serve/entries/firestore.d.ts.map +1 -1
  114. package/dist/serve/entries/firestore.js +1 -0
  115. package/dist/serve/entries/firestore.js.map +1 -1
  116. package/dist/serve/entries/init.d.ts.map +1 -1
  117. package/dist/serve/entries/init.js +4 -2
  118. package/dist/serve/entries/init.js.map +1 -1
  119. package/dist/serve/entries/runtime.js +23 -0
  120. package/dist/serve/entries/runtime.js.map +1 -1
  121. package/dist/serve/entries/storage.d.ts +2 -0
  122. package/dist/serve/entries/storage.d.ts.map +1 -1
  123. package/dist/serve/entries/storage.js +9 -2
  124. package/dist/serve/entries/storage.js.map +1 -1
  125. package/dist/serve/html-injection.d.ts +3 -1
  126. package/dist/serve/html-injection.d.ts.map +1 -1
  127. package/dist/serve/html-injection.js +27 -1
  128. package/dist/serve/html-injection.js.map +1 -1
  129. package/dist/serve/rules.js +2 -2
  130. package/dist/serve/rules.js.map +1 -1
  131. package/dist/serve/runtime/chip-config.d.ts +1 -1
  132. package/dist/serve/runtime/chip-config.d.ts.map +1 -1
  133. package/dist/serve/runtime/chip-config.js +16 -8
  134. package/dist/serve/runtime/chip-config.js.map +1 -1
  135. package/dist/serve/sandbox-session.d.ts +1 -0
  136. package/dist/serve/sandbox-session.d.ts.map +1 -1
  137. package/dist/serve/sandbox-session.js +30 -2
  138. package/dist/serve/sandbox-session.js.map +1 -1
  139. package/dist/serve/site-ui/_astro/_studio_.B6b_G1ev.css +1 -0
  140. package/dist/serve/site-ui/_astro/app.bnmVTkIY.js +11 -0
  141. package/dist/serve/site-ui/_astro/app.t6u-adB_.js +1 -0
  142. package/dist/serve/site-ui/_astro/{chess-showcase.CnoxIle5.js → chess-showcase.kC8dXLKY.js} +1 -1
  143. package/dist/serve/site-ui/_astro/{example-runtime.R1d96L6-.js → example-runtime.D79PnoSk.js} +1 -1
  144. package/dist/serve/site-ui/_astro/index.DzVde04M.js +1 -0
  145. package/dist/serve/site-ui/_astro/reads.BYBRLbsE.js +1 -0
  146. package/dist/serve/site-ui/_astro/sandbox-controls.C9Aaazt8.js +1252 -0
  147. package/dist/serve/site-ui/_astro/{seed.EyI3VYEu.js → seed.DANAIyRw.js} +1 -1
  148. package/dist/serve/site-ui/auth/index.html +2 -2
  149. package/dist/serve/site-ui/docs/_rhythm/index.html +1 -1
  150. package/dist/serve/site-ui/docs/agent/set-up-your-agent/index.html +1 -1
  151. package/dist/serve/site-ui/docs/agent/watch-and-review/index.html +1 -1
  152. package/dist/serve/site-ui/docs/agent/work-with-an-agent/index.html +1 -1
  153. package/dist/serve/site-ui/docs/ai-compat/index.html +85 -85
  154. package/dist/serve/site-ui/docs/ai-compat.md +84 -84
  155. package/dist/serve/site-ui/docs/api-reference/index.html +3 -1
  156. package/dist/serve/site-ui/docs/api-reference.md +2 -0
  157. package/dist/serve/site-ui/docs/app-compat/index.html +28 -28
  158. package/dist/serve/site-ui/docs/app-compat.md +27 -27
  159. package/dist/serve/site-ui/docs/auth-compat/index.html +122 -122
  160. package/dist/serve/site-ui/docs/auth-compat.md +121 -121
  161. package/dist/serve/site-ui/docs/build/ai-logic/index.html +1 -1
  162. package/dist/serve/site-ui/docs/build/authentication/index.html +1 -1
  163. package/dist/serve/site-ui/docs/build/cloud-firestore/index.html +1 -1
  164. package/dist/serve/site-ui/docs/build/cloud-messaging/index.html +1 -1
  165. package/dist/serve/site-ui/docs/build/cloud-storage/index.html +1 -1
  166. package/dist/serve/site-ui/docs/build/realtime-database/index.html +1 -1
  167. package/dist/serve/site-ui/docs/conformance-scores/index.html +4 -4
  168. package/dist/serve/site-ui/docs/conformance-scores.md +3 -3
  169. package/dist/serve/site-ui/docs/create-pyric-reference-api/index.html +6 -6
  170. package/dist/serve/site-ui/docs/create-pyric-reference-api.md +5 -5
  171. package/dist/serve/site-ui/docs/database-compat/index.html +200 -448
  172. package/dist/serve/site-ui/docs/database-compat.md +198 -461
  173. package/dist/serve/site-ui/docs/examples/chess/index.html +2 -2
  174. package/dist/serve/site-ui/docs/examples/index.html +1 -1
  175. package/dist/serve/site-ui/docs/firestore-compat/index.html +186 -195
  176. package/dist/serve/site-ui/docs/firestore-compat.md +184 -195
  177. package/dist/serve/site-ui/docs/functions-rtdb-compat/index.html +15 -15
  178. package/dist/serve/site-ui/docs/functions-rtdb-compat.md +14 -14
  179. package/dist/serve/site-ui/docs/get-started/how-the-swap-works/index.html +1 -1
  180. package/dist/serve/site-ui/docs/get-started/nextjs/index.html +57 -0
  181. package/dist/serve/site-ui/docs/get-started/nextjs.md +86 -0
  182. package/dist/serve/site-ui/docs/get-started/start-building/index.html +25 -8
  183. package/dist/serve/site-ui/docs/get-started/start-building.md +34 -5
  184. package/dist/serve/site-ui/docs/get-started/vite/index.html +26 -0
  185. package/dist/serve/site-ui/docs/get-started/vite.md +45 -0
  186. package/dist/serve/site-ui/docs/index.json +668 -103
  187. package/dist/serve/site-ui/docs/messaging-compat/index.html +56 -56
  188. package/dist/serve/site-ui/docs/messaging-compat.md +55 -55
  189. package/dist/serve/site-ui/docs/observe/resolve-runtime-status/index.html +1 -1
  190. package/dist/serve/site-ui/docs/observe/see-whats-happening/index.html +1 -1
  191. package/dist/serve/site-ui/docs/observe/shape-your-data/index.html +1 -1
  192. package/dist/serve/site-ui/docs/overview/index.html +1 -1
  193. package/dist/serve/site-ui/docs/pyric-admin-app-reference-api/index.html +39 -13
  194. package/dist/serve/site-ui/docs/pyric-admin-app-reference-api.md +28 -2
  195. package/dist/serve/site-ui/docs/pyric-admin-auth-reference-api/index.html +1 -1
  196. package/dist/serve/site-ui/docs/pyric-admin-database-reference-api/index.html +38 -6
  197. package/dist/serve/site-ui/docs/pyric-admin-database-reference-api.md +43 -0
  198. package/dist/serve/site-ui/docs/pyric-admin-firestore-reference-api/index.html +9 -1
  199. package/dist/serve/site-ui/docs/pyric-admin-firestore-reference-api.md +8 -0
  200. package/dist/serve/site-ui/docs/pyric-admin-messaging-reference-api/index.html +1 -1
  201. package/dist/serve/site-ui/docs/pyric-admin-storage-reference-api/index.html +27 -4
  202. package/dist/serve/site-ui/docs/pyric-admin-storage-reference-api.md +23 -0
  203. package/dist/serve/site-ui/docs/pyric-ai-reference-api/index.html +1 -1
  204. package/dist/serve/site-ui/docs/pyric-ai-scripting-reference-api/index.html +1 -1
  205. package/dist/serve/site-ui/docs/pyric-app-reference-api/index.html +1 -1
  206. package/dist/serve/site-ui/docs/pyric-auth-reference-api/index.html +1 -1
  207. package/dist/serve/site-ui/docs/pyric-cli-assurance-browser-reference-api/index.html +1 -1
  208. package/dist/serve/site-ui/docs/pyric-cli-assurance-reference-api/index.html +1 -1
  209. package/dist/serve/site-ui/docs/pyric-cli-bridge-client-reference-api/index.html +1 -1
  210. package/dist/serve/site-ui/docs/pyric-cli-bridge-reference-api/index.html +1 -1
  211. package/dist/serve/site-ui/docs/pyric-cli-conformance-browser-reference-api/index.html +1 -1
  212. package/dist/serve/site-ui/docs/pyric-cli-conformance-docs-reference-api/index.html +1 -1
  213. package/dist/serve/site-ui/docs/pyric-cli-conformance-reference-api/index.html +1 -1
  214. package/dist/serve/site-ui/docs/pyric-cli-credentials-node-reference-api/index.html +1 -1
  215. package/dist/serve/site-ui/docs/pyric-cli-discover-reference-api/index.html +1 -1
  216. package/dist/serve/site-ui/docs/pyric-cli-next-reference-api/index.html +123 -0
  217. package/dist/serve/site-ui/docs/pyric-cli-next-reference-api.md +99 -0
  218. package/dist/serve/site-ui/docs/pyric-cli-register-app-bridge-reference-api/index.html +127 -0
  219. package/dist/serve/site-ui/docs/pyric-cli-register-app-bridge-reference-api.md +174 -0
  220. package/dist/serve/site-ui/docs/pyric-cli-register-reference-api/index.html +1 -1
  221. package/dist/serve/site-ui/docs/pyric-cli-remote-reference-api/index.html +1 -1
  222. package/dist/serve/site-ui/docs/pyric-cli-serve-worker-reference-api/index.html +570 -326
  223. package/dist/serve/site-ui/docs/pyric-cli-serve-worker-reference-api.md +198 -6
  224. package/dist/serve/site-ui/docs/pyric-cli-verify-reference-api/index.html +1 -1
  225. package/dist/serve/site-ui/docs/pyric-cli-vite-reference-api/index.html +1 -1
  226. package/dist/serve/site-ui/docs/pyric-database-reference-api/index.html +1 -1
  227. package/dist/serve/site-ui/docs/pyric-firestore-reference-api/index.html +2971 -627
  228. package/dist/serve/site-ui/docs/pyric-firestore-reference-api.md +2873 -517
  229. package/dist/serve/site-ui/docs/pyric-messaging-reference-api/index.html +1 -1
  230. package/dist/serve/site-ui/docs/pyric-messaging-sw-reference-api/index.html +1 -1
  231. package/dist/serve/site-ui/docs/pyric-rules-reference-api/index.html +43 -3
  232. package/dist/serve/site-ui/docs/pyric-rules-reference-api.md +8 -0
  233. package/dist/serve/site-ui/docs/pyric-sandbox-database-reference-api/index.html +26 -2
  234. package/dist/serve/site-ui/docs/pyric-sandbox-database-reference-api.md +24 -0
  235. package/dist/serve/site-ui/docs/pyric-sandbox-firestore-reference-api/index.html +1 -1
  236. package/dist/serve/site-ui/docs/pyric-sandbox-reference-api/index.html +77 -9
  237. package/dist/serve/site-ui/docs/pyric-sandbox-reference-api.md +28 -13
  238. package/dist/serve/site-ui/docs/pyric-storage-reference-api/index.html +240 -63
  239. package/dist/serve/site-ui/docs/pyric-storage-reference-api.md +164 -5
  240. package/dist/serve/site-ui/docs/pyric-ui-agents-reference-api/index.html +1 -1
  241. package/dist/serve/site-ui/docs/pyric-ui-auth-hooks-reference-api/index.html +1 -1
  242. package/dist/serve/site-ui/docs/pyric-ui-auth-reference-api/index.html +1 -1
  243. package/dist/serve/site-ui/docs/pyric-ui-events-hooks-reference-api/index.html +1 -1
  244. package/dist/serve/site-ui/docs/pyric-ui-events-reference-api/index.html +1 -1
  245. package/dist/serve/site-ui/docs/pyric-ui-firestore-hooks-reference-api/index.html +1 -1
  246. package/dist/serve/site-ui/docs/pyric-ui-firestore-reference-api/index.html +1 -1
  247. package/dist/serve/site-ui/docs/pyric-ui-primitives-reference-api/index.html +1 -1
  248. package/dist/serve/site-ui/docs/pyric-ui-rtdb-reference-api/index.html +1 -1
  249. package/dist/serve/site-ui/docs/pyric-ui-rules-hooks-reference-api/index.html +1 -1
  250. package/dist/serve/site-ui/docs/pyric-ui-rules-reference-api/index.html +1 -1
  251. package/dist/serve/site-ui/docs/pyric-ui-storage-hooks-reference-api/index.html +1 -1
  252. package/dist/serve/site-ui/docs/pyric-ui-storage-reference-api/index.html +2 -1
  253. package/dist/serve/site-ui/docs/pyric-ui-storage-reference-api.md +1 -0
  254. package/dist/serve/site-ui/docs/pyric-ui-traffic-hooks-reference-api/index.html +1 -1
  255. package/dist/serve/site-ui/docs/pyric-ui-traffic-reference-api/index.html +1 -1
  256. package/dist/serve/site-ui/docs/rules-compat/index.html +87 -79
  257. package/dist/serve/site-ui/docs/rules-compat.md +86 -78
  258. package/dist/serve/site-ui/docs/secure/audit-your-rules/index.html +1 -1
  259. package/dist/serve/site-ui/docs/secure/firestore-rules-limits/index.html +1 -1
  260. package/dist/serve/site-ui/docs/secure/read-a-denial/index.html +1 -1
  261. package/dist/serve/site-ui/docs/secure/rtdb-rules-in-typescript/index.html +1 -1
  262. package/dist/serve/site-ui/docs/secure/rules-standard-library/index.html +1 -1
  263. package/dist/serve/site-ui/docs/secure/secure-it-with-rules/index.html +1 -1
  264. package/dist/serve/site-ui/docs/secure/simulate-and-lint/index.html +1 -1
  265. package/dist/serve/site-ui/docs/secure/write-a-rules-test-suite/index.html +1 -1
  266. package/dist/serve/site-ui/docs/ship/ship-to-production/index.html +1 -1
  267. package/dist/serve/site-ui/docs/ship/test-in-node/index.html +1 -1
  268. package/dist/serve/site-ui/docs/storage-compat/index.html +119 -125
  269. package/dist/serve/site-ui/docs/storage-compat.md +118 -124
  270. package/dist/serve/site-ui/docs/trust/how-we-know-it-matches-firebase/index.html +1 -1
  271. package/dist/serve/site-ui/docs/trust/rules-standard-library/index.html +1 -1
  272. package/dist/serve/site-ui/docs/trust/storage-rules-stdlib-research/index.html +1 -1
  273. package/dist/serve/site-ui/docs/trust/versioning-and-compatibility/index.html +1 -1
  274. package/dist/serve/site-ui/docs/tutorial/index.html +1 -1
  275. package/dist/serve/site-ui/examples/chess/index.html +1 -1
  276. package/dist/serve/site-ui/examples/firestore-first-write/index.html +1 -1
  277. package/dist/serve/site-ui/firestore/index.html +2 -2
  278. package/dist/serve/site-ui/index.html +2 -2
  279. package/dist/serve/site-ui/llms.txt +6 -2
  280. package/dist/serve/site-ui/rtdb/index.html +2 -2
  281. package/dist/serve/site-ui/settings/index.html +2 -2
  282. package/dist/serve/site-ui/storage/index.html +2 -2
  283. package/dist/serve/site-ui/traffic/index.html +2 -2
  284. package/dist/serve/vite-ai-config.d.ts +4 -1
  285. package/dist/serve/vite-ai-config.d.ts.map +1 -1
  286. package/dist/serve/vite-ai-config.js +83 -19
  287. package/dist/serve/vite-ai-config.js.map +1 -1
  288. package/dist/serve/vite-generation-rules-watch.d.ts.map +1 -1
  289. package/dist/serve/vite-generation-rules-watch.js +61 -14
  290. package/dist/serve/vite-generation-rules-watch.js.map +1 -1
  291. package/dist/serve/vite-module-swap.d.ts +4 -1
  292. package/dist/serve/vite-module-swap.d.ts.map +1 -1
  293. package/dist/serve/vite-module-swap.js +106 -21
  294. package/dist/serve/vite-module-swap.js.map +1 -1
  295. package/dist/serve/vite-plugin.d.ts.map +1 -1
  296. package/dist/serve/vite-plugin.js +45 -5
  297. package/dist/serve/vite-plugin.js.map +1 -1
  298. package/dist/serve/vite-sandbox-generation.js +1 -1
  299. package/dist/serve/vite-sandbox-generation.js.map +1 -1
  300. package/dist/serve/worker/client/resumable.d.ts +30 -0
  301. package/dist/serve/worker/client/resumable.d.ts.map +1 -0
  302. package/dist/serve/worker/client/resumable.js +416 -0
  303. package/dist/serve/worker/client/resumable.js.map +1 -0
  304. package/dist/serve/worker/client/rtdb-references.d.ts.map +1 -1
  305. package/dist/serve/worker/client/rtdb-references.js +4 -1
  306. package/dist/serve/worker/client/rtdb-references.js.map +1 -1
  307. package/dist/serve/worker/client/storage.d.ts +16 -2
  308. package/dist/serve/worker/client/storage.d.ts.map +1 -1
  309. package/dist/serve/worker/client/storage.js +57 -6
  310. package/dist/serve/worker/client/storage.js.map +1 -1
  311. package/dist/serve/worker/host/rules.d.ts.map +1 -1
  312. package/dist/serve/worker/host/rules.js +2 -1
  313. package/dist/serve/worker/host/rules.js.map +1 -1
  314. package/dist/serve/worker/index.d.ts +1 -1
  315. package/dist/serve/worker/index.d.ts.map +1 -1
  316. package/dist/serve/worker/index.js +1 -1
  317. package/dist/serve/worker/index.js.map +1 -1
  318. package/dist/serve/worker/serve-init.d.ts.map +1 -1
  319. package/dist/serve/worker/serve-init.js +31 -0
  320. package/dist/serve/worker/serve-init.js.map +1 -1
  321. package/package.json +15 -4
  322. package/src/assurance/.generated/conformance-verdicts.ts +80 -72
  323. package/src/cli/cli.test.ts +14 -0
  324. package/src/cli/database-rules.ts +6 -4
  325. package/src/cli/dev-runner.ts +21 -0
  326. package/src/cli/serve.ts +62 -5
  327. package/src/cli/verify.ts +2 -2
  328. package/src/conformance/.generated/can-i-use-browser.ts +1 -1
  329. package/src/conformance/.generated/can-i-use.ts +1 -1
  330. package/src/conformance/.generated/conformance-docs.ts +1 -1
  331. package/src/next/client-aliases.ts +39 -0
  332. package/src/next/dev-rewrites.ts +77 -0
  333. package/src/next/guard.ts +61 -0
  334. package/src/next/index.ts +16 -0
  335. package/src/next/runtime-env.ts +18 -0
  336. package/src/next/server-external-packages.ts +43 -0
  337. package/src/next/target-url.ts +46 -0
  338. package/src/next/turbopack-config.ts +54 -0
  339. package/src/next/types.ts +47 -0
  340. package/src/next/webpack-config.ts +71 -0
  341. package/src/next/with-pyric.ts +58 -0
  342. package/src/register/app-bridge.ts +79 -0
  343. package/src/register/hooks.ts +6 -1
  344. package/src/register/index.ts +1 -1
  345. package/src/register/mapping.ts +50 -4
  346. package/src/rtdb/rules-json.ts +110 -0
  347. package/src/serve/bundler.ts +2 -0
  348. package/src/serve/discovery.ts +65 -44
  349. package/src/serve/entries/app-ai-passthrough.ts +83 -0
  350. package/src/serve/entries/auth-helper-core.ts +9 -7
  351. package/src/serve/entries/auth.ts +1 -0
  352. package/src/serve/entries/bridge-url.ts +9 -2
  353. package/src/serve/entries/database.ts +1 -0
  354. package/src/serve/entries/firestore.ts +1 -0
  355. package/src/serve/entries/init.ts +5 -2
  356. package/src/serve/entries/runtime.ts +25 -0
  357. package/src/serve/entries/storage.ts +12 -1
  358. package/src/serve/html-injection.ts +26 -1
  359. package/src/serve/rules.ts +2 -2
  360. package/src/serve/runtime/chip-config.ts +19 -6
  361. package/src/serve/sandbox-session.ts +31 -2
  362. package/src/serve/vite-ai-config.ts +86 -19
  363. package/src/serve/vite-generation-rules-watch.ts +67 -15
  364. package/src/serve/vite-module-swap.ts +121 -21
  365. package/src/serve/vite-plugin.ts +44 -6
  366. package/src/serve/vite-sandbox-generation.ts +1 -1
  367. package/src/serve/worker/client/resumable.ts +506 -0
  368. package/src/serve/worker/client/rtdb-references.ts +4 -1
  369. package/src/serve/worker/client/storage.ts +77 -7
  370. package/src/serve/worker/host/rules.ts +2 -1
  371. package/src/serve/worker/index.ts +4 -0
  372. package/src/serve/worker/serve-init.ts +30 -0
  373. package/dist/serve/site-ui/_astro/_studio_.BtYpqe1A.css +0 -1
  374. package/dist/serve/site-ui/_astro/app.4HeLP_FA.js +0 -109
  375. package/dist/serve/site-ui/_astro/app.BgSnCR5G.js +0 -1
  376. package/dist/serve/site-ui/_astro/index.BJiOemMX.js +0 -1
  377. package/dist/serve/site-ui/_astro/reads.BrKNdKAa.js +0 -1
  378. package/dist/serve/site-ui/_astro/sandbox-controls.BTb3EbQp.js +0 -1153
@@ -1,5 +1,5 @@
1
1
  <!DOCTYPE html><html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>pyric messaging compatibility matrix · Pyric Studio</title><link rel="icon" type="image/svg+xml" href="/__pyric/ui/pyric-logo.svg"><link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500;700&display=swap" rel="stylesheet"><link rel="stylesheet" href="/__pyric/ui/_astro/_slug_.CXh9yTP1.css">
2
- <link rel="stylesheet" href="/__pyric/ui/_astro/_slug_.BoKXYrnu.css"></head> <body> <header class="studio__bar" data-astro-cid-mw7aashj> <div class="studio__bar-inner" data-astro-cid-mw7aashj> <a class="studio__brand" href="/__pyric/ui/" aria-label="Pyric Studio" data-astro-cid-mw7aashj>Pyric</a> <nav class="studio__nav" aria-label="Studio tabs" data-astro-cid-mw7aashj> <a class="studio__nav-tab" href="/__pyric/ui/" data-astro-cid-mw7aashj> Home </a><a class="studio__nav-tab" href="/__pyric/ui/firestore" data-astro-cid-mw7aashj> Firestore </a><a class="studio__nav-tab" href="/__pyric/ui/auth" data-astro-cid-mw7aashj> Auth </a><a class="studio__nav-tab" href="/__pyric/ui/rtdb" data-astro-cid-mw7aashj> RTDB </a><a class="studio__nav-tab" href="/__pyric/ui/storage" data-astro-cid-mw7aashj> Storage </a><a class="studio__nav-tab" href="/__pyric/ui/traffic" data-astro-cid-mw7aashj> Traffic </a><a class="studio__nav-tab" href="/__pyric/ui/settings" data-astro-cid-mw7aashj> Settings </a><a class="studio__nav-tab" href="/__pyric/ui/docs" aria-current="page" data-astro-cid-mw7aashj> Docs </a> </nav> </div> </header> <div class="docs-shell" data-astro-cid-mw7aashj> <details class="docs-nav-drawer" data-astro-cid-mw7aashj> <summary data-astro-cid-mw7aashj>Navigate</summary> <nav class="docs-nav" aria-label="Documentation"> <div class="docs-search" data-index-url="/__pyric/ui/docs/index.json"> <div class="docs-search-field"> <svg class="docs-search-icon" viewBox="0 0 16 16" width="14" height="14" aria-hidden="true"> <path d="M11.5 11.5 15 15M13 7A6 6 0 1 1 1 7a6 6 0 0 1 12 0Z" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"></path> </svg> <input type="text" class="docs-search-input" placeholder="Search docs" aria-label="Search docs" autocomplete="off" spellcheck="false"> <kbd class="docs-search-kbd">⌘K</kbd> </div> <ul class="docs-search-results" hidden></ul> </div> <script type="module">let i=null;function d(t){return i||(i=fetch(t).then(e=>e.json())),i}function l(t,e){return t.title.toLowerCase().includes(e)||t.excerpt.toLowerCase().includes(e)?!0:t.headings.some(r=>r.text.toLowerCase().includes(e))}function u(t,e,r){if(e.innerHTML="",t.length===0){e.hidden=!1;{const n=document.createElement("li");n.className="docs-search-empty",n.textContent="No matches",e.appendChild(n)}return}e.hidden=!1;for(const n of t.slice(0,8)){const s=document.createElement("li"),c=document.createElement("a");c.href=n.path;const o=document.createElement("span");o.className="docs-search-result-title",o.textContent=n.title;const a=document.createElement("span");a.className="docs-search-result-meta",a.textContent=[n.group,n.section].filter(Boolean).join(" / "),c.append(o,a),s.appendChild(c),e.appendChild(s)}}document.querySelectorAll(".docs-search").forEach(t=>{const e=t.dataset.indexUrl,r=t.querySelector(".docs-search-input"),n=t.querySelector(".docs-search-results");r.addEventListener("input",async()=>{const s=r.value.trim().toLowerCase();if(!s){n.hidden=!0,n.innerHTML="";return}const{pages:c}=await d(e);r.value.trim().toLowerCase()===s&&u(c.filter(o=>l(o,s)),n)}),r.addEventListener("focus",()=>{d(e),n.childElementCount>0&&(n.hidden=!1)}),r.addEventListener("keydown",s=>{s.key==="Escape"&&(r.value="",n.hidden=!0,n.innerHTML="",r.blur())}),r.addEventListener("blur",()=>{window.setTimeout(()=>{n.hidden=!0},150)})});document.addEventListener("keydown",t=>{if(!(t.metaKey||t.ctrlKey)||t.key.toLowerCase()!=="k")return;const e=[...document.querySelectorAll(".docs-search-input")].find(r=>r.offsetParent!==null);e&&(t.preventDefault(),e.focus(),e.select())});</script> <details class="docs-nav-group"> <summary>Overview</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/overview/"> Overview </a> </li><li> <a href="/__pyric/ui/docs/tutorial/"> Tutorial </a> </li><li> <a href="/__pyric/ui/docs/examples/"> Examples </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Get started</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/get-started/start-building/"> Quickstart </a> </li><li> <a href="/__pyric/ui/docs/get-started/how-the-swap-works/"> How the swap works </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Build</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/build/authentication/"> Authentication </a> </li><li> <a href="/__pyric/ui/docs/build/cloud-firestore/"> Cloud Firestore </a> </li><li> <a href="/__pyric/ui/docs/build/realtime-database/"> Realtime Database </a> </li><li> <a href="/__pyric/ui/docs/build/cloud-storage/"> Cloud Storage </a> </li><li> <a href="/__pyric/ui/docs/build/cloud-messaging/"> Cloud Messaging </a> </li><li> <a href="/__pyric/ui/docs/build/ai-logic/"> AI Logic </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Secure &amp; debug</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/secure/secure-it-with-rules/"> Security Rules </a> </li><li> <a href="/__pyric/ui/docs/secure/simulate-and-lint/"> Simulate and lint before you deploy </a> </li><li> <a href="/__pyric/ui/docs/secure/write-a-rules-test-suite/"> Write a rules test suite </a> </li><li> <a href="/__pyric/ui/docs/secure/read-a-denial/"> Read a denial and understand it </a> </li><li> <a href="/__pyric/ui/docs/secure/rules-standard-library/"> The rules standard library </a> </li><li> <a href="/__pyric/ui/docs/secure/rtdb-rules-in-typescript/"> RTDB rules in TypeScript </a> </li><li> <a href="/__pyric/ui/docs/secure/firestore-rules-limits/"> Rules limits </a> </li><li> <a href="/__pyric/ui/docs/secure/audit-your-rules/"> Audit rules and data </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading"> Examples </h2> <ul> <li> <a href="/__pyric/ui/docs/examples/chess/"> Chess showcase </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Observe &amp; shape</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/observe/see-whats-happening/"> Traffic &amp; rule verdicts </a> </li><li> <a href="/__pyric/ui/docs/observe/resolve-runtime-status/"> Runtime status </a> </li><li> <a href="/__pyric/ui/docs/observe/shape-your-data/"> Seed, snapshot, replay </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Ship &amp; test</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/ship/ship-to-production/"> Ship to production </a> </li><li> <a href="/__pyric/ui/docs/ship/test-in-node/"> Test in Node </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Work with an agent</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/agent/set-up-your-agent/"> Connect an agent </a> </li><li> <a href="/__pyric/ui/docs/agent/work-with-an-agent/"> Use the MCP tools </a> </li><li> <a href="/__pyric/ui/docs/agent/watch-and-review/"> Watch in Pyric Studio </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Trust</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/trust/versioning-and-compatibility/"> Versioning and the fb tag </a> </li><li> <a href="/__pyric/ui/docs/trust/storage-rules-stdlib-research/"> Storage Rules modules: evidence and design </a> </li><li> <a href="/__pyric/ui/docs/trust/rules-standard-library/"> Rules standard library reference </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" open> <summary>Conformance</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/conformance-scores/"> Public API coverage </a> </li><li> <a href="/__pyric/ui/docs/trust/how-we-know-it-matches-firebase/"> How we know it matches Firebase </a> </li><li> <a href="/__pyric/ui/docs/app-compat/"> App </a> </li><li> <a href="/__pyric/ui/docs/ai-compat/"> AI Logic </a> </li><li> <a href="/__pyric/ui/docs/auth-compat/"> Auth </a> </li><li> <a href="/__pyric/ui/docs/firestore-compat/"> Firestore </a> </li><li> <a href="/__pyric/ui/docs/database-compat/"> Realtime Database </a> </li><li> <a href="/__pyric/ui/docs/storage-compat/"> Storage </a> </li><li> <a href="/__pyric/ui/docs/messaging-compat/" aria-current="page"> Messaging </a> </li><li> <a href="/__pyric/ui/docs/functions-rtdb-compat/"> Functions · RTDB </a> </li><li> <a href="/__pyric/ui/docs/rules-compat/"> Rules </a> </li> </ul> </div> </div> </details> <details class="docs-nav-group"> <summary>Reference</summary> <div class="docs-nav-group-body docs-nav-group-body--reference"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/api-reference/"> API reference </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">pyric</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-app-reference-api/"> pyric/app </a> </li><li> <a href="/__pyric/ui/docs/pyric-firestore-reference-api/"> pyric/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-auth-reference-api/"> pyric/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-ai-reference-api/"> pyric/ai </a> </li><li> <a href="/__pyric/ui/docs/pyric-ai-scripting-reference-api/"> pyric/ai/scripting </a> </li><li> <a href="/__pyric/ui/docs/pyric-database-reference-api/"> pyric/database </a> </li><li> <a href="/__pyric/ui/docs/pyric-storage-reference-api/"> pyric/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-messaging-reference-api/"> pyric/messaging </a> </li><li> <a href="/__pyric/ui/docs/pyric-messaging-sw-reference-api/"> pyric/messaging/sw </a> </li><li> <a href="/__pyric/ui/docs/pyric-rules-reference-api/"> pyric/rules </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-reference-api/"> pyric/sandbox </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-firestore-reference-api/"> pyric/sandbox/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-database-reference-api/"> pyric/sandbox/database </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">pyric-admin</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-admin-app-reference-api/"> pyric-admin/app </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-firestore-reference-api/"> pyric-admin/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-auth-reference-api/"> pyric-admin/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-database-reference-api/"> pyric-admin/database </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-storage-reference-api/"> pyric-admin/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-messaging-reference-api/"> pyric-admin/messaging </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">create-pyric</h2> <ul> <li> <a href="/__pyric/ui/docs/create-pyric-reference-api/"> create-pyric </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">@pyric/cli</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-cli-credentials-node-reference-api/"> @pyric/cli/credentials/node </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-verify-reference-api/"> @pyric/cli/verify </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-conformance-reference-api/"> @pyric/cli/conformance </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-conformance-browser-reference-api/"> @pyric/cli/conformance/browser </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-conformance-docs-reference-api/"> @pyric/cli/conformance/docs </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-assurance-reference-api/"> @pyric/cli/assurance </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-assurance-browser-reference-api/"> @pyric/cli/assurance/browser </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-bridge-reference-api/"> @pyric/cli/bridge </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-bridge-client-reference-api/"> @pyric/cli/bridge/client </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-discover-reference-api/"> @pyric/cli/discover </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-vite-reference-api/"> @pyric/cli/vite </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-serve-worker-reference-api/"> @pyric/cli/serve/worker </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-remote-reference-api/"> @pyric/cli/remote </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-register-reference-api/"> @pyric/cli/register </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">@pyric/ui</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-ui-auth-reference-api/"> @pyric/ui/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-auth-hooks-reference-api/"> @pyric/ui/auth/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-primitives-reference-api/"> @pyric/ui/primitives </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-firestore-reference-api/"> @pyric/ui/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-firestore-hooks-reference-api/"> @pyric/ui/firestore/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-rtdb-reference-api/"> @pyric/ui/rtdb </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-storage-reference-api/"> @pyric/ui/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-storage-hooks-reference-api/"> @pyric/ui/storage/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-traffic-reference-api/"> @pyric/ui/traffic </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-traffic-hooks-reference-api/"> @pyric/ui/traffic/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-events-reference-api/"> @pyric/ui/events </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-events-hooks-reference-api/"> @pyric/ui/events/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-agents-reference-api/"> @pyric/ui/agents </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-rules-reference-api/"> @pyric/ui/rules </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-rules-hooks-reference-api/"> @pyric/ui/rules/hooks </a> </li> </ul> </div> </div> </details> </nav> </details> <nav class="docs-nav" aria-label="Documentation"> <div class="docs-search" data-index-url="/__pyric/ui/docs/index.json"> <div class="docs-search-field"> <svg class="docs-search-icon" viewBox="0 0 16 16" width="14" height="14" aria-hidden="true"> <path d="M11.5 11.5 15 15M13 7A6 6 0 1 1 1 7a6 6 0 0 1 12 0Z" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"></path> </svg> <input type="text" class="docs-search-input" placeholder="Search docs" aria-label="Search docs" autocomplete="off" spellcheck="false"> <kbd class="docs-search-kbd">⌘K</kbd> </div> <ul class="docs-search-results" hidden></ul> </div> <details class="docs-nav-group" id="nav-group-overview"> <summary>Overview</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/overview/"> Overview </a> </li><li> <a href="/__pyric/ui/docs/tutorial/"> Tutorial </a> </li><li> <a href="/__pyric/ui/docs/examples/"> Examples </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-get-started"> <summary>Get started</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/get-started/start-building/"> Quickstart </a> </li><li> <a href="/__pyric/ui/docs/get-started/how-the-swap-works/"> How the swap works </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-build"> <summary>Build</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/build/authentication/"> Authentication </a> </li><li> <a href="/__pyric/ui/docs/build/cloud-firestore/"> Cloud Firestore </a> </li><li> <a href="/__pyric/ui/docs/build/realtime-database/"> Realtime Database </a> </li><li> <a href="/__pyric/ui/docs/build/cloud-storage/"> Cloud Storage </a> </li><li> <a href="/__pyric/ui/docs/build/cloud-messaging/"> Cloud Messaging </a> </li><li> <a href="/__pyric/ui/docs/build/ai-logic/"> AI Logic </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-secure-debug"> <summary>Secure &amp; debug</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/secure/secure-it-with-rules/"> Security Rules </a> </li><li> <a href="/__pyric/ui/docs/secure/simulate-and-lint/"> Simulate and lint before you deploy </a> </li><li> <a href="/__pyric/ui/docs/secure/write-a-rules-test-suite/"> Write a rules test suite </a> </li><li> <a href="/__pyric/ui/docs/secure/read-a-denial/"> Read a denial and understand it </a> </li><li> <a href="/__pyric/ui/docs/secure/rules-standard-library/"> The rules standard library </a> </li><li> <a href="/__pyric/ui/docs/secure/rtdb-rules-in-typescript/"> RTDB rules in TypeScript </a> </li><li> <a href="/__pyric/ui/docs/secure/firestore-rules-limits/"> Rules limits </a> </li><li> <a href="/__pyric/ui/docs/secure/audit-your-rules/"> Audit rules and data </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading" id="nav-section-secure-debug-examples"> Examples </h2> <ul> <li> <a href="/__pyric/ui/docs/examples/chess/"> Chess showcase </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-observe-shape"> <summary>Observe &amp; shape</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/observe/see-whats-happening/"> Traffic &amp; rule verdicts </a> </li><li> <a href="/__pyric/ui/docs/observe/resolve-runtime-status/"> Runtime status </a> </li><li> <a href="/__pyric/ui/docs/observe/shape-your-data/"> Seed, snapshot, replay </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-ship-test"> <summary>Ship &amp; test</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/ship/ship-to-production/"> Ship to production </a> </li><li> <a href="/__pyric/ui/docs/ship/test-in-node/"> Test in Node </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-work-with-an-agent"> <summary>Work with an agent</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/agent/set-up-your-agent/"> Connect an agent </a> </li><li> <a href="/__pyric/ui/docs/agent/work-with-an-agent/"> Use the MCP tools </a> </li><li> <a href="/__pyric/ui/docs/agent/watch-and-review/"> Watch in Pyric Studio </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-trust"> <summary>Trust</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/trust/versioning-and-compatibility/"> Versioning and the fb tag </a> </li><li> <a href="/__pyric/ui/docs/trust/storage-rules-stdlib-research/"> Storage Rules modules: evidence and design </a> </li><li> <a href="/__pyric/ui/docs/trust/rules-standard-library/"> Rules standard library reference </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-conformance" open> <summary>Conformance</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/conformance-scores/"> Public API coverage </a> </li><li> <a href="/__pyric/ui/docs/trust/how-we-know-it-matches-firebase/"> How we know it matches Firebase </a> </li><li> <a href="/__pyric/ui/docs/app-compat/"> App </a> </li><li> <a href="/__pyric/ui/docs/ai-compat/"> AI Logic </a> </li><li> <a href="/__pyric/ui/docs/auth-compat/"> Auth </a> </li><li> <a href="/__pyric/ui/docs/firestore-compat/"> Firestore </a> </li><li> <a href="/__pyric/ui/docs/database-compat/"> Realtime Database </a> </li><li> <a href="/__pyric/ui/docs/storage-compat/"> Storage </a> </li><li> <a href="/__pyric/ui/docs/messaging-compat/" aria-current="page"> Messaging </a> </li><li> <a href="/__pyric/ui/docs/functions-rtdb-compat/"> Functions · RTDB </a> </li><li> <a href="/__pyric/ui/docs/rules-compat/"> Rules </a> </li> </ul> </div> </div> </details> <details class="docs-nav-group" id="nav-group-reference"> <summary>Reference</summary> <div class="docs-nav-group-body docs-nav-group-body--reference"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/api-reference/"> API reference </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">pyric</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-app-reference-api/"> pyric/app </a> </li><li> <a href="/__pyric/ui/docs/pyric-firestore-reference-api/"> pyric/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-auth-reference-api/"> pyric/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-ai-reference-api/"> pyric/ai </a> </li><li> <a href="/__pyric/ui/docs/pyric-ai-scripting-reference-api/"> pyric/ai/scripting </a> </li><li> <a href="/__pyric/ui/docs/pyric-database-reference-api/"> pyric/database </a> </li><li> <a href="/__pyric/ui/docs/pyric-storage-reference-api/"> pyric/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-messaging-reference-api/"> pyric/messaging </a> </li><li> <a href="/__pyric/ui/docs/pyric-messaging-sw-reference-api/"> pyric/messaging/sw </a> </li><li> <a href="/__pyric/ui/docs/pyric-rules-reference-api/"> pyric/rules </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-reference-api/"> pyric/sandbox </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-firestore-reference-api/"> pyric/sandbox/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-database-reference-api/"> pyric/sandbox/database </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">pyric-admin</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-admin-app-reference-api/"> pyric-admin/app </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-firestore-reference-api/"> pyric-admin/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-auth-reference-api/"> pyric-admin/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-database-reference-api/"> pyric-admin/database </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-storage-reference-api/"> pyric-admin/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-messaging-reference-api/"> pyric-admin/messaging </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">create-pyric</h2> <ul> <li> <a href="/__pyric/ui/docs/create-pyric-reference-api/"> create-pyric </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">@pyric/cli</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-cli-credentials-node-reference-api/"> @pyric/cli/credentials/node </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-verify-reference-api/"> @pyric/cli/verify </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-conformance-reference-api/"> @pyric/cli/conformance </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-conformance-browser-reference-api/"> @pyric/cli/conformance/browser </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-conformance-docs-reference-api/"> @pyric/cli/conformance/docs </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-assurance-reference-api/"> @pyric/cli/assurance </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-assurance-browser-reference-api/"> @pyric/cli/assurance/browser </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-bridge-reference-api/"> @pyric/cli/bridge </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-bridge-client-reference-api/"> @pyric/cli/bridge/client </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-discover-reference-api/"> @pyric/cli/discover </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-vite-reference-api/"> @pyric/cli/vite </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-serve-worker-reference-api/"> @pyric/cli/serve/worker </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-remote-reference-api/"> @pyric/cli/remote </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-register-reference-api/"> @pyric/cli/register </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">@pyric/ui</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-ui-auth-reference-api/"> @pyric/ui/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-auth-hooks-reference-api/"> @pyric/ui/auth/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-primitives-reference-api/"> @pyric/ui/primitives </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-firestore-reference-api/"> @pyric/ui/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-firestore-hooks-reference-api/"> @pyric/ui/firestore/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-rtdb-reference-api/"> @pyric/ui/rtdb </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-storage-reference-api/"> @pyric/ui/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-storage-hooks-reference-api/"> @pyric/ui/storage/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-traffic-reference-api/"> @pyric/ui/traffic </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-traffic-hooks-reference-api/"> @pyric/ui/traffic/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-events-reference-api/"> @pyric/ui/events </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-events-hooks-reference-api/"> @pyric/ui/events/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-agents-reference-api/"> @pyric/ui/agents </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-rules-reference-api/"> @pyric/ui/rules </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-rules-hooks-reference-api/"> @pyric/ui/rules/hooks </a> </li> </ul> </div> </div> </details> </nav> <main class="doc-main" data-astro-cid-mw7aashj> <nav class="docs-breadcrumbs" aria-label="Breadcrumb"> <ol> <li> <a href="/__pyric/ui/docs/conformance-scores/">Conformance</a> </li><li> <span class="docs-breadcrumbs-sep" aria-hidden="true">/</span> <span aria-current="page">Messaging</span> </li> </ol> </nav> <article class="prose" data-astro-cid-mw7aashj> <!-- Generated from the conformance model (registry rows + surface contracts). Do not edit by hand; run bun run compat:generate. -->
2
+ <link rel="stylesheet" href="/__pyric/ui/_astro/_slug_.BoKXYrnu.css"></head> <body> <header class="studio__bar" data-astro-cid-mw7aashj> <div class="studio__bar-inner" data-astro-cid-mw7aashj> <a class="studio__brand" href="/__pyric/ui/" aria-label="Pyric Studio" data-astro-cid-mw7aashj>Pyric</a> <nav class="studio__nav" aria-label="Studio tabs" data-astro-cid-mw7aashj> <a class="studio__nav-tab" href="/__pyric/ui/" data-astro-cid-mw7aashj> Home </a><a class="studio__nav-tab" href="/__pyric/ui/firestore" data-astro-cid-mw7aashj> Firestore </a><a class="studio__nav-tab" href="/__pyric/ui/auth" data-astro-cid-mw7aashj> Auth </a><a class="studio__nav-tab" href="/__pyric/ui/rtdb" data-astro-cid-mw7aashj> RTDB </a><a class="studio__nav-tab" href="/__pyric/ui/storage" data-astro-cid-mw7aashj> Storage </a><a class="studio__nav-tab" href="/__pyric/ui/traffic" data-astro-cid-mw7aashj> Traffic </a><a class="studio__nav-tab" href="/__pyric/ui/settings" data-astro-cid-mw7aashj> Settings </a><a class="studio__nav-tab" href="/__pyric/ui/docs" aria-current="page" data-astro-cid-mw7aashj> Docs </a> </nav> </div> </header> <div class="docs-shell" data-astro-cid-mw7aashj> <details class="docs-nav-drawer" data-astro-cid-mw7aashj> <summary data-astro-cid-mw7aashj>Navigate</summary> <nav class="docs-nav" aria-label="Documentation"> <div class="docs-search" data-index-url="/__pyric/ui/docs/index.json"> <div class="docs-search-field"> <svg class="docs-search-icon" viewBox="0 0 16 16" width="14" height="14" aria-hidden="true"> <path d="M11.5 11.5 15 15M13 7A6 6 0 1 1 1 7a6 6 0 0 1 12 0Z" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"></path> </svg> <input type="text" class="docs-search-input" placeholder="Search docs" aria-label="Search docs" autocomplete="off" spellcheck="false"> <kbd class="docs-search-kbd">⌘K</kbd> </div> <ul class="docs-search-results" hidden></ul> </div> <script type="module">let i=null;function d(t){return i||(i=fetch(t).then(e=>e.json())),i}function l(t,e){return t.title.toLowerCase().includes(e)||t.excerpt.toLowerCase().includes(e)?!0:t.headings.some(r=>r.text.toLowerCase().includes(e))}function u(t,e,r){if(e.innerHTML="",t.length===0){e.hidden=!1;{const n=document.createElement("li");n.className="docs-search-empty",n.textContent="No matches",e.appendChild(n)}return}e.hidden=!1;for(const n of t.slice(0,8)){const s=document.createElement("li"),c=document.createElement("a");c.href=n.path;const o=document.createElement("span");o.className="docs-search-result-title",o.textContent=n.title;const a=document.createElement("span");a.className="docs-search-result-meta",a.textContent=[n.group,n.section].filter(Boolean).join(" / "),c.append(o,a),s.appendChild(c),e.appendChild(s)}}document.querySelectorAll(".docs-search").forEach(t=>{const e=t.dataset.indexUrl,r=t.querySelector(".docs-search-input"),n=t.querySelector(".docs-search-results");r.addEventListener("input",async()=>{const s=r.value.trim().toLowerCase();if(!s){n.hidden=!0,n.innerHTML="";return}const{pages:c}=await d(e);r.value.trim().toLowerCase()===s&&u(c.filter(o=>l(o,s)),n)}),r.addEventListener("focus",()=>{d(e),n.childElementCount>0&&(n.hidden=!1)}),r.addEventListener("keydown",s=>{s.key==="Escape"&&(r.value="",n.hidden=!0,n.innerHTML="",r.blur())}),r.addEventListener("blur",()=>{window.setTimeout(()=>{n.hidden=!0},150)})});document.addEventListener("keydown",t=>{if(!(t.metaKey||t.ctrlKey)||t.key.toLowerCase()!=="k")return;const e=[...document.querySelectorAll(".docs-search-input")].find(r=>r.offsetParent!==null);e&&(t.preventDefault(),e.focus(),e.select())});</script> <details class="docs-nav-group"> <summary>Overview</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/overview/"> Overview </a> </li><li> <a href="/__pyric/ui/docs/tutorial/"> Tutorial </a> </li><li> <a href="/__pyric/ui/docs/examples/"> Examples </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Get started</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/get-started/start-building/"> Quickstart </a> </li><li> <a href="/__pyric/ui/docs/get-started/vite/"> Vite </a> </li><li> <a href="/__pyric/ui/docs/get-started/nextjs/"> Next.js </a> </li><li> <a href="/__pyric/ui/docs/get-started/how-the-swap-works/"> How the swap works </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Build</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/build/authentication/"> Authentication </a> </li><li> <a href="/__pyric/ui/docs/build/cloud-firestore/"> Cloud Firestore </a> </li><li> <a href="/__pyric/ui/docs/build/realtime-database/"> Realtime Database </a> </li><li> <a href="/__pyric/ui/docs/build/cloud-storage/"> Cloud Storage </a> </li><li> <a href="/__pyric/ui/docs/build/cloud-messaging/"> Cloud Messaging </a> </li><li> <a href="/__pyric/ui/docs/build/ai-logic/"> AI Logic </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Secure &amp; debug</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/secure/secure-it-with-rules/"> Security Rules </a> </li><li> <a href="/__pyric/ui/docs/secure/simulate-and-lint/"> Simulate and lint before you deploy </a> </li><li> <a href="/__pyric/ui/docs/secure/write-a-rules-test-suite/"> Write a rules test suite </a> </li><li> <a href="/__pyric/ui/docs/secure/read-a-denial/"> Read a denial and understand it </a> </li><li> <a href="/__pyric/ui/docs/secure/rules-standard-library/"> The rules standard library </a> </li><li> <a href="/__pyric/ui/docs/secure/rtdb-rules-in-typescript/"> RTDB rules in TypeScript </a> </li><li> <a href="/__pyric/ui/docs/secure/firestore-rules-limits/"> Rules limits </a> </li><li> <a href="/__pyric/ui/docs/secure/audit-your-rules/"> Audit rules and data </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading"> Examples </h2> <ul> <li> <a href="/__pyric/ui/docs/examples/chess/"> Chess showcase </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Observe &amp; shape</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/observe/see-whats-happening/"> Traffic &amp; rule verdicts </a> </li><li> <a href="/__pyric/ui/docs/observe/resolve-runtime-status/"> Runtime status </a> </li><li> <a href="/__pyric/ui/docs/observe/shape-your-data/"> Seed, snapshot, replay </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Ship &amp; test</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/ship/ship-to-production/"> Ship to production </a> </li><li> <a href="/__pyric/ui/docs/ship/test-in-node/"> Test in Node </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Work with an agent</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/agent/set-up-your-agent/"> Connect an agent </a> </li><li> <a href="/__pyric/ui/docs/agent/work-with-an-agent/"> Use the MCP tools </a> </li><li> <a href="/__pyric/ui/docs/agent/watch-and-review/"> Watch in Pyric Studio </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Trust</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/trust/versioning-and-compatibility/"> Versioning and the fb tag </a> </li><li> <a href="/__pyric/ui/docs/trust/storage-rules-stdlib-research/"> Storage Rules modules: evidence and design </a> </li><li> <a href="/__pyric/ui/docs/trust/rules-standard-library/"> Rules standard library reference </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" open> <summary>Conformance</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/conformance-scores/"> Public API coverage </a> </li><li> <a href="/__pyric/ui/docs/trust/how-we-know-it-matches-firebase/"> How we know it matches Firebase </a> </li><li> <a href="/__pyric/ui/docs/app-compat/"> App </a> </li><li> <a href="/__pyric/ui/docs/ai-compat/"> AI Logic </a> </li><li> <a href="/__pyric/ui/docs/auth-compat/"> Auth </a> </li><li> <a href="/__pyric/ui/docs/firestore-compat/"> Firestore </a> </li><li> <a href="/__pyric/ui/docs/database-compat/"> Realtime Database </a> </li><li> <a href="/__pyric/ui/docs/storage-compat/"> Storage </a> </li><li> <a href="/__pyric/ui/docs/messaging-compat/" aria-current="page"> Messaging </a> </li><li> <a href="/__pyric/ui/docs/functions-rtdb-compat/"> Functions · RTDB </a> </li><li> <a href="/__pyric/ui/docs/rules-compat/"> Rules </a> </li> </ul> </div> </div> </details> <details class="docs-nav-group"> <summary>Reference</summary> <div class="docs-nav-group-body docs-nav-group-body--reference"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/api-reference/"> API reference </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">pyric</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-app-reference-api/"> pyric/app </a> </li><li> <a href="/__pyric/ui/docs/pyric-firestore-reference-api/"> pyric/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-auth-reference-api/"> pyric/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-ai-reference-api/"> pyric/ai </a> </li><li> <a href="/__pyric/ui/docs/pyric-ai-scripting-reference-api/"> pyric/ai/scripting </a> </li><li> <a href="/__pyric/ui/docs/pyric-database-reference-api/"> pyric/database </a> </li><li> <a href="/__pyric/ui/docs/pyric-storage-reference-api/"> pyric/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-messaging-reference-api/"> pyric/messaging </a> </li><li> <a href="/__pyric/ui/docs/pyric-messaging-sw-reference-api/"> pyric/messaging/sw </a> </li><li> <a href="/__pyric/ui/docs/pyric-rules-reference-api/"> pyric/rules </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-reference-api/"> pyric/sandbox </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-firestore-reference-api/"> pyric/sandbox/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-database-reference-api/"> pyric/sandbox/database </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">pyric-admin</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-admin-app-reference-api/"> pyric-admin/app </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-firestore-reference-api/"> pyric-admin/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-auth-reference-api/"> pyric-admin/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-database-reference-api/"> pyric-admin/database </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-storage-reference-api/"> pyric-admin/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-messaging-reference-api/"> pyric-admin/messaging </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">create-pyric</h2> <ul> <li> <a href="/__pyric/ui/docs/create-pyric-reference-api/"> create-pyric </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">@pyric/cli</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-cli-credentials-node-reference-api/"> @pyric/cli/credentials/node </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-verify-reference-api/"> @pyric/cli/verify </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-conformance-reference-api/"> @pyric/cli/conformance </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-conformance-browser-reference-api/"> @pyric/cli/conformance/browser </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-conformance-docs-reference-api/"> @pyric/cli/conformance/docs </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-assurance-reference-api/"> @pyric/cli/assurance </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-assurance-browser-reference-api/"> @pyric/cli/assurance/browser </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-bridge-reference-api/"> @pyric/cli/bridge </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-bridge-client-reference-api/"> @pyric/cli/bridge/client </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-discover-reference-api/"> @pyric/cli/discover </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-vite-reference-api/"> @pyric/cli/vite </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-next-reference-api/"> @pyric/cli/next </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-serve-worker-reference-api/"> @pyric/cli/serve/worker </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-remote-reference-api/"> @pyric/cli/remote </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-register-reference-api/"> @pyric/cli/register </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-register-app-bridge-reference-api/"> @pyric/cli/register/app-bridge </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">@pyric/ui</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-ui-auth-reference-api/"> @pyric/ui/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-auth-hooks-reference-api/"> @pyric/ui/auth/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-primitives-reference-api/"> @pyric/ui/primitives </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-firestore-reference-api/"> @pyric/ui/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-firestore-hooks-reference-api/"> @pyric/ui/firestore/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-rtdb-reference-api/"> @pyric/ui/rtdb </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-storage-reference-api/"> @pyric/ui/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-storage-hooks-reference-api/"> @pyric/ui/storage/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-traffic-reference-api/"> @pyric/ui/traffic </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-traffic-hooks-reference-api/"> @pyric/ui/traffic/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-events-reference-api/"> @pyric/ui/events </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-events-hooks-reference-api/"> @pyric/ui/events/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-agents-reference-api/"> @pyric/ui/agents </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-rules-reference-api/"> @pyric/ui/rules </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-rules-hooks-reference-api/"> @pyric/ui/rules/hooks </a> </li> </ul> </div> </div> </details> </nav> </details> <nav class="docs-nav" aria-label="Documentation"> <div class="docs-search" data-index-url="/__pyric/ui/docs/index.json"> <div class="docs-search-field"> <svg class="docs-search-icon" viewBox="0 0 16 16" width="14" height="14" aria-hidden="true"> <path d="M11.5 11.5 15 15M13 7A6 6 0 1 1 1 7a6 6 0 0 1 12 0Z" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"></path> </svg> <input type="text" class="docs-search-input" placeholder="Search docs" aria-label="Search docs" autocomplete="off" spellcheck="false"> <kbd class="docs-search-kbd">⌘K</kbd> </div> <ul class="docs-search-results" hidden></ul> </div> <details class="docs-nav-group" id="nav-group-overview"> <summary>Overview</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/overview/"> Overview </a> </li><li> <a href="/__pyric/ui/docs/tutorial/"> Tutorial </a> </li><li> <a href="/__pyric/ui/docs/examples/"> Examples </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-get-started"> <summary>Get started</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/get-started/start-building/"> Quickstart </a> </li><li> <a href="/__pyric/ui/docs/get-started/vite/"> Vite </a> </li><li> <a href="/__pyric/ui/docs/get-started/nextjs/"> Next.js </a> </li><li> <a href="/__pyric/ui/docs/get-started/how-the-swap-works/"> How the swap works </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-build"> <summary>Build</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/build/authentication/"> Authentication </a> </li><li> <a href="/__pyric/ui/docs/build/cloud-firestore/"> Cloud Firestore </a> </li><li> <a href="/__pyric/ui/docs/build/realtime-database/"> Realtime Database </a> </li><li> <a href="/__pyric/ui/docs/build/cloud-storage/"> Cloud Storage </a> </li><li> <a href="/__pyric/ui/docs/build/cloud-messaging/"> Cloud Messaging </a> </li><li> <a href="/__pyric/ui/docs/build/ai-logic/"> AI Logic </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-secure-debug"> <summary>Secure &amp; debug</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/secure/secure-it-with-rules/"> Security Rules </a> </li><li> <a href="/__pyric/ui/docs/secure/simulate-and-lint/"> Simulate and lint before you deploy </a> </li><li> <a href="/__pyric/ui/docs/secure/write-a-rules-test-suite/"> Write a rules test suite </a> </li><li> <a href="/__pyric/ui/docs/secure/read-a-denial/"> Read a denial and understand it </a> </li><li> <a href="/__pyric/ui/docs/secure/rules-standard-library/"> The rules standard library </a> </li><li> <a href="/__pyric/ui/docs/secure/rtdb-rules-in-typescript/"> RTDB rules in TypeScript </a> </li><li> <a href="/__pyric/ui/docs/secure/firestore-rules-limits/"> Rules limits </a> </li><li> <a href="/__pyric/ui/docs/secure/audit-your-rules/"> Audit rules and data </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading" id="nav-section-secure-debug-examples"> Examples </h2> <ul> <li> <a href="/__pyric/ui/docs/examples/chess/"> Chess showcase </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-observe-shape"> <summary>Observe &amp; shape</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/observe/see-whats-happening/"> Traffic &amp; rule verdicts </a> </li><li> <a href="/__pyric/ui/docs/observe/resolve-runtime-status/"> Runtime status </a> </li><li> <a href="/__pyric/ui/docs/observe/shape-your-data/"> Seed, snapshot, replay </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-ship-test"> <summary>Ship &amp; test</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/ship/ship-to-production/"> Ship to production </a> </li><li> <a href="/__pyric/ui/docs/ship/test-in-node/"> Test in Node </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-work-with-an-agent"> <summary>Work with an agent</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/agent/set-up-your-agent/"> Connect an agent </a> </li><li> <a href="/__pyric/ui/docs/agent/work-with-an-agent/"> Use the MCP tools </a> </li><li> <a href="/__pyric/ui/docs/agent/watch-and-review/"> Watch in Pyric Studio </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-trust"> <summary>Trust</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/trust/versioning-and-compatibility/"> Versioning and the fb tag </a> </li><li> <a href="/__pyric/ui/docs/trust/storage-rules-stdlib-research/"> Storage Rules modules: evidence and design </a> </li><li> <a href="/__pyric/ui/docs/trust/rules-standard-library/"> Rules standard library reference </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-conformance" open> <summary>Conformance</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/conformance-scores/"> Public API coverage </a> </li><li> <a href="/__pyric/ui/docs/trust/how-we-know-it-matches-firebase/"> How we know it matches Firebase </a> </li><li> <a href="/__pyric/ui/docs/app-compat/"> App </a> </li><li> <a href="/__pyric/ui/docs/ai-compat/"> AI Logic </a> </li><li> <a href="/__pyric/ui/docs/auth-compat/"> Auth </a> </li><li> <a href="/__pyric/ui/docs/firestore-compat/"> Firestore </a> </li><li> <a href="/__pyric/ui/docs/database-compat/"> Realtime Database </a> </li><li> <a href="/__pyric/ui/docs/storage-compat/"> Storage </a> </li><li> <a href="/__pyric/ui/docs/messaging-compat/" aria-current="page"> Messaging </a> </li><li> <a href="/__pyric/ui/docs/functions-rtdb-compat/"> Functions · RTDB </a> </li><li> <a href="/__pyric/ui/docs/rules-compat/"> Rules </a> </li> </ul> </div> </div> </details> <details class="docs-nav-group" id="nav-group-reference"> <summary>Reference</summary> <div class="docs-nav-group-body docs-nav-group-body--reference"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/api-reference/"> API reference </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">pyric</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-app-reference-api/"> pyric/app </a> </li><li> <a href="/__pyric/ui/docs/pyric-firestore-reference-api/"> pyric/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-auth-reference-api/"> pyric/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-ai-reference-api/"> pyric/ai </a> </li><li> <a href="/__pyric/ui/docs/pyric-ai-scripting-reference-api/"> pyric/ai/scripting </a> </li><li> <a href="/__pyric/ui/docs/pyric-database-reference-api/"> pyric/database </a> </li><li> <a href="/__pyric/ui/docs/pyric-storage-reference-api/"> pyric/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-messaging-reference-api/"> pyric/messaging </a> </li><li> <a href="/__pyric/ui/docs/pyric-messaging-sw-reference-api/"> pyric/messaging/sw </a> </li><li> <a href="/__pyric/ui/docs/pyric-rules-reference-api/"> pyric/rules </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-reference-api/"> pyric/sandbox </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-firestore-reference-api/"> pyric/sandbox/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-database-reference-api/"> pyric/sandbox/database </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">pyric-admin</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-admin-app-reference-api/"> pyric-admin/app </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-firestore-reference-api/"> pyric-admin/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-auth-reference-api/"> pyric-admin/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-database-reference-api/"> pyric-admin/database </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-storage-reference-api/"> pyric-admin/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-messaging-reference-api/"> pyric-admin/messaging </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">create-pyric</h2> <ul> <li> <a href="/__pyric/ui/docs/create-pyric-reference-api/"> create-pyric </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">@pyric/cli</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-cli-credentials-node-reference-api/"> @pyric/cli/credentials/node </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-verify-reference-api/"> @pyric/cli/verify </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-conformance-reference-api/"> @pyric/cli/conformance </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-conformance-browser-reference-api/"> @pyric/cli/conformance/browser </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-conformance-docs-reference-api/"> @pyric/cli/conformance/docs </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-assurance-reference-api/"> @pyric/cli/assurance </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-assurance-browser-reference-api/"> @pyric/cli/assurance/browser </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-bridge-reference-api/"> @pyric/cli/bridge </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-bridge-client-reference-api/"> @pyric/cli/bridge/client </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-discover-reference-api/"> @pyric/cli/discover </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-vite-reference-api/"> @pyric/cli/vite </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-next-reference-api/"> @pyric/cli/next </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-serve-worker-reference-api/"> @pyric/cli/serve/worker </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-remote-reference-api/"> @pyric/cli/remote </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-register-reference-api/"> @pyric/cli/register </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-register-app-bridge-reference-api/"> @pyric/cli/register/app-bridge </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">@pyric/ui</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-ui-auth-reference-api/"> @pyric/ui/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-auth-hooks-reference-api/"> @pyric/ui/auth/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-primitives-reference-api/"> @pyric/ui/primitives </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-firestore-reference-api/"> @pyric/ui/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-firestore-hooks-reference-api/"> @pyric/ui/firestore/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-rtdb-reference-api/"> @pyric/ui/rtdb </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-storage-reference-api/"> @pyric/ui/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-storage-hooks-reference-api/"> @pyric/ui/storage/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-traffic-reference-api/"> @pyric/ui/traffic </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-traffic-hooks-reference-api/"> @pyric/ui/traffic/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-events-reference-api/"> @pyric/ui/events </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-events-hooks-reference-api/"> @pyric/ui/events/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-agents-reference-api/"> @pyric/ui/agents </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-rules-reference-api/"> @pyric/ui/rules </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-rules-hooks-reference-api/"> @pyric/ui/rules/hooks </a> </li> </ul> </div> </div> </details> </nav> <main class="doc-main" data-astro-cid-mw7aashj> <nav class="docs-breadcrumbs" aria-label="Breadcrumb"> <ol> <li> <a href="/__pyric/ui/docs/conformance-scores/">Conformance</a> </li><li> <span class="docs-breadcrumbs-sep" aria-hidden="true">/</span> <span aria-current="page">Messaging</span> </li> </ol> </nav> <article class="prose" data-astro-cid-mw7aashj> <!-- Generated from the conformance model (registry rows + surface contracts). Do not edit by hand; run bun run compat:generate. -->
3
3
  <h1 id="pyric-messaging-compatibility-matrix"><code>pyric</code> messaging compatibility matrix</h1>
4
4
  <div class="compat-stat">
5
5
  <p class="compat-stat-figure">
@@ -21,39 +21,39 @@
21
21
  <div class="compat-list">
22
22
  <details class="compat-row" data-status="ok">
23
23
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">getMessaging(app?): Messaging</code><span class="compat-sub"><span class="compat-behavior">Returns the FCM <code>Messaging</code> instance associated with the given (or default) <code>FirebaseApp</code>. Bound to the client component registered under the name <code>messaging</code>.</span></span></span></summary>
24
- <div class="compat-evidence"><div class="compat-probe">Upstream typings/JSDoc (firebase 12.13.0, <code>@firebase/messaging</code> 0.12.26); in-process mirror suite plus canonical-import SharedWorker replay <code>messaging-app-boundary.pw.ts</code>.</div></div>
24
+ <div class="compat-evidence"><div class="compat-probe">Upstream typings/JSDoc (firebase 12.13.0, <code>@firebase/messaging</code> 0.12.26); in-process mirror suite plus canonical-import SharedWorker replay <a href="https://github.com/davideast/pyric/blob/main/packages/cli/test/e2e/messaging-app-boundary.pw.ts#L3" target="_blank" rel="noopener noreferrer"><code>messaging-app-boundary.pw.ts</code></a>. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/messaging/oracle-conformance.test.ts#L63" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
25
25
  </details>
26
26
  <details class="compat-row" data-status="ok">
27
27
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">getToken(messaging, options?): Promise&#x3C;string></code><span class="compat-sub"><span class="compat-behavior">Subscribes the instance to push and resolves with an FCM registration token; requests notification permission if not already granted and rejects if denied. Production tokens are colon-separated, URL-safe, ~142 chars, with the suffix after the colon beginning <code>APA91b</code>, and are stable across repeated <code>getToken</code> calls on the same service-worker registration (no per-call rotation).</span></span></span></summary>
28
- <div class="compat-evidence"><div class="compat-probe">oracle: <code>messaging-web-token-shape.json</code> (minted, length 142, colon-separated, suffix starts <code>APA91b</code>, URL-safe) + <code>messaging-web-token-stability.json</code> (second <code>getToken</code> on the same registration returns the same token). Replayed by the conformance suite.</div></div>
28
+ <div class="compat-evidence"><div class="compat-probe">oracle: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/messaging/messaging-web-token-shape.json" target="_blank" rel="noopener noreferrer"><code>messaging-web-token-shape.json</code></a> (minted, length 142, colon-separated, suffix starts <code>APA91b</code>, URL-safe) + <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/messaging/messaging-web-token-stability.json" target="_blank" rel="noopener noreferrer"><code>messaging-web-token-stability.json</code></a> (second <code>getToken</code> on the same registration returns the same token). Replayed by the conformance suite. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/messaging/oracle-conformance.test.ts#L125" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
29
29
  </details>
30
30
  <details class="compat-row" data-status="ok">
31
31
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">deleteToken(messaging): Promise&#x3C;boolean></code><span class="compat-sub"><span class="compat-behavior">Deletes the registration token and unsubscribes the instance from its push subscription; resolves truthy. After deletion no message reaches the client on either route, and a server send to the now-dead token eventually surfaces the UNREGISTERED / 404-class error on the send plane (propagation is asynchronous — the first send after delete may still be accepted while delivery has already stopped).</span></span></span></summary>
32
- <div class="compat-evidence"><div class="compat-probe">oracle: <code>messaging-web-deletetoken-unregistered.json</code> (deleteToken resolved truthy; no delivery to client; send plane eventually UNREGISTERED). Replayed by the conformance suite.</div></div>
32
+ <div class="compat-evidence"><div class="compat-probe">oracle: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/messaging/messaging-web-deletetoken-unregistered.json" target="_blank" rel="noopener noreferrer"><code>messaging-web-deletetoken-unregistered.json</code></a> (deleteToken resolved truthy; no delivery to client; send plane eventually UNREGISTERED). Replayed by the conformance suite. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/messaging/oracle-conformance.test.ts#L145" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
33
33
  </details>
34
34
  <details class="compat-row" data-status="ok">
35
35
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">onMessage(messaging, nextOrObserver): Unsubscribe</code><span class="compat-sub"><span class="compat-behavior">Dispatched with the push payload when a message arrives while a window client is visible; the returned function stops listening. Routing keys on page VISIBILITY, not focus: a <code>visibilityState: "visible"</code> page receives <code>onMessage</code> even when unfocused, and when no window client is visible the message routes to the service-worker <code>onBackgroundMessage</code> instead.</span></span></span></summary>
36
- <div class="compat-evidence"><div class="compat-probe">oracle: <code>messaging-web-onmessage-foreground.json</code> (focused page → onMessage) + <code>messaging-web-visibility-routing.json</code> (visible → onMessage, no visible client → onBackgroundMessage). Replayed by the conformance suite.</div></div>
36
+ <div class="compat-evidence"><div class="compat-probe">oracle: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/messaging/messaging-web-onmessage-foreground.json" target="_blank" rel="noopener noreferrer"><code>messaging-web-onmessage-foreground.json</code></a> (focused page → onMessage) + <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/messaging/messaging-web-visibility-routing.json" target="_blank" rel="noopener noreferrer"><code>messaging-web-visibility-routing.json</code></a> (visible → onMessage, no visible client → onBackgroundMessage). Replayed by the conformance suite. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/messaging/oracle-conformance.test.ts#L192" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
37
37
  </details>
38
38
  <details class="compat-row" data-status="ok">
39
39
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">isSupported(): Promise&#x3C;boolean></code><span class="compat-sub"><span class="compat-behavior">Resolves whether every API required by FCM exists in the current browser window context (bound to <code>isWindowSupported</code>).</span></span></span></summary>
40
- <div class="compat-evidence"><div class="compat-probe">Upstream typings/JSDoc (<code>@firebase/messaging</code> 0.12.26); no observation yet.</div></div>
40
+ <div class="compat-evidence"><div class="compat-probe">Upstream typings/JSDoc (<code>@firebase/messaging</code> 0.12.26); no observation yet. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/messaging/oracle-conformance.test.ts#L231" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
41
41
  </details>
42
42
  <details class="compat-row" data-status="ok">
43
43
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">interface Messaging { app }</code><span class="compat-sub"><span class="compat-behavior">Public interface of the FCM client SDK; exposes the bound <code>FirebaseApp</code> as <code>app</code>.</span></span></span></summary>
44
- <div class="compat-evidence"><div class="compat-probe">Upstream typings (<code>@firebase/messaging</code> 0.12.26 <code>public-types</code>); no observation yet.</div></div>
44
+ <div class="compat-evidence"><div class="compat-probe">Upstream typings (<code>@firebase/messaging</code> 0.12.26 <code>public-types</code>); no observation yet. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/messaging/oracle-conformance.test.ts#L238" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
45
45
  </details>
46
46
  <details class="compat-row" data-status="ok">
47
47
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">interface GetTokenOptions { vapidKey?; serviceWorkerRegistration? }</code><span class="compat-sub"><span class="compat-behavior">Options for <code>getToken</code>: an optional <code>vapidKey</code> (Web Push certificate public key) and an optional <code>serviceWorkerRegistration</code>.</span></span></span></summary>
48
- <div class="compat-evidence"><div class="compat-probe">Upstream typings (<code>@firebase/messaging</code> 0.12.26 <code>public-types</code>); no observation yet.</div></div>
48
+ <div class="compat-evidence"><div class="compat-probe">Upstream typings (<code>@firebase/messaging</code> 0.12.26 <code>public-types</code>); no observation yet. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/messaging/oracle-conformance.test.ts#L245" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
49
49
  </details>
50
50
  <details class="compat-row" data-status="ok">
51
51
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">interface MessagePayload { notification?; data?; fcmOptions?; from; collapseKey; messageId }</code><span class="compat-sub"><span class="compat-behavior">Received message envelope delivered to <code>onMessage</code> / <code>onBackgroundMessage</code>. Production deliveries carry top-level keys <code>data</code>, <code>from</code>, <code>messageId</code>, and <code>notification</code>; <code>from</code> equals the project messaging sender id and <code>messageId</code> is present. (<code>from</code>, <code>collapseKey</code>, <code>messageId</code> are typed as required.)</span></span></span></summary>
52
- <div class="compat-evidence"><div class="compat-probe">oracle: <code>messaging-web-onmessage-foreground.json</code> + <code>messaging-web-onbackgroundmessage.json</code> (top-level keys data/from/messageId/notification; from = sender id; messageId present). Replayed by the conformance suite.</div></div>
52
+ <div class="compat-evidence"><div class="compat-probe">oracle: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/messaging/messaging-web-onmessage-foreground.json" target="_blank" rel="noopener noreferrer"><code>messaging-web-onmessage-foreground.json</code></a> + <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/messaging/messaging-web-onbackgroundmessage.json" target="_blank" rel="noopener noreferrer"><code>messaging-web-onbackgroundmessage.json</code></a> (top-level keys data/from/messageId/notification; from = sender id; messageId present). Replayed by the conformance suite. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/messaging/oracle-conformance.test.ts#L197" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
53
53
  </details>
54
54
  <details class="compat-row" data-status="ok">
55
55
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">interface NotificationPayload { title?; body?; image?; icon? }</code><span class="compat-sub"><span class="compat-behavior">Display-notification block inside a <code>MessagePayload</code>. Production foreground deliveries carry a <code>notification</code> object whose keys include <code>title</code> and <code>body</code>.</span></span></span></summary>
56
- <div class="compat-evidence"><div class="compat-probe">oracle: <code>messaging-web-onmessage-foreground.json</code> (notificationKeys body, title). Replayed by the conformance suite.</div></div>
56
+ <div class="compat-evidence"><div class="compat-probe">oracle: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/messaging/messaging-web-onmessage-foreground.json" target="_blank" rel="noopener noreferrer"><code>messaging-web-onmessage-foreground.json</code></a> (notificationKeys body, title). Replayed by the conformance suite. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/messaging/oracle-conformance.test.ts#L197" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
57
57
  </details>
58
58
  <details class="compat-row" data-status="ok">
59
59
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">interface FcmOptions { link?; analyticsLabel? }</code><span class="compat-sub"><span class="compat-behavior">WebpushFcmOptions-style options carried on a client <code>MessagePayload</code> (<code>link</code>, <code>analyticsLabel</code>).</span></span></span></summary>
@@ -61,34 +61,34 @@
61
61
  </details>
62
62
  <details class="compat-row" data-status="ok">
63
63
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">NextFn, Observer, Unsubscribe (re-exported from @firebase/util)</code><span class="compat-sub"><span class="compat-behavior">The callback, observer, and teardown types consumed by <code>onMessage</code> / <code>onBackgroundMessage</code> are re-exported from <code>@firebase/util</code>.</span></span></span></summary>
64
- <div class="compat-evidence"><div class="compat-probe">Upstream typings (<code>@firebase/messaging</code> 0.12.26 re-exports); no observation yet.</div></div>
64
+ <div class="compat-evidence"><div class="compat-probe">Upstream typings (<code>@firebase/messaging</code> 0.12.26 re-exports); no observation yet. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/messaging/oracle-conformance.test.ts#L340" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
65
65
  </details>
66
66
  <details class="compat-row" data-status="ok">
67
67
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">const enum ErrorCode (client)</code><span class="compat-sub"><span class="compat-behavior">Client failures surface as thrown <code>FirebaseError</code>s carrying one of the 18 documented <code>ErrorCode</code> values (<code>missing-app-config-values</code>, <code>only-available-in-window</code>, <code>only-available-in-sw</code>, <code>permission-default</code>, <code>permission-blocked</code>, <code>unsupported-browser</code>, <code>indexed-db-unsupported</code>, <code>failed-service-worker-registration</code>, <code>token-subscribe-failed</code>, <code>token-subscribe-no-token</code>, <code>token-unsubscribe-failed</code>, <code>token-update-failed</code>, <code>token-update-no-token</code>, <code>invalid-bg-handler</code>, <code>use-sw-after-get-token</code>, <code>invalid-sw-registration</code>, <code>use-vapid-key-after-get-token</code>, <code>invalid-vapid-key</code>). The enum itself is <code>@internal</code>, not a public export.</span></span></span></summary>
68
- <div class="compat-evidence"><div class="compat-probe">Upstream typings (<code>@firebase/messaging</code> 0.12.26 <code>src/util/errors</code>); no client-error observation among the committed set.</div></div>
68
+ <div class="compat-evidence"><div class="compat-probe">Upstream typings (<code>@firebase/messaging</code> 0.12.26 <code>src/util/errors</code>); no client-error observation among the committed set. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/messaging/oracle-conformance.test.ts#L372" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
69
69
  </details>
70
70
  </div>
71
71
  <h2 id="firebasemessagingsw-service-worker"><code>firebase/messaging/sw</code> (service worker)</h2>
72
72
  <div class="compat-list">
73
73
  <details class="compat-row" data-status="ok">
74
74
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">getMessaging(app?): Messaging (sw)</code><span class="compat-sub"><span class="compat-behavior">Returns the FCM instance within a service-worker context (bound to <code>getMessagingInSw</code>); registers under the component name <code>messaging-sw</code>.</span></span></span></summary>
75
- <div class="compat-evidence"><div class="compat-probe">Upstream typings (<code>@firebase/messaging</code> 0.12.26 <code>sw/index-public</code>) plus real module-ServiceWorker served-entry replay <code>messaging-app-boundary.pw.ts</code>.</div></div>
75
+ <div class="compat-evidence"><div class="compat-probe">Upstream typings (<code>@firebase/messaging</code> 0.12.26 <code>sw/index-public</code>) plus real module-ServiceWorker served-entry replay <a href="https://github.com/davideast/pyric/blob/main/packages/cli/test/e2e/messaging-app-boundary.pw.ts#L3" target="_blank" rel="noopener noreferrer"><code>messaging-app-boundary.pw.ts</code></a>. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/messaging/oracle-conformance.test.ts#L380" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
76
76
  </details>
77
77
  <details class="compat-row" data-status="ok">
78
78
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">onBackgroundMessage(messaging, nextOrObserver): Unsubscribe</code><span class="compat-sub"><span class="compat-behavior">Called when a message arrives while the app has no visible window client. Production routes background deliveries here rather than to <code>onMessage</code>; the delivered payload carries <code>data</code> / <code>from</code> / <code>messageId</code> and, for notification messages, a <code>notification</code> block. A DATA-ONLY message still fires <code>onBackgroundMessage</code> with no <code>notification</code> key, and a registered handler suppresses the SDK auto-display.</span></span></span></summary>
79
- <div class="compat-evidence"><div class="compat-probe">oracle: <code>messaging-web-onbackgroundmessage.json</code> (no visible client → onBackgroundMessage) + <code>messaging-web-visibility-routing.json</code> + <code>messaging-web-data-only-background.json</code> (data-only fires, no notification key). Replayed by the conformance suite and by a real module Service Worker connected to the canonical SharedWorker broker in <code>messaging-app-boundary.pw.ts</code>.</div></div>
79
+ <div class="compat-evidence"><div class="compat-probe">oracle: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/messaging/messaging-web-onbackgroundmessage.json" target="_blank" rel="noopener noreferrer"><code>messaging-web-onbackgroundmessage.json</code></a> (no visible client → onBackgroundMessage) + <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/messaging/messaging-web-visibility-routing.json" target="_blank" rel="noopener noreferrer"><code>messaging-web-visibility-routing.json</code></a> + <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/messaging/messaging-web-data-only-background.json" target="_blank" rel="noopener noreferrer"><code>messaging-web-data-only-background.json</code></a> (data-only fires, no notification key). Replayed by the conformance suite and by a real module Service Worker connected to the canonical SharedWorker broker in <a href="https://github.com/davideast/pyric/blob/main/packages/cli/test/e2e/messaging-app-boundary.pw.ts#L73" target="_blank" rel="noopener noreferrer"><code>messaging-app-boundary.pw.ts</code></a>. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/messaging/oracle-conformance.test.ts#L198" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
80
80
  </details>
81
81
  <details class="compat-row" data-status="ok">
82
82
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">experimentalSetDeliveryMetricsExportedToBigQueryEnabled(messaging, enable): void</code><span class="compat-sub"><span class="compat-behavior">Enables or disables delivery-metrics export to BigQuery at runtime; default off.</span></span></span></summary>
83
- <div class="compat-evidence"><div class="compat-probe">Upstream typings (<code>@firebase/messaging</code> 0.12.26 <code>sw/index-public</code>); no observation yet.</div></div>
83
+ <div class="compat-evidence"><div class="compat-probe">Upstream typings (<code>@firebase/messaging</code> 0.12.26 <code>sw/index-public</code>); no observation yet. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/messaging/oracle-conformance.test.ts#L416" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
84
84
  </details>
85
85
  <details class="compat-row" data-status="ok">
86
86
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">isSupported(): Promise&#x3C;boolean> (sw)</code><span class="compat-sub"><span class="compat-behavior">Resolves whether every API required by FCM exists within the service-worker context (bound to <code>isSwSupported</code>).</span></span></span></summary>
87
- <div class="compat-evidence"><div class="compat-probe">Upstream typings (<code>@firebase/messaging</code> 0.12.26 <code>sw/index-public</code>); no observation yet.</div></div>
87
+ <div class="compat-evidence"><div class="compat-probe">Upstream typings (<code>@firebase/messaging</code> 0.12.26 <code>sw/index-public</code>); no observation yet. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/messaging/oracle-conformance.test.ts#L422" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
88
88
  </details>
89
89
  <details class="compat-row" data-status="ok">
90
90
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">firebase/messaging/sw module boundary + shared type parity</code><span class="compat-sub"><span class="compat-behavior">The sw entry exports <code>onBackgroundMessage</code>, <code>getMessaging</code>, <code>experimentalSetDeliveryMetricsExportedToBigQueryEnabled</code>, and <code>isSupported</code>, but NOT <code>getToken</code> / <code>deleteToken</code> / <code>onMessage</code>; the client entry exports the latter but NOT <code>onBackgroundMessage</code> / the metrics toggle. The two modules register under different component names (<code>messaging</code> vs <code>messaging-sw</code>) and re-export identical <code>Messaging</code> / <code>GetTokenOptions</code> / <code>MessagePayload</code> / <code>NotificationPayload</code> / <code>FcmOptions</code> type declarations.</span></span></span></summary>
91
- <div class="compat-evidence"><div class="compat-probe">Upstream typings (<code>@firebase/messaging</code> 0.12.26 <code>index.d.ts</code> / <code>index.sw.d.ts</code>) plus Window and real module-ServiceWorker boundary replay <code>messaging-app-boundary.pw.ts</code>.</div></div>
91
+ <div class="compat-evidence"><div class="compat-probe">Upstream typings (<code>@firebase/messaging</code> 0.12.26 <code>index.d.ts</code> / <code>index.sw.d.ts</code>) plus Window and real module-ServiceWorker boundary replay <a href="https://github.com/davideast/pyric/blob/main/packages/cli/test/e2e/messaging-app-boundary.pw.ts#L3" target="_blank" rel="noopener noreferrer"><code>messaging-app-boundary.pw.ts</code></a>. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/messaging/oracle-conformance.test.ts#L429" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
92
92
  </details>
93
93
  </div>
94
94
  <h2 id="behavior-classes-over-time--across-clients-client-receive-plane">Behavior classes over time &#x26; across clients (client receive plane)</h2>
@@ -114,174 +114,174 @@
114
114
  <div class="compat-list">
115
115
  <details class="compat-row" data-status="ok">
116
116
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">getMessaging(app?): Messaging</code><span class="compat-sub"><span class="compat-behavior">Returns the <code>Messaging</code> service for the default or given admin <code>App</code>.</span></span></span></summary>
117
- <div class="compat-evidence"><div class="compat-probe">Upstream typings/JSDoc (firebase-admin 13.10.0 <code>lib/messaging/index</code>); no observation yet.</div></div>
117
+ <div class="compat-evidence"><div class="compat-probe">Upstream typings/JSDoc (firebase-admin 13.10.0 <code>lib/messaging/index</code>); no observation yet. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric-admin/test/messaging/oracle-conformance.test.ts#L63" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
118
118
  </details>
119
119
  <details class="compat-row" data-status="ok">
120
120
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">messaging(app?): messaging.Messaging</code><span class="compat-sub"><span class="compat-behavior">Namespaced / legacy accessor equivalent of <code>getMessaging</code>, exposed by the compat entry alongside the <code>namespace messaging</code> type aliases.</span></span></span></summary>
121
- <div class="compat-evidence"><div class="compat-probe">Upstream typings (firebase-admin 13.10.0 <code>messaging-namespace</code>); no observation yet.</div></div>
121
+ <div class="compat-evidence"><div class="compat-probe">Upstream typings (firebase-admin 13.10.0 <code>messaging-namespace</code>); no observation yet. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric-admin/test/messaging/oracle-conformance.test.ts#L181" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
122
122
  </details>
123
123
  <details class="compat-row" data-status="ok">
124
124
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">Messaging.get app(): App</code><span class="compat-sub"><span class="compat-behavior">The admin <code>App</code> this <code>Messaging</code> instance is bound to.</span></span></span></summary>
125
- <div class="compat-evidence"><div class="compat-probe">Upstream typings (firebase-admin 13.10.0 <code>messaging</code>); no observation yet.</div></div>
125
+ <div class="compat-evidence"><div class="compat-probe">Upstream typings (firebase-admin 13.10.0 <code>messaging</code>); no observation yet. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric-admin/test/messaging/oracle-conformance.test.ts#L156" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
126
126
  </details>
127
127
  <details class="compat-row" data-status="ok">
128
128
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">Messaging.send(message, dryRun?): Promise&#x3C;string></code><span class="compat-sub"><span class="compat-behavior">Sends one message via FCM v1 and resolves with the resource name <code>projects/&#x3C;projectId>/messages/&#x3C;numeric id></code>. <code>dryRun=true</code> returns the SAME shape (fake id), so callers cannot distinguish validation from acceptance by shape. Topic, condition, token, notification-only, data-only, and webpush-config sends are all accepted. Malformed sends fail server-side validation with HTTP 4xx <code>google.rpc</code> error envelopes carrying both a <code>google.rpc.BadRequest</code> (fieldViolations) and a <code>google.firebase.fcm.v1.FcmError</code> (errorCode); detail ordering is not contractual. The documented data-payload cap is 4096 bytes.</span></span></span></summary>
129
- <div class="compat-evidence"><div class="compat-probe">oracle: 10 send-plane observations — accept paths <code>messaging-send-topic-accepted</code>, <code>messaging-send-condition-accepted</code>, <code>messaging-send-notification-only-vs-data-only-accepted</code>, <code>messaging-send-webpush-config-accepted</code>; error envelopes <code>messaging-send-no-target-error-envelope</code>, <code>messaging-send-invalid-token-error-envelope</code>, <code>messaging-send-invalid-condition-error-envelope</code>, <code>messaging-send-invalid-topic-name-error-envelope</code>, <code>messaging-send-oversized-payload-error-envelope</code>, <code>messaging-send-webpush-invalid-ttl-error-envelope</code>. Replayed by the conformance suite.</div></div>
129
+ <div class="compat-evidence"><div class="compat-probe">oracle: 10 send-plane observations — accept paths <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/messaging-admin/messaging-send-topic-accepted.json" target="_blank" rel="noopener noreferrer"><code>messaging-send-topic-accepted</code></a>, <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/messaging-admin/messaging-send-condition-accepted.json" target="_blank" rel="noopener noreferrer"><code>messaging-send-condition-accepted</code></a>, <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/messaging-admin/messaging-send-notification-only-vs-data-only-accepted.json" target="_blank" rel="noopener noreferrer"><code>messaging-send-notification-only-vs-data-only-accepted</code></a>, <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/messaging-admin/messaging-send-webpush-config-accepted.json" target="_blank" rel="noopener noreferrer"><code>messaging-send-webpush-config-accepted</code></a>; error envelopes <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/messaging-admin/messaging-send-no-target-error-envelope.json" target="_blank" rel="noopener noreferrer"><code>messaging-send-no-target-error-envelope</code></a>, <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/messaging-admin/messaging-send-invalid-token-error-envelope.json" target="_blank" rel="noopener noreferrer"><code>messaging-send-invalid-token-error-envelope</code></a>, <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/messaging-admin/messaging-send-invalid-condition-error-envelope.json" target="_blank" rel="noopener noreferrer"><code>messaging-send-invalid-condition-error-envelope</code></a>, <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/messaging-admin/messaging-send-invalid-topic-name-error-envelope.json" target="_blank" rel="noopener noreferrer"><code>messaging-send-invalid-topic-name-error-envelope</code></a>, <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/messaging-admin/messaging-send-oversized-payload-error-envelope.json" target="_blank" rel="noopener noreferrer"><code>messaging-send-oversized-payload-error-envelope</code></a>, <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/messaging-admin/messaging-send-webpush-invalid-ttl-error-envelope.json" target="_blank" rel="noopener noreferrer"><code>messaging-send-webpush-invalid-ttl-error-envelope</code></a>. Replayed by the conformance suite. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric-admin/test/messaging/oracle-conformance.test.ts#L192" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
130
130
  </details>
131
131
  <details class="compat-row" data-status="ok">
132
132
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">Messaging.sendEach(messages, dryRun?): Promise&#x3C;BatchResponse></code><span class="compat-sub"><span class="compat-behavior">Sends an array of up to 500 messages, one RPC per message; resolves a <code>BatchResponse</code> whose <code>responses</code> are ordered to match the input. Total failure is signalled by a throw or an all-failure <code>BatchResponse</code>.</span></span></span></summary>
133
- <div class="compat-evidence"><div class="compat-probe">Upstream typings/JSDoc (firebase-admin 13.10.0 <code>messaging</code>); no observation yet.</div></div>
133
+ <div class="compat-evidence"><div class="compat-probe">Upstream typings/JSDoc (firebase-admin 13.10.0 <code>messaging</code>); no observation yet. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric-admin/test/messaging/oracle-conformance.test.ts#L237" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
134
134
  </details>
135
135
  <details class="compat-row" data-status="ok">
136
136
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">Messaging.sendEachForMulticast(message, dryRun?): Promise&#x3C;BatchResponse></code><span class="compat-sub"><span class="compat-behavior">Fans a <code>MulticastMessage</code> (up to 500 tokens) out through <code>sendEach</code>.</span></span></span></summary>
137
- <div class="compat-evidence"><div class="compat-probe">Upstream typings/JSDoc (firebase-admin 13.10.0 <code>messaging</code>); no observation yet.</div></div>
137
+ <div class="compat-evidence"><div class="compat-probe">Upstream typings/JSDoc (firebase-admin 13.10.0 <code>messaging</code>); no observation yet. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric-admin/test/messaging/oracle-conformance.test.ts#L241" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
138
138
  </details>
139
139
  <details class="compat-row" data-status="ok">
140
140
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">Messaging.subscribeToTopic(tokenOrTokens, topic): Promise&#x3C;MessagingTopicManagementResponse></code><span class="compat-sub"><span class="compat-behavior">Subscribes one or many registration tokens to a topic; resolves a <code>MessagingTopicManagementResponse</code>.</span></span></span></summary>
141
- <div class="compat-evidence"><div class="compat-probe">Upstream typings/JSDoc (firebase-admin 13.10.0 <code>messaging</code>); no observation yet.</div></div>
141
+ <div class="compat-evidence"><div class="compat-probe">Upstream typings/JSDoc (firebase-admin 13.10.0 <code>messaging</code>); no observation yet. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric-admin/test/messaging/oracle-conformance.test.ts#L245" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
142
142
  </details>
143
143
  <details class="compat-row" data-status="ok">
144
144
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">Messaging.unsubscribeFromTopic(tokenOrTokens, topic): Promise&#x3C;MessagingTopicManagementResponse></code><span class="compat-sub"><span class="compat-behavior">Unsubscribes one or many registration tokens from a topic; resolves a <code>MessagingTopicManagementResponse</code>.</span></span></span></summary>
145
- <div class="compat-evidence"><div class="compat-probe">Upstream typings/JSDoc (firebase-admin 13.10.0 <code>messaging</code>); no observation yet.</div></div>
145
+ <div class="compat-evidence"><div class="compat-probe">Upstream typings/JSDoc (firebase-admin 13.10.0 <code>messaging</code>); no observation yet. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric-admin/test/messaging/oracle-conformance.test.ts#L249" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
146
146
  </details>
147
147
  <details class="compat-row" data-status="ok">
148
148
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">Messaging.enableLegacyHttpTransport(): void</code><span class="compat-sub"><span class="compat-behavior">Forces HTTP/1.1 transport for <code>sendEach</code> / <code>sendEachForMulticast</code>; deprecated.</span></span></span></summary>
149
- <div class="compat-evidence"><div class="compat-probe">Upstream typings/JSDoc (firebase-admin 13.10.0 <code>messaging</code>, <code>@deprecated</code>); no observation yet.</div></div>
149
+ <div class="compat-evidence"><div class="compat-probe">Upstream typings/JSDoc (firebase-admin 13.10.0 <code>messaging</code>, <code>@deprecated</code>); no observation yet. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric-admin/test/messaging/oracle-conformance.test.ts#L253" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
150
150
  </details>
151
151
  </div>
152
152
  <h2 id="message-union--targets"><code>Message</code> union + targets</h2>
153
153
  <div class="compat-list">
154
154
  <details class="compat-row" data-status="ok">
155
155
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">type Message = TokenMessage | TopicMessage | ConditionMessage</code><span class="compat-sub"><span class="compat-behavior">A send payload carrying exactly one of token, topic, or condition.</span></span></span></summary>
156
- <div class="compat-evidence"><div class="compat-probe">Upstream typings (firebase-admin 13.10.0 <code>messaging-api</code>); no observation yet.</div></div>
156
+ <div class="compat-evidence"><div class="compat-probe">Upstream typings (firebase-admin 13.10.0 <code>messaging-api</code>); no observation yet. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric-admin/test/messaging/oracle-conformance.test.ts#L63" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
157
157
  </details>
158
158
  <details class="compat-row" data-status="ok">
159
159
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">interface BaseMessage { data?; notification?; android?; webpush?; apns?; fcmOptions? }</code><span class="compat-sub"><span class="compat-behavior">Common message fields shared by every target variant. Production accepts a message carrying ONLY a <code>notification</code> block and, separately, ONLY a <code>data</code> block — neither is individually required.</span></span></span></summary>
160
- <div class="compat-evidence"><div class="compat-probe">oracle: <code>messaging-send-notification-only-vs-data-only-accepted.json</code> (both accepted). Replayed by the conformance suite.</div></div>
160
+ <div class="compat-evidence"><div class="compat-probe">oracle: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/messaging-admin/messaging-send-notification-only-vs-data-only-accepted.json" target="_blank" rel="noopener noreferrer"><code>messaging-send-notification-only-vs-data-only-accepted.json</code></a> (both accepted). Replayed by the conformance suite. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric-admin/test/messaging/oracle-conformance.test.ts#L214" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
161
161
  </details>
162
162
  <details class="compat-row" data-status="ok">
163
163
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">interface TokenMessage extends BaseMessage { token: string }</code><span class="compat-sub"><span class="compat-behavior">A device-token target. A syntactically invalid token is rejected with HTTP 400 INVALID_ARGUMENT whose fieldViolations name <code>message.token</code>.</span></span></span></summary>
164
- <div class="compat-evidence"><div class="compat-probe">oracle: <code>messaging-send-invalid-token-error-envelope.json</code> (fieldViolations names message.token). Replayed by the conformance suite.</div></div>
164
+ <div class="compat-evidence"><div class="compat-probe">oracle: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/messaging-admin/messaging-send-invalid-token-error-envelope.json" target="_blank" rel="noopener noreferrer"><code>messaging-send-invalid-token-error-envelope.json</code></a> (fieldViolations names message.token). Replayed by the conformance suite. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric-admin/test/messaging/oracle-conformance.test.ts#L225" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
165
165
  </details>
166
166
  <details class="compat-row" data-status="ok">
167
167
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">interface TopicMessage extends BaseMessage { topic: string }</code><span class="compat-sub"><span class="compat-behavior">A topic target. A well-formed topic send is accepted and returns the standard resource name (no subscribers required); a topic name containing characters outside the documented <code>[a-zA-Z0-9-_.~%]</code> set is rejected with an INVALID_ARGUMENT error envelope.</span></span></span></summary>
168
- <div class="compat-evidence"><div class="compat-probe">oracle: <code>messaging-send-topic-accepted.json</code> (accepted) + <code>messaging-send-invalid-topic-name-error-envelope.json</code> (bad name rejected). Replayed by the conformance suite.</div></div>
168
+ <div class="compat-evidence"><div class="compat-probe">oracle: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/messaging-admin/messaging-send-topic-accepted.json" target="_blank" rel="noopener noreferrer"><code>messaging-send-topic-accepted.json</code></a> (accepted) + <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/messaging-admin/messaging-send-invalid-topic-name-error-envelope.json" target="_blank" rel="noopener noreferrer"><code>messaging-send-invalid-topic-name-error-envelope.json</code></a> (bad name rejected). Replayed by the conformance suite. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric-admin/test/messaging/oracle-conformance.test.ts#L208" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
169
169
  </details>
170
170
  <details class="compat-row" data-status="ok">
171
171
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">interface ConditionMessage extends BaseMessage { condition: string }</code><span class="compat-sub"><span class="compat-behavior">A condition target. A well-formed condition of the form <code>"'a' in topics &#x26;&#x26; 'b' in topics"</code> is accepted with the standard resource-name shape (no subscribers required); a malformed condition (dangling operator) is rejected with an error envelope.</span></span></span></summary>
172
- <div class="compat-evidence"><div class="compat-probe">oracle: <code>messaging-send-condition-accepted.json</code> (accepted) + <code>messaging-send-invalid-condition-error-envelope.json</code> (malformed rejected). Replayed by the conformance suite.</div></div>
172
+ <div class="compat-evidence"><div class="compat-probe">oracle: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/messaging-admin/messaging-send-condition-accepted.json" target="_blank" rel="noopener noreferrer"><code>messaging-send-condition-accepted.json</code></a> (accepted) + <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/messaging-admin/messaging-send-invalid-condition-error-envelope.json" target="_blank" rel="noopener noreferrer"><code>messaging-send-invalid-condition-error-envelope.json</code></a> (malformed rejected). Replayed by the conformance suite. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric-admin/test/messaging/oracle-conformance.test.ts#L209" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
173
173
  </details>
174
174
  <details class="compat-row" data-status="ok">
175
175
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">interface MulticastMessage extends BaseMessage { tokens: string[] }</code><span class="compat-sub"><span class="compat-behavior">A multicast target of up to 500 tokens, fanned out by <code>sendEachForMulticast</code>.</span></span></span></summary>
176
- <div class="compat-evidence"><div class="compat-probe">Upstream typings (firebase-admin 13.10.0 <code>messaging-api</code>); no observation yet.</div></div>
176
+ <div class="compat-evidence"><div class="compat-probe">Upstream typings (firebase-admin 13.10.0 <code>messaging-api</code>); no observation yet. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric-admin/test/messaging/oracle-conformance.test.ts#L298" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
177
177
  </details>
178
178
  </div>
179
179
  <h2 id="payload--config-option-shapes">Payload / config option shapes</h2>
180
180
  <div class="compat-list">
181
181
  <details class="compat-row" data-status="ok">
182
182
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">interface Notification { title?; body?; imageUrl? }</code><span class="compat-sub"><span class="compat-behavior">Top-level, platform-independent notification block. Production accepts a notification-only message (no data block).</span></span></span></summary>
183
- <div class="compat-evidence"><div class="compat-probe">oracle: <code>messaging-send-notification-only-vs-data-only-accepted.json</code>. Replayed by the conformance suite.</div></div>
183
+ <div class="compat-evidence"><div class="compat-probe">oracle: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/messaging-admin/messaging-send-notification-only-vs-data-only-accepted.json" target="_blank" rel="noopener noreferrer"><code>messaging-send-notification-only-vs-data-only-accepted.json</code></a>. Replayed by the conformance suite. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric-admin/test/messaging/oracle-conformance.test.ts#L214" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
184
184
  </details>
185
185
  <details class="compat-row" data-status="ok">
186
186
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">interface FcmOptions { analyticsLabel? }</code><span class="compat-sub"><span class="compat-behavior">Platform-independent FCM options (<code>analyticsLabel</code>).</span></span></span></summary>
187
- <div class="compat-evidence"><div class="compat-probe">Upstream typings (firebase-admin 13.10.0 <code>messaging-api</code>); no observation yet.</div></div>
187
+ <div class="compat-evidence"><div class="compat-probe">Upstream typings (firebase-admin 13.10.0 <code>messaging-api</code>); no observation yet. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric-admin/test/messaging/oracle-conformance.test.ts#L309" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
188
188
  </details>
189
189
  <details class="compat-row" data-status="ok">
190
190
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">interface WebpushConfig { headers?; data?; notification?; fcmOptions? }</code><span class="compat-sub"><span class="compat-behavior">Webpush overrides. Production accepts a webpush config carrying <code>headers.TTL</code> and <code>fcmOptions.link</code>; a non-numeric <code>headers.TTL</code> is rejected with an error envelope.</span></span></span></summary>
191
- <div class="compat-evidence"><div class="compat-probe">oracle: <code>messaging-send-webpush-config-accepted.json</code> (accepted) + <code>messaging-send-webpush-invalid-ttl-error-envelope.json</code> (bad TTL rejected). Replayed by the conformance suite.</div></div>
191
+ <div class="compat-evidence"><div class="compat-probe">oracle: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/messaging-admin/messaging-send-webpush-config-accepted.json" target="_blank" rel="noopener noreferrer"><code>messaging-send-webpush-config-accepted.json</code></a> (accepted) + <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/messaging-admin/messaging-send-webpush-invalid-ttl-error-envelope.json" target="_blank" rel="noopener noreferrer"><code>messaging-send-webpush-invalid-ttl-error-envelope.json</code></a> (bad TTL rejected). Replayed by the conformance suite. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric-admin/test/messaging/oracle-conformance.test.ts#L210" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
192
192
  </details>
193
193
  <details class="compat-row" data-status="ok">
194
194
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">interface WebpushFcmOptions { link? }</code><span class="compat-sub"><span class="compat-behavior">Webpush FCM options (<code>link</code>, HTTPS required). Production accepts <code>fcmOptions.link</code> on a webpush send.</span></span></span></summary>
195
- <div class="compat-evidence"><div class="compat-probe">oracle: <code>messaging-send-webpush-config-accepted.json</code> (link accepted). Replayed by the conformance suite.</div></div>
195
+ <div class="compat-evidence"><div class="compat-probe">oracle: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/messaging-admin/messaging-send-webpush-config-accepted.json" target="_blank" rel="noopener noreferrer"><code>messaging-send-webpush-config-accepted.json</code></a> (link accepted). Replayed by the conformance suite. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric-admin/test/messaging/oracle-conformance.test.ts#L210" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
196
196
  </details>
197
197
  <details class="compat-row" data-status="ok">
198
198
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">interface WebpushNotification { title?; actions?; badge?; body?; dir?; icon?; image?; renotify?; requireInteraction?; silent?; tag?; vibrate?; [key] }</code><span class="compat-sub"><span class="compat-behavior">Web Notification API-shaped options, including an open-ended index signature.</span></span></span></summary>
199
- <div class="compat-evidence"><div class="compat-probe">Upstream typings (firebase-admin 13.10.0 <code>messaging-api</code>); no observation yet.</div></div>
199
+ <div class="compat-evidence"><div class="compat-probe">Upstream typings (firebase-admin 13.10.0 <code>messaging-api</code>); no observation yet. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric-admin/test/messaging/oracle-conformance.test.ts#L333" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
200
200
  </details>
201
201
  <details class="compat-row" data-status="ok">
202
202
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">interface ApnsConfig { liveActivityToken?; headers?; payload?; fcmOptions? }</code><span class="compat-sub"><span class="compat-behavior">APNs overrides.</span></span></span></summary>
203
- <div class="compat-evidence"><div class="compat-probe">Upstream typings (firebase-admin 13.10.0 <code>messaging-api</code>); no observation yet.</div></div>
203
+ <div class="compat-evidence"><div class="compat-probe">Upstream typings (firebase-admin 13.10.0 <code>messaging-api</code>); no observation yet. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric-admin/test/messaging/oracle-conformance.test.ts#L334" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
204
204
  </details>
205
205
  <details class="compat-row" data-status="ok">
206
206
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">interface ApnsPayload { aps; [customData] }</code><span class="compat-sub"><span class="compat-behavior">APNs payload wrapper carrying the required <code>aps</code> dictionary plus arbitrary custom keys.</span></span></span></summary>
207
- <div class="compat-evidence"><div class="compat-probe">Upstream typings (firebase-admin 13.10.0 <code>messaging-api</code>); no observation yet.</div></div>
207
+ <div class="compat-evidence"><div class="compat-probe">Upstream typings (firebase-admin 13.10.0 <code>messaging-api</code>); no observation yet. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric-admin/test/messaging/oracle-conformance.test.ts#L335" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
208
208
  </details>
209
209
  <details class="compat-row" data-status="ok">
210
210
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">interface Aps { alert?; badge?; sound?; contentAvailable?; mutableContent?; category?; threadId?; [customData] }</code><span class="compat-sub"><span class="compat-behavior">APNs <code>aps</code> dictionary; <code>alert</code> is a string or an <code>ApsAlert</code>, <code>sound</code> a string or a <code>CriticalSound</code>.</span></span></span></summary>
211
- <div class="compat-evidence"><div class="compat-probe">Upstream typings (firebase-admin 13.10.0 <code>messaging-api</code>); no observation yet.</div></div>
211
+ <div class="compat-evidence"><div class="compat-probe">Upstream typings (firebase-admin 13.10.0 <code>messaging-api</code>); no observation yet. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric-admin/test/messaging/oracle-conformance.test.ts#L336" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
212
212
  </details>
213
213
  <details class="compat-row" data-status="ok">
214
214
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">interface ApsAlert { title?; subtitle?; body?; locKey?; locArgs?; ...; launchImage? }</code><span class="compat-sub"><span class="compat-behavior">APNs alert object with title/subtitle/body and localization keys.</span></span></span></summary>
215
- <div class="compat-evidence"><div class="compat-probe">Upstream typings (firebase-admin 13.10.0 <code>messaging-api</code>); no observation yet.</div></div>
215
+ <div class="compat-evidence"><div class="compat-probe">Upstream typings (firebase-admin 13.10.0 <code>messaging-api</code>); no observation yet. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric-admin/test/messaging/oracle-conformance.test.ts#L337" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
216
216
  </details>
217
217
  <details class="compat-row" data-status="ok">
218
218
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">interface CriticalSound { critical?; name; volume? }</code><span class="compat-sub"><span class="compat-behavior">APNs critical sound — <code>name</code> required; <code>volume</code> in the range 0.0–1.0.</span></span></span></summary>
219
- <div class="compat-evidence"><div class="compat-probe">Upstream typings (firebase-admin 13.10.0 <code>messaging-api</code>); no observation yet.</div></div>
219
+ <div class="compat-evidence"><div class="compat-probe">Upstream typings (firebase-admin 13.10.0 <code>messaging-api</code>); no observation yet. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric-admin/test/messaging/oracle-conformance.test.ts#L338" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
220
220
  </details>
221
221
  <details class="compat-row" data-status="ok">
222
222
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">interface ApnsFcmOptions { analyticsLabel?; imageUrl? }</code><span class="compat-sub"><span class="compat-behavior">APNs FCM options (<code>analyticsLabel</code>, <code>imageUrl</code>).</span></span></span></summary>
223
- <div class="compat-evidence"><div class="compat-probe">Upstream typings (firebase-admin 13.10.0 <code>messaging-api</code>); no observation yet.</div></div>
223
+ <div class="compat-evidence"><div class="compat-probe">Upstream typings (firebase-admin 13.10.0 <code>messaging-api</code>); no observation yet. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric-admin/test/messaging/oracle-conformance.test.ts#L339" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
224
224
  </details>
225
225
  <details class="compat-row" data-status="ok">
226
226
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">interface AndroidConfig { collapseKey?; priority?; ttl?; restrictedPackageName?; data?; notification?; fcmOptions?; ... }</code><span class="compat-sub"><span class="compat-behavior">Android overrides; <code>ttl</code> is in milliseconds and <code>priority</code> is <code>high</code> | <code>normal</code>.</span></span></span></summary>
227
- <div class="compat-evidence"><div class="compat-probe">Upstream typings (firebase-admin 13.10.0 <code>messaging-api</code>); no observation yet.</div></div>
227
+ <div class="compat-evidence"><div class="compat-probe">Upstream typings (firebase-admin 13.10.0 <code>messaging-api</code>); no observation yet. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric-admin/test/messaging/oracle-conformance.test.ts#L340" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
228
228
  </details>
229
229
  <details class="compat-row" data-status="ok">
230
230
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">interface AndroidNotification { title?; body?; icon?; color?; sound?; tag?; imageUrl?; channelId?; priority?; visibility?; lightSettings?; ... }</code><span class="compat-sub"><span class="compat-behavior">Android notification options, including localization keys, LED light settings, and delivery-proxy controls.</span></span></span></summary>
231
- <div class="compat-evidence"><div class="compat-probe">Upstream typings (firebase-admin 13.10.0 <code>messaging-api</code>); no observation yet.</div></div>
231
+ <div class="compat-evidence"><div class="compat-probe">Upstream typings (firebase-admin 13.10.0 <code>messaging-api</code>); no observation yet. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric-admin/test/messaging/oracle-conformance.test.ts#L341" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
232
232
  </details>
233
233
  <details class="compat-row" data-status="ok">
234
234
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">interface LightSettings { color; lightOnDurationMillis; lightOffDurationMillis }</code><span class="compat-sub"><span class="compat-behavior">Android LED light settings — all three fields required.</span></span></span></summary>
235
- <div class="compat-evidence"><div class="compat-probe">Upstream typings (firebase-admin 13.10.0 <code>messaging-api</code>); no observation yet.</div></div>
235
+ <div class="compat-evidence"><div class="compat-probe">Upstream typings (firebase-admin 13.10.0 <code>messaging-api</code>); no observation yet. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric-admin/test/messaging/oracle-conformance.test.ts#L342" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
236
236
  </details>
237
237
  <details class="compat-row" data-status="ok">
238
238
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">interface AndroidFcmOptions { analyticsLabel? }</code><span class="compat-sub"><span class="compat-behavior">Android FCM options (<code>analyticsLabel</code>).</span></span></span></summary>
239
- <div class="compat-evidence"><div class="compat-probe">Upstream typings (firebase-admin 13.10.0 <code>messaging-api</code>); no observation yet.</div></div>
239
+ <div class="compat-evidence"><div class="compat-probe">Upstream typings (firebase-admin 13.10.0 <code>messaging-api</code>); no observation yet. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric-admin/test/messaging/oracle-conformance.test.ts#L343" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
240
240
  </details>
241
241
  </div>
242
242
  <h2 id="legacy-payload-shapes">Legacy payload shapes</h2>
243
243
  <div class="compat-list">
244
244
  <details class="compat-row" data-status="ok">
245
245
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">interface DataMessagePayload { [key]: string }</code><span class="compat-sub"><span class="compat-behavior">Legacy data payload — up to 4KB; the keys <code>from</code> and <code>google.*</code> are reserved.</span></span></span></summary>
246
- <div class="compat-evidence"><div class="compat-probe">Upstream typings (firebase-admin 13.10.0 <code>messaging-api</code>); no observation yet.</div></div>
246
+ <div class="compat-evidence"><div class="compat-probe">Upstream typings (firebase-admin 13.10.0 <code>messaging-api</code>); no observation yet. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric-admin/test/messaging/oracle-conformance.test.ts#L346" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
247
247
  </details>
248
248
  <details class="compat-row" data-status="ok">
249
249
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">interface NotificationMessagePayload { tag?; body?; icon?; badge?; color?; sound?; title?; ...; [key] }</code><span class="compat-sub"><span class="compat-behavior">Legacy notification payload with localization keys, a <code>clickAction</code>, and arbitrary string keys.</span></span></span></summary>
250
- <div class="compat-evidence"><div class="compat-probe">Upstream typings (firebase-admin 13.10.0 <code>messaging-api</code>); no observation yet.</div></div>
250
+ <div class="compat-evidence"><div class="compat-probe">Upstream typings (firebase-admin 13.10.0 <code>messaging-api</code>); no observation yet. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric-admin/test/messaging/oracle-conformance.test.ts#L347" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
251
251
  </details>
252
252
  <details class="compat-row" data-status="ok">
253
253
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">interface MessagingPayload { data?; notification? }</code><span class="compat-sub"><span class="compat-behavior">Legacy combined payload — one or both of <code>data</code> / <code>notification</code> required.</span></span></span></summary>
254
- <div class="compat-evidence"><div class="compat-probe">Upstream typings (firebase-admin 13.10.0 <code>messaging-api</code>); no observation yet.</div></div>
254
+ <div class="compat-evidence"><div class="compat-probe">Upstream typings (firebase-admin 13.10.0 <code>messaging-api</code>); no observation yet. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric-admin/test/messaging/oracle-conformance.test.ts#L348" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
255
255
  </details>
256
256
  <details class="compat-row" data-status="ok">
257
257
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">interface MessagingOptions { dryRun?; priority?; timeToLive?; collapseKey?; mutableContent?; contentAvailable?; restrictedPackageName?; [key] }</code><span class="compat-sub"><span class="compat-behavior">Legacy send options; documented defaults are dryRun false, ttl 2419200s (4 weeks), priority high for notifications / normal for data.</span></span></span></summary>
258
- <div class="compat-evidence"><div class="compat-probe">Upstream typings (firebase-admin 13.10.0 <code>messaging-api</code>); no observation yet.</div></div>
258
+ <div class="compat-evidence"><div class="compat-probe">Upstream typings (firebase-admin 13.10.0 <code>messaging-api</code>); no observation yet. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric-admin/test/messaging/oracle-conformance.test.ts#L349" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
259
259
  </details>
260
260
  </div>
261
261
  <h2 id="response-shapes">Response shapes</h2>
262
262
  <div class="compat-list">
263
263
  <details class="compat-row" data-status="ok">
264
264
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">interface MessagingTopicManagementResponse { failureCount; successCount; errors }</code><span class="compat-sub"><span class="compat-behavior">Topic subscribe / unsubscribe result carrying per-index errors as <code>FirebaseArrayIndexError[]</code>.</span></span></span></summary>
265
- <div class="compat-evidence"><div class="compat-probe">Upstream typings (firebase-admin 13.10.0 <code>messaging-api</code>); no observation yet.</div></div>
265
+ <div class="compat-evidence"><div class="compat-probe">Upstream typings (firebase-admin 13.10.0 <code>messaging-api</code>); no observation yet. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric-admin/test/messaging/oracle-conformance.test.ts#L352" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
266
266
  </details>
267
267
  <details class="compat-row" data-status="ok">
268
268
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">interface BatchResponse { responses; successCount; failureCount }</code><span class="compat-sub"><span class="compat-behavior">Batch send result; <code>responses</code> is a <code>SendResponse[]</code>.</span></span></span></summary>
269
- <div class="compat-evidence"><div class="compat-probe">Upstream typings (firebase-admin 13.10.0 <code>messaging-api</code>); no observation yet.</div></div>
269
+ <div class="compat-evidence"><div class="compat-probe">Upstream typings (firebase-admin 13.10.0 <code>messaging-api</code>); no observation yet. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric-admin/test/messaging/oracle-conformance.test.ts#L353" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
270
270
  </details>
271
271
  <details class="compat-row" data-status="ok">
272
272
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">interface SendResponse { success; messageId?; error? }</code><span class="compat-sub"><span class="compat-behavior">Per-message batch entry — on success <code>messageId</code> is set, on failure <code>error</code> is set.</span></span></span></summary>
273
- <div class="compat-evidence"><div class="compat-probe">Upstream typings (firebase-admin 13.10.0 <code>messaging-api</code>); no observation yet.</div></div>
273
+ <div class="compat-evidence"><div class="compat-probe">Upstream typings (firebase-admin 13.10.0 <code>messaging-api</code>); no observation yet. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric-admin/test/messaging/oracle-conformance.test.ts#L354" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
274
274
  </details>
275
275
  </div>
276
276
  <h2 id="errors">Errors</h2>
277
277
  <div class="compat-list">
278
278
  <details class="compat-row" data-status="ok">
279
279
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">class FirebaseMessagingError extends PrefixedFirebaseError</code><span class="compat-sub"><span class="compat-behavior">The exported admin messaging error type.</span></span></span></summary>
280
- <div class="compat-evidence"><div class="compat-probe">Upstream typings (firebase-admin 13.10.0 <code>lib/messaging/index</code>); no observation yet.</div></div>
280
+ <div class="compat-evidence"><div class="compat-probe">Upstream typings (firebase-admin 13.10.0 <code>lib/messaging/index</code>); no observation yet. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric-admin/test/messaging/oracle-conformance.test.ts#L357" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
281
281
  </details>
282
282
  <details class="compat-row" data-status="ok">
283
283
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">class MessagingClientErrorCode</code><span class="compat-sub"><span class="compat-behavior">Exported static <code>{ code, message }</code> members (<code>INVALID_ARGUMENT</code>, <code>INVALID_RECIPIENT</code>, <code>INVALID_PAYLOAD</code>, … <code>UNKNOWN_ERROR</code>). The wire-level <code>INVALID_ARGUMENT</code> FcmError returned by malformed sends maps to <code>MessagingClientErrorCode.INVALID_ARGUMENT</code>.</span></span></span></summary>
284
- <div class="compat-evidence"><div class="compat-probe">oracle: <code>messaging-send-no-target-error-envelope.json</code> + <code>messaging-send-invalid-token-error-envelope.json</code> (both carry the INVALID_ARGUMENT FcmError). Replayed by the conformance suite.</div></div>
284
+ <div class="compat-evidence"><div class="compat-probe">oracle: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/messaging-admin/messaging-send-no-target-error-envelope.json" target="_blank" rel="noopener noreferrer"><code>messaging-send-no-target-error-envelope.json</code></a> + <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/messaging-admin/messaging-send-invalid-token-error-envelope.json" target="_blank" rel="noopener noreferrer"><code>messaging-send-invalid-token-error-envelope.json</code></a> (both carry the INVALID_ARGUMENT FcmError). Replayed by the conformance suite. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric-admin/test/messaging/oracle-conformance.test.ts#L156" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
285
285
  </details>
286
286
  </div>
287
287
  <h2 id="behavior-classes--quota-retry-offline-delivery-send-plane">Behavior classes — quota, retry, offline delivery (send plane)</h2>