@pyric/cli 0.1.0-alpha.20 → 0.1.0-alpha.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (491) hide show
  1. package/README.md +64 -89
  2. package/dist/assurance/.generated/conformance-verdicts.d.ts +68 -1
  3. package/dist/assurance/.generated/conformance-verdicts.d.ts.map +1 -1
  4. package/dist/assurance/.generated/conformance-verdicts.js +68 -1
  5. package/dist/assurance/.generated/conformance-verdicts.js.map +1 -1
  6. package/dist/bridge/client/dispatch.d.ts +25 -19
  7. package/dist/bridge/client/dispatch.d.ts.map +1 -1
  8. package/dist/bridge/client/dispatch.js +41 -48
  9. package/dist/bridge/client/dispatch.js.map +1 -1
  10. package/dist/bridge/client/tool-family-factories.d.ts +26 -0
  11. package/dist/bridge/client/tool-family-factories.d.ts.map +1 -0
  12. package/dist/bridge/client/tool-family-factories.js +10 -0
  13. package/dist/bridge/client/tool-family-factories.js.map +1 -0
  14. package/dist/bridge/server/mcp-contract.d.ts +7 -6
  15. package/dist/bridge/server/mcp-contract.d.ts.map +1 -1
  16. package/dist/bridge/server/mcp-contract.js +9 -48
  17. package/dist/bridge/server/mcp-contract.js.map +1 -1
  18. package/dist/bridge/server/peer.d.ts +11 -1
  19. package/dist/bridge/server/peer.d.ts.map +1 -1
  20. package/dist/bridge/server/peer.js +22 -1
  21. package/dist/bridge/server/peer.js.map +1 -1
  22. package/dist/bridge/server/tool-family-factories.d.ts +30 -0
  23. package/dist/bridge/server/tool-family-factories.d.ts.map +1 -0
  24. package/dist/bridge/server/tool-family-factories.js +22 -0
  25. package/dist/bridge/server/tool-family-factories.js.map +1 -0
  26. package/dist/bridge/server/tool-metadata.d.ts +17 -18
  27. package/dist/bridge/server/tool-metadata.d.ts.map +1 -1
  28. package/dist/bridge/server/tool-metadata.js +24 -59
  29. package/dist/bridge/server/tool-metadata.js.map +1 -1
  30. package/dist/bridge/tool-families.d.ts +48 -0
  31. package/dist/bridge/tool-families.d.ts.map +1 -0
  32. package/dist/bridge/tool-families.generated.d.ts +32 -0
  33. package/dist/bridge/tool-families.generated.d.ts.map +1 -0
  34. package/dist/bridge/tool-families.generated.js +15 -0
  35. package/dist/bridge/tool-families.generated.js.map +1 -0
  36. package/dist/bridge/tool-families.js +51 -0
  37. package/dist/bridge/tool-families.js.map +1 -0
  38. package/dist/bridge/tool-family-records/conformance.d.ts +7 -0
  39. package/dist/bridge/tool-family-records/conformance.d.ts.map +1 -0
  40. package/dist/bridge/tool-family-records/conformance.js +6 -0
  41. package/dist/bridge/tool-family-records/conformance.js.map +1 -0
  42. package/dist/bridge/tool-family-records/firestore-data.d.ts +7 -0
  43. package/dist/bridge/tool-family-records/firestore-data.d.ts.map +1 -0
  44. package/dist/bridge/tool-family-records/firestore-data.js +15 -0
  45. package/dist/bridge/tool-family-records/firestore-data.js.map +1 -0
  46. package/dist/bridge/tool-family-records/firestore-inspect.d.ts +7 -0
  47. package/dist/bridge/tool-family-records/firestore-inspect.d.ts.map +1 -0
  48. package/dist/bridge/tool-family-records/firestore-inspect.js +6 -0
  49. package/dist/bridge/tool-family-records/firestore-inspect.js.map +1 -0
  50. package/dist/bridge/tool-family-records/firestore-rules.d.ts +7 -0
  51. package/dist/bridge/tool-family-records/firestore-rules.d.ts.map +1 -0
  52. package/dist/bridge/tool-family-records/firestore-rules.js +15 -0
  53. package/dist/bridge/tool-family-records/firestore-rules.js.map +1 -0
  54. package/dist/bridge/tool-family-records/firestore-simulator.d.ts +7 -0
  55. package/dist/bridge/tool-family-records/firestore-simulator.d.ts.map +1 -0
  56. package/dist/bridge/tool-family-records/firestore-simulator.js +16 -0
  57. package/dist/bridge/tool-family-records/firestore-simulator.js.map +1 -0
  58. package/dist/bridge/tool-family-records/rtdb-inspection.d.ts +7 -0
  59. package/dist/bridge/tool-family-records/rtdb-inspection.d.ts.map +1 -0
  60. package/dist/bridge/tool-family-records/rtdb-inspection.js +6 -0
  61. package/dist/bridge/tool-family-records/rtdb-inspection.js.map +1 -0
  62. package/dist/bundler/externals.d.ts +37 -0
  63. package/dist/bundler/externals.d.ts.map +1 -0
  64. package/dist/bundler/externals.js +52 -0
  65. package/dist/bundler/externals.js.map +1 -0
  66. package/dist/bundler/index.d.ts +17 -0
  67. package/dist/bundler/index.d.ts.map +1 -0
  68. package/dist/bundler/index.js +17 -0
  69. package/dist/bundler/index.js.map +1 -0
  70. package/dist/cli/inlined-sdk-scanner.d.ts +6 -0
  71. package/dist/cli/inlined-sdk-scanner.d.ts.map +1 -0
  72. package/dist/cli/inlined-sdk-scanner.js +82 -0
  73. package/dist/cli/inlined-sdk-scanner.js.map +1 -0
  74. package/dist/cli/sandbox-interlock.d.ts +97 -0
  75. package/dist/cli/sandbox-interlock.d.ts.map +1 -0
  76. package/dist/cli/sandbox-interlock.js +112 -0
  77. package/dist/cli/sandbox-interlock.js.map +1 -0
  78. package/dist/cli/sandbox-runner.d.ts +20 -12
  79. package/dist/cli/sandbox-runner.d.ts.map +1 -1
  80. package/dist/cli/sandbox-runner.js +24 -21
  81. package/dist/cli/sandbox-runner.js.map +1 -1
  82. package/dist/cli/serve.d.ts +6 -10
  83. package/dist/cli/serve.d.ts.map +1 -1
  84. package/dist/cli/serve.js +57 -77
  85. package/dist/cli/serve.js.map +1 -1
  86. package/dist/cli/unsupported-runtime.d.ts +27 -0
  87. package/dist/cli/unsupported-runtime.d.ts.map +1 -0
  88. package/dist/cli/unsupported-runtime.js +63 -0
  89. package/dist/cli/unsupported-runtime.js.map +1 -0
  90. package/dist/conformance/.generated/can-i-use-browser.d.ts +1 -1
  91. package/dist/conformance/.generated/can-i-use-browser.d.ts.map +1 -1
  92. package/dist/conformance/.generated/can-i-use-browser.js +1 -1
  93. package/dist/conformance/.generated/can-i-use-browser.js.map +1 -1
  94. package/dist/conformance/.generated/can-i-use.d.ts +1 -1
  95. package/dist/conformance/.generated/can-i-use.d.ts.map +1 -1
  96. package/dist/conformance/.generated/can-i-use.js +1 -1
  97. package/dist/conformance/.generated/can-i-use.js.map +1 -1
  98. package/dist/conformance/.generated/conformance-docs.d.ts.map +1 -1
  99. package/dist/conformance/.generated/conformance-docs.js +1 -1
  100. package/dist/conformance/.generated/conformance-docs.js.map +1 -1
  101. package/dist/functions-rtdb/child.d.ts +37 -0
  102. package/dist/functions-rtdb/child.d.ts.map +1 -1
  103. package/dist/functions-rtdb/child.js +90 -21
  104. package/dist/functions-rtdb/child.js.map +1 -1
  105. package/dist/functions-rtdb/development-runtime.d.ts +3 -0
  106. package/dist/functions-rtdb/development-runtime.d.ts.map +1 -1
  107. package/dist/functions-rtdb/development-runtime.js +1 -0
  108. package/dist/functions-rtdb/development-runtime.js.map +1 -1
  109. package/dist/google-endpoints.d.ts +67 -0
  110. package/dist/google-endpoints.d.ts.map +1 -0
  111. package/dist/google-endpoints.js +119 -0
  112. package/dist/google-endpoints.js.map +1 -0
  113. package/dist/next/runtime-env.d.ts.map +1 -1
  114. package/dist/next/runtime-env.js +5 -0
  115. package/dist/next/runtime-env.js.map +1 -1
  116. package/dist/next/with-pyric.d.ts +1 -1
  117. package/dist/next/with-pyric.js +1 -1
  118. package/dist/register/beacon.d.ts +69 -0
  119. package/dist/register/beacon.d.ts.map +1 -0
  120. package/dist/register/beacon.js +199 -0
  121. package/dist/register/beacon.js.map +1 -0
  122. package/dist/register/index.d.ts.map +1 -1
  123. package/dist/register/index.js +65 -6
  124. package/dist/register/index.js.map +1 -1
  125. package/dist/register/net-guard.d.ts +110 -0
  126. package/dist/register/net-guard.d.ts.map +1 -0
  127. package/dist/register/net-guard.js +462 -0
  128. package/dist/register/net-guard.js.map +1 -0
  129. package/dist/serve/ai-diagnostics-relay.d.ts +63 -0
  130. package/dist/serve/ai-diagnostics-relay.d.ts.map +1 -0
  131. package/dist/serve/ai-diagnostics-relay.js +125 -0
  132. package/dist/serve/ai-diagnostics-relay.js.map +1 -0
  133. package/dist/serve/ai-proxy.d.ts +92 -0
  134. package/dist/serve/ai-proxy.d.ts.map +1 -0
  135. package/dist/serve/ai-proxy.js +269 -0
  136. package/dist/serve/ai-proxy.js.map +1 -0
  137. package/dist/serve/ai-status.d.ts +44 -0
  138. package/dist/serve/ai-status.d.ts.map +1 -0
  139. package/dist/serve/ai-status.js +77 -0
  140. package/dist/serve/ai-status.js.map +1 -0
  141. package/dist/serve/ai-terminal-blocks.d.ts +97 -0
  142. package/dist/serve/ai-terminal-blocks.d.ts.map +1 -0
  143. package/dist/serve/ai-terminal-blocks.js +128 -0
  144. package/dist/serve/ai-terminal-blocks.js.map +1 -0
  145. package/dist/serve/ai-terminal-text.d.ts +36 -0
  146. package/dist/serve/ai-terminal-text.d.ts.map +1 -0
  147. package/dist/serve/ai-terminal-text.js +48 -0
  148. package/dist/serve/ai-terminal-text.js.map +1 -0
  149. package/dist/serve/beacon-route.d.ts +53 -0
  150. package/dist/serve/beacon-route.d.ts.map +1 -0
  151. package/dist/serve/beacon-route.js +101 -0
  152. package/dist/serve/beacon-route.js.map +1 -0
  153. package/dist/serve/entries/active-auth-registry.d.ts +16 -0
  154. package/dist/serve/entries/active-auth-registry.d.ts.map +1 -0
  155. package/dist/serve/entries/active-auth-registry.js +48 -0
  156. package/dist/serve/entries/active-auth-registry.js.map +1 -0
  157. package/dist/serve/entries/active-auth.d.ts +18 -0
  158. package/dist/serve/entries/active-auth.d.ts.map +1 -0
  159. package/dist/serve/entries/active-auth.js +84 -0
  160. package/dist/serve/entries/active-auth.js.map +1 -0
  161. package/dist/serve/entries/auth-helper-core.d.ts +1 -0
  162. package/dist/serve/entries/auth-helper-core.d.ts.map +1 -1
  163. package/dist/serve/entries/auth-helper-core.js +4 -0
  164. package/dist/serve/entries/auth-helper-core.js.map +1 -1
  165. package/dist/serve/entries/auth-helper-dom.d.ts.map +1 -1
  166. package/dist/serve/entries/auth-helper-dom.js +28 -2
  167. package/dist/serve/entries/auth-helper-dom.js.map +1 -1
  168. package/dist/serve/entries/auth.d.ts.map +1 -1
  169. package/dist/serve/entries/auth.js +8 -0
  170. package/dist/serve/entries/auth.js.map +1 -1
  171. package/dist/serve/entries/bridge-url.d.ts +1 -1
  172. package/dist/serve/entries/bridge-url.js +1 -1
  173. package/dist/serve/entries/init.d.ts.map +1 -1
  174. package/dist/serve/entries/init.js +70 -4
  175. package/dist/serve/entries/init.js.map +1 -1
  176. package/dist/serve/entries/runtime.d.ts.map +1 -1
  177. package/dist/serve/entries/runtime.js +9 -0
  178. package/dist/serve/entries/runtime.js.map +1 -1
  179. package/dist/serve/namespace.d.ts +14 -5
  180. package/dist/serve/namespace.d.ts.map +1 -1
  181. package/dist/serve/namespace.js +57 -124
  182. package/dist/serve/namespace.js.map +1 -1
  183. package/dist/serve/runtime/chip-config.d.ts.map +1 -1
  184. package/dist/serve/runtime/chip-config.js +16 -2
  185. package/dist/serve/runtime/chip-config.js.map +1 -1
  186. package/dist/serve/runtime/chip-dialog.d.ts +18 -0
  187. package/dist/serve/runtime/chip-dialog.d.ts.map +1 -0
  188. package/dist/serve/runtime/chip-dialog.js +315 -0
  189. package/dist/serve/runtime/chip-dialog.js.map +1 -0
  190. package/dist/serve/runtime/chip-install.d.ts +2 -0
  191. package/dist/serve/runtime/chip-install.d.ts.map +1 -1
  192. package/dist/serve/runtime/chip-install.js +9 -4
  193. package/dist/serve/runtime/chip-install.js.map +1 -1
  194. package/dist/serve/runtime/chip-user-search.d.ts +16 -0
  195. package/dist/serve/runtime/chip-user-search.d.ts.map +1 -0
  196. package/dist/serve/runtime/chip-user-search.js +354 -0
  197. package/dist/serve/runtime/chip-user-search.js.map +1 -0
  198. package/dist/serve/runtime/chip.d.ts +10 -0
  199. package/dist/serve/runtime/chip.d.ts.map +1 -1
  200. package/dist/serve/runtime/chip.js +118 -15
  201. package/dist/serve/runtime/chip.js.map +1 -1
  202. package/dist/serve/runtime/identity.d.ts +17 -0
  203. package/dist/serve/runtime/identity.d.ts.map +1 -0
  204. package/dist/serve/runtime/identity.js +10 -0
  205. package/dist/serve/runtime/identity.js.map +1 -0
  206. package/dist/serve/sandbox-session.d.ts +7 -0
  207. package/dist/serve/sandbox-session.d.ts.map +1 -1
  208. package/dist/serve/sandbox-session.js +2 -0
  209. package/dist/serve/sandbox-session.js.map +1 -1
  210. package/dist/serve/site-ui/_astro/{RulesCodeEditor.XtDmHOlN.js → RulesCodeEditor.DsTAsKIa.js} +1 -1
  211. package/dist/serve/site-ui/_astro/app.BOr2kwae.js +115 -0
  212. package/dist/serve/site-ui/_astro/app.DhAcImFD.js +1 -0
  213. package/dist/serve/site-ui/_astro/{chess-showcase.B72XYeoh.js → chess-showcase.Bn_pP6UJ.js} +2 -2
  214. package/dist/serve/site-ui/_astro/{example-runtime.C25_lx6Z.js → example-runtime.CXopTGv7.js} +1 -1
  215. package/dist/serve/site-ui/_astro/sandbox-controls.rOuZTOUG.js +510 -0
  216. package/dist/serve/site-ui/_astro/{seed.Co0yUJY5.js → seed.03a08f9t.js} +2 -2
  217. package/dist/serve/site-ui/_astro/writes.BsPBG3dp.js +653 -0
  218. package/dist/serve/site-ui/auth/index.html +1 -1
  219. package/dist/serve/site-ui/docs/_rhythm/index.html +1 -1
  220. package/dist/serve/site-ui/docs/agent/set-up-your-agent/index.html +1 -1
  221. package/dist/serve/site-ui/docs/agent/watch-and-review/index.html +1 -1
  222. package/dist/serve/site-ui/docs/agent/work-with-an-agent/index.html +1 -1
  223. package/dist/serve/site-ui/docs/ai-compat/index.html +1 -1
  224. package/dist/serve/site-ui/docs/api-reference/index.html +8 -1
  225. package/dist/serve/site-ui/docs/api-reference.md +7 -0
  226. package/dist/serve/site-ui/docs/app-compat/index.html +1 -1
  227. package/dist/serve/site-ui/docs/auth-compat/index.html +3 -3
  228. package/dist/serve/site-ui/docs/auth-compat.md +2 -2
  229. package/dist/serve/site-ui/docs/build/ai-logic/index.html +6 -1
  230. package/dist/serve/site-ui/docs/build/ai-logic.md +6 -0
  231. package/dist/serve/site-ui/docs/build/authentication/index.html +1 -1
  232. package/dist/serve/site-ui/docs/build/cloud-firestore/index.html +1 -1
  233. package/dist/serve/site-ui/docs/build/cloud-messaging/index.html +1 -1
  234. package/dist/serve/site-ui/docs/build/cloud-storage/index.html +1 -1
  235. package/dist/serve/site-ui/docs/build/realtime-database/index.html +1 -1
  236. package/dist/serve/site-ui/docs/conformance-scores/index.html +6 -2
  237. package/dist/serve/site-ui/docs/conformance-scores.md +5 -1
  238. package/dist/serve/site-ui/docs/create-pyric-reference-api/index.html +1 -1
  239. package/dist/serve/site-ui/docs/database-compat/index.html +44 -44
  240. package/dist/serve/site-ui/docs/database-compat.md +43 -43
  241. package/dist/serve/site-ui/docs/examples/chess/index.html +1 -1
  242. package/dist/serve/site-ui/docs/examples/index.html +1 -1
  243. package/dist/serve/site-ui/docs/firestore-compat/index.html +4 -4
  244. package/dist/serve/site-ui/docs/firestore-compat.md +3 -3
  245. package/dist/serve/site-ui/docs/firestore-flutter-compat/index.html +319 -0
  246. package/dist/serve/site-ui/docs/firestore-flutter-compat.md +344 -0
  247. package/dist/serve/site-ui/docs/functions-rtdb-compat/index.html +1 -1
  248. package/dist/serve/site-ui/docs/get-started/backend-bundlers/index.html +105 -0
  249. package/dist/serve/site-ui/docs/get-started/backend-bundlers.md +165 -0
  250. package/dist/serve/site-ui/docs/get-started/how-the-swap-works/index.html +1 -1
  251. package/dist/serve/site-ui/docs/get-started/nextjs/index.html +1 -1
  252. package/dist/serve/site-ui/docs/get-started/start-building/index.html +1 -1
  253. package/dist/serve/site-ui/docs/get-started/vite/index.html +1 -1
  254. package/dist/serve/site-ui/docs/index.json +2967 -1482
  255. package/dist/serve/site-ui/docs/messaging-compat/index.html +1 -1
  256. package/dist/serve/site-ui/docs/observe/resolve-runtime-status/index.html +1 -1
  257. package/dist/serve/site-ui/docs/observe/see-whats-happening/index.html +1 -1
  258. package/dist/serve/site-ui/docs/observe/shape-your-data/index.html +1 -1
  259. package/dist/serve/site-ui/docs/overview/index.html +1 -1
  260. package/dist/serve/site-ui/docs/pyric-admin-app-reference-api/index.html +1 -1
  261. package/dist/serve/site-ui/docs/pyric-admin-auth-reference-api/index.html +1 -1
  262. package/dist/serve/site-ui/docs/pyric-admin-database-reference-api/index.html +1 -1
  263. package/dist/serve/site-ui/docs/pyric-admin-firestore-reference-api/index.html +1 -1
  264. package/dist/serve/site-ui/docs/pyric-admin-messaging-reference-api/index.html +1 -1
  265. package/dist/serve/site-ui/docs/pyric-admin-reference-api/index.html +1 -1
  266. package/dist/serve/site-ui/docs/pyric-admin-storage-reference-api/index.html +1 -1
  267. package/dist/serve/site-ui/docs/pyric-ai-reference-api/index.html +1 -1
  268. package/dist/serve/site-ui/docs/pyric-ai-scripting-reference-api/index.html +1 -1
  269. package/dist/serve/site-ui/docs/pyric-analytics-reference-api/index.html +124 -0
  270. package/dist/serve/site-ui/docs/pyric-analytics-reference-api.md +287 -0
  271. package/dist/serve/site-ui/docs/pyric-app-check-reference-api/index.html +87 -0
  272. package/dist/serve/site-ui/docs/pyric-app-check-reference-api.md +199 -0
  273. package/dist/serve/site-ui/docs/pyric-app-reference-api/index.html +1 -1
  274. package/dist/serve/site-ui/docs/pyric-auth-reference-api/index.html +6 -2
  275. package/dist/serve/site-ui/docs/pyric-auth-reference-api.md +2 -1
  276. package/dist/serve/site-ui/docs/pyric-cli-assurance-browser-reference-api/index.html +1 -1
  277. package/dist/serve/site-ui/docs/pyric-cli-assurance-reference-api/index.html +1 -1
  278. package/dist/serve/site-ui/docs/pyric-cli-bridge-client-reference-api/index.html +2 -2
  279. package/dist/serve/site-ui/docs/pyric-cli-bridge-client-reference-api.md +1 -1
  280. package/dist/serve/site-ui/docs/pyric-cli-bridge-reference-api/index.html +1 -1
  281. package/dist/serve/site-ui/docs/pyric-cli-bundler-reference-api/index.html +56 -0
  282. package/dist/serve/site-ui/docs/pyric-cli-bundler-reference-api.md +72 -0
  283. package/dist/serve/site-ui/docs/pyric-cli-conformance-browser-reference-api/index.html +2 -1
  284. package/dist/serve/site-ui/docs/pyric-cli-conformance-browser-reference-api.md +1 -0
  285. package/dist/serve/site-ui/docs/pyric-cli-conformance-docs-reference-api/index.html +1 -1
  286. package/dist/serve/site-ui/docs/pyric-cli-conformance-reference-api/index.html +2 -1
  287. package/dist/serve/site-ui/docs/pyric-cli-conformance-reference-api.md +1 -0
  288. package/dist/serve/site-ui/docs/pyric-cli-credentials-node-reference-api/index.html +1 -1
  289. package/dist/serve/site-ui/docs/pyric-cli-discover-reference-api/index.html +1 -1
  290. package/dist/serve/site-ui/docs/pyric-cli-next-reference-api/index.html +2 -2
  291. package/dist/serve/site-ui/docs/pyric-cli-next-reference-api.md +1 -1
  292. package/dist/serve/site-ui/docs/pyric-cli-register-app-bridge-reference-api/index.html +1 -1
  293. package/dist/serve/site-ui/docs/pyric-cli-register-reference-api/index.html +1 -1
  294. package/dist/serve/site-ui/docs/pyric-cli-remote-reference-api/index.html +34 -9
  295. package/dist/serve/site-ui/docs/pyric-cli-remote-reference-api.md +16 -8
  296. package/dist/serve/site-ui/docs/pyric-cli-serve-worker-reference-api/index.html +133 -93
  297. package/dist/serve/site-ui/docs/pyric-cli-serve-worker-reference-api.md +61 -1
  298. package/dist/serve/site-ui/docs/pyric-cli-verify-reference-api/index.html +2 -2
  299. package/dist/serve/site-ui/docs/pyric-cli-verify-reference-api.md +1 -1
  300. package/dist/serve/site-ui/docs/pyric-cli-vite-reference-api/index.html +2 -2
  301. package/dist/serve/site-ui/docs/pyric-cli-vite-reference-api.md +2 -2
  302. package/dist/serve/site-ui/docs/pyric-database-reference-api/index.html +2 -2
  303. package/dist/serve/site-ui/docs/pyric-database-reference-api.md +1 -1
  304. package/dist/serve/site-ui/docs/pyric-firestore-lite-reference-api/index.html +559 -0
  305. package/dist/serve/site-ui/docs/pyric-firestore-lite-reference-api.md +1240 -0
  306. package/dist/serve/site-ui/docs/pyric-firestore-reference-api/index.html +40 -11
  307. package/dist/serve/site-ui/docs/pyric-firestore-reference-api.md +18 -8
  308. package/dist/serve/site-ui/docs/pyric-functions-reference-api/index.html +67 -0
  309. package/dist/serve/site-ui/docs/pyric-functions-reference-api.md +149 -0
  310. package/dist/serve/site-ui/docs/pyric-messaging-reference-api/index.html +1 -1
  311. package/dist/serve/site-ui/docs/pyric-messaging-sw-reference-api/index.html +1 -1
  312. package/dist/serve/site-ui/docs/pyric-performance-reference-api/index.html +35 -0
  313. package/dist/serve/site-ui/docs/pyric-performance-reference-api.md +69 -0
  314. package/dist/serve/site-ui/docs/pyric-remote-config-reference-api/index.html +132 -0
  315. package/dist/serve/site-ui/docs/pyric-remote-config-reference-api.md +307 -0
  316. package/dist/serve/site-ui/docs/pyric-rules-reference-api/index.html +1 -1
  317. package/dist/serve/site-ui/docs/pyric-sandbox-database-reference-api/index.html +52 -17
  318. package/dist/serve/site-ui/docs/pyric-sandbox-database-reference-api.md +48 -9
  319. package/dist/serve/site-ui/docs/pyric-sandbox-firestore-reference-api/index.html +1 -1
  320. package/dist/serve/site-ui/docs/pyric-sandbox-reference-api/index.html +239 -49
  321. package/dist/serve/site-ui/docs/pyric-sandbox-reference-api.md +148 -31
  322. package/dist/serve/site-ui/docs/pyric-storage-reference-api/index.html +22 -4
  323. package/dist/serve/site-ui/docs/pyric-storage-reference-api.md +24 -2
  324. package/dist/serve/site-ui/docs/pyric-ui-agents-reference-api/index.html +26 -96
  325. package/dist/serve/site-ui/docs/pyric-ui-agents-reference-api.md +20 -51
  326. package/dist/serve/site-ui/docs/pyric-ui-auth-hooks-reference-api/index.html +1 -1
  327. package/dist/serve/site-ui/docs/pyric-ui-auth-reference-api/index.html +2 -2
  328. package/dist/serve/site-ui/docs/pyric-ui-auth-reference-api.md +1 -1
  329. package/dist/serve/site-ui/docs/pyric-ui-events-hooks-reference-api/index.html +1 -1
  330. package/dist/serve/site-ui/docs/pyric-ui-events-reference-api/index.html +1 -1
  331. package/dist/serve/site-ui/docs/pyric-ui-firestore-hooks-reference-api/index.html +1 -1
  332. package/dist/serve/site-ui/docs/pyric-ui-firestore-reference-api/index.html +2 -2
  333. package/dist/serve/site-ui/docs/pyric-ui-firestore-reference-api.md +1 -1
  334. package/dist/serve/site-ui/docs/pyric-ui-primitives-reference-api/index.html +124 -26
  335. package/dist/serve/site-ui/docs/pyric-ui-primitives-reference-api.md +58 -5
  336. package/dist/serve/site-ui/docs/pyric-ui-rtdb-reference-api/index.html +1 -1
  337. package/dist/serve/site-ui/docs/pyric-ui-rules-hooks-reference-api/index.html +1 -1
  338. package/dist/serve/site-ui/docs/pyric-ui-rules-reference-api/index.html +1 -1
  339. package/dist/serve/site-ui/docs/pyric-ui-storage-hooks-reference-api/index.html +1 -1
  340. package/dist/serve/site-ui/docs/pyric-ui-storage-reference-api/index.html +4 -5
  341. package/dist/serve/site-ui/docs/pyric-ui-storage-reference-api.md +3 -4
  342. package/dist/serve/site-ui/docs/pyric-ui-traffic-hooks-reference-api/index.html +1 -1
  343. package/dist/serve/site-ui/docs/pyric-ui-traffic-reference-api/index.html +1 -1
  344. package/dist/serve/site-ui/docs/reference/cli/index.html +6 -3
  345. package/dist/serve/site-ui/docs/reference/cli.md +8 -2
  346. package/dist/serve/site-ui/docs/rules-compat/index.html +10 -2
  347. package/dist/serve/site-ui/docs/rules-compat.md +9 -1
  348. package/dist/serve/site-ui/docs/secure/audit-your-rules/index.html +1 -1
  349. package/dist/serve/site-ui/docs/secure/firestore-rules-limits/index.html +1 -1
  350. package/dist/serve/site-ui/docs/secure/read-a-denial/index.html +1 -1
  351. package/dist/serve/site-ui/docs/secure/rtdb-rules-in-typescript/index.html +1 -1
  352. package/dist/serve/site-ui/docs/secure/rules-standard-library/index.html +1 -1
  353. package/dist/serve/site-ui/docs/secure/secure-it-with-rules/index.html +1 -1
  354. package/dist/serve/site-ui/docs/secure/simulate-and-lint/index.html +1 -1
  355. package/dist/serve/site-ui/docs/secure/write-a-rules-test-suite/index.html +1 -1
  356. package/dist/serve/site-ui/docs/ship/ship-to-production/index.html +1 -1
  357. package/dist/serve/site-ui/docs/ship/test-in-node/index.html +1 -1
  358. package/dist/serve/site-ui/docs/storage-compat/index.html +13 -13
  359. package/dist/serve/site-ui/docs/storage-compat.md +12 -12
  360. package/dist/serve/site-ui/docs/trust/how-we-know-it-matches-firebase/index.html +1 -1
  361. package/dist/serve/site-ui/docs/trust/rules-standard-library/index.html +1 -1
  362. package/dist/serve/site-ui/docs/trust/versioning-and-compatibility/index.html +1 -1
  363. package/dist/serve/site-ui/docs/tutorial/index.html +1 -1
  364. package/dist/serve/site-ui/examples/chess/index.html +1 -1
  365. package/dist/serve/site-ui/firestore/index.html +1 -1
  366. package/dist/serve/site-ui/llms.txt +9 -0
  367. package/dist/serve/site-ui/rtdb/index.html +1 -1
  368. package/dist/serve/site-ui/settings/index.html +1 -1
  369. package/dist/serve/site-ui/storage/index.html +1 -1
  370. package/dist/serve/site-ui/studio/index.html +1 -1
  371. package/dist/serve/site-ui/traffic/index.html +1 -1
  372. package/dist/serve/studio/disk-workspace.d.ts.map +1 -1
  373. package/dist/serve/studio/disk-workspace.js +64 -2
  374. package/dist/serve/studio/disk-workspace.js.map +1 -1
  375. package/dist/serve/vite-plugin.d.ts +7 -7
  376. package/dist/serve/vite-plugin.js +1 -1
  377. package/dist/serve/vite-plugin.js.map +1 -1
  378. package/dist/serve/vite-sandbox-generation.d.ts.map +1 -1
  379. package/dist/serve/vite-sandbox-generation.js +12 -0
  380. package/dist/serve/vite-sandbox-generation.js.map +1 -1
  381. package/dist/serve/worker/client/auth.js +1 -2
  382. package/dist/serve/worker/client/auth.js.map +1 -1
  383. package/dist/serve/worker/client/core.d.ts +21 -1
  384. package/dist/serve/worker/client/core.d.ts.map +1 -1
  385. package/dist/serve/worker/client/core.js +79 -3
  386. package/dist/serve/worker/client/core.js.map +1 -1
  387. package/dist/serve/worker/client.d.ts +1 -1
  388. package/dist/serve/worker/client.d.ts.map +1 -1
  389. package/dist/serve/worker/client.js +1 -1
  390. package/dist/serve/worker/client.js.map +1 -1
  391. package/dist/serve/worker/context-resolver.d.ts +30 -0
  392. package/dist/serve/worker/context-resolver.d.ts.map +1 -0
  393. package/dist/serve/worker/context-resolver.js +44 -0
  394. package/dist/serve/worker/context-resolver.js.map +1 -0
  395. package/dist/serve/worker/entry.js +23 -19
  396. package/dist/serve/worker/entry.js.map +1 -1
  397. package/dist/serve/worker/host/core.d.ts +1 -0
  398. package/dist/serve/worker/host/core.d.ts.map +1 -1
  399. package/dist/serve/worker/host/core.js +12 -6
  400. package/dist/serve/worker/host/core.js.map +1 -1
  401. package/dist/serve/worker/host/storage.js +2 -2
  402. package/dist/serve/worker/host-auth.js +1 -2
  403. package/dist/serve/worker/host-auth.js.map +1 -1
  404. package/dist/serve/worker/index.d.ts +1 -1
  405. package/dist/serve/worker/index.d.ts.map +1 -1
  406. package/dist/serve/worker/index.js +2 -2
  407. package/dist/serve/worker/index.js.map +1 -1
  408. package/dist/serve/worker/port-lifecycle.d.ts +18 -0
  409. package/dist/serve/worker/port-lifecycle.d.ts.map +1 -0
  410. package/dist/serve/worker/port-lifecycle.js +28 -0
  411. package/dist/serve/worker/port-lifecycle.js.map +1 -0
  412. package/dist/serve/worker/serve-init.d.ts.map +1 -1
  413. package/dist/serve/worker/serve-init.js +8 -2
  414. package/dist/serve/worker/serve-init.js.map +1 -1
  415. package/dist/verify/fixture.d.ts +1 -1
  416. package/package.json +16 -5
  417. package/src/assurance/.generated/conformance-verdicts.ts +68 -1
  418. package/src/bridge/client/dispatch.ts +52 -56
  419. package/src/bridge/client/tool-family-factories.ts +34 -0
  420. package/src/bridge/server/mcp-contract.ts +15 -59
  421. package/src/bridge/server/peer.ts +24 -1
  422. package/src/bridge/server/tool-family-factories.ts +40 -0
  423. package/src/bridge/server/tool-metadata.ts +29 -61
  424. package/src/bridge/tool-families.generated.ts +17 -0
  425. package/src/bridge/tool-families.ts +87 -0
  426. package/src/bridge/tool-family-records/conformance.ts +6 -0
  427. package/src/bridge/tool-family-records/firestore-data.ts +15 -0
  428. package/src/bridge/tool-family-records/firestore-inspect.ts +6 -0
  429. package/src/bridge/tool-family-records/firestore-rules.ts +15 -0
  430. package/src/bridge/tool-family-records/firestore-simulator.ts +16 -0
  431. package/src/bridge/tool-family-records/rtdb-inspection.ts +6 -0
  432. package/src/bundler/externals.ts +55 -0
  433. package/src/bundler/index.ts +21 -0
  434. package/src/cli/cli.test.ts +0 -44
  435. package/src/cli/inlined-sdk-scanner.ts +77 -0
  436. package/src/cli/sandbox-interlock.ts +167 -0
  437. package/src/cli/sandbox-runner.ts +37 -26
  438. package/src/cli/serve.ts +68 -69
  439. package/src/cli/unsupported-runtime.ts +68 -0
  440. package/src/conformance/.generated/can-i-use-browser.ts +2 -2
  441. package/src/conformance/.generated/can-i-use.ts +2 -2
  442. package/src/conformance/.generated/conformance-docs.ts +1 -1
  443. package/src/functions-rtdb/child.ts +115 -21
  444. package/src/functions-rtdb/development-runtime.ts +4 -0
  445. package/src/google-endpoints.ts +155 -0
  446. package/src/next/runtime-env.ts +5 -0
  447. package/src/next/with-pyric.ts +1 -1
  448. package/src/register/beacon.ts +232 -0
  449. package/src/register/index.ts +68 -6
  450. package/src/register/net-guard.ts +567 -0
  451. package/src/serve/ai-diagnostics-relay.ts +243 -0
  452. package/src/serve/ai-proxy.ts +327 -0
  453. package/src/serve/ai-status.ts +109 -0
  454. package/src/serve/ai-terminal-blocks.ts +210 -0
  455. package/src/serve/ai-terminal-text.ts +52 -0
  456. package/src/serve/beacon-route.ts +141 -0
  457. package/src/serve/entries/active-auth-registry.ts +56 -0
  458. package/src/serve/entries/active-auth.ts +100 -0
  459. package/src/serve/entries/auth-helper-core.ts +5 -0
  460. package/src/serve/entries/auth-helper-dom.ts +26 -2
  461. package/src/serve/entries/auth.ts +8 -0
  462. package/src/serve/entries/bridge-url.ts +1 -1
  463. package/src/serve/entries/init.ts +78 -3
  464. package/src/serve/entries/runtime.ts +10 -0
  465. package/src/serve/namespace.ts +73 -140
  466. package/src/serve/runtime/chip-config.ts +16 -2
  467. package/src/serve/runtime/chip-dialog.ts +366 -0
  468. package/src/serve/runtime/chip-install.ts +10 -4
  469. package/src/serve/runtime/chip-user-search.ts +391 -0
  470. package/src/serve/runtime/chip.ts +140 -15
  471. package/src/serve/runtime/identity.ts +26 -0
  472. package/src/serve/sandbox-session.ts +9 -0
  473. package/src/serve/studio/disk-workspace.ts +76 -2
  474. package/src/serve/vite-plugin.ts +8 -8
  475. package/src/serve/vite-sandbox-generation.ts +15 -0
  476. package/src/serve/worker/client/auth.ts +1 -1
  477. package/src/serve/worker/client/core.ts +80 -3
  478. package/src/serve/worker/client.ts +1 -1
  479. package/src/serve/worker/context-resolver.ts +60 -0
  480. package/src/serve/worker/entry.ts +22 -18
  481. package/src/serve/worker/host/core.ts +9 -7
  482. package/src/serve/worker/host/storage.ts +2 -2
  483. package/src/serve/worker/host-auth.ts +1 -1
  484. package/src/serve/worker/index.ts +4 -1
  485. package/src/serve/worker/port-lifecycle.ts +45 -0
  486. package/src/serve/worker/serve-init.ts +9 -2
  487. package/src/verify/fixture.ts +1 -1
  488. package/dist/serve/site-ui/_astro/app.B52xr-DK.js +0 -1
  489. package/dist/serve/site-ui/_astro/app.DWBraPUw.js +0 -12
  490. package/dist/serve/site-ui/_astro/sandbox-controls.DEpnKg-O.js +0 -1169
  491. package/dist/serve/site-ui/_astro/writes.rpjrFzmu.js +0 -102
@@ -2,7 +2,7 @@
2
2
  <link rel="stylesheet" href="/__pyric/ui/_astro/_slug_.Da5VLhW1.css">
3
3
  <style>:root{--rhythm-para: .875rem;--rhythm-group: 1.5rem;--rhythm-subsection: 2.25rem;--rhythm-section: 3.25rem;--rhythm-list: calc(var(--rhythm-para) * .75)}.prose>*,.prose blockquote>*,.prose li>*,.prose .compat-stat>*{margin-block:0}.prose>*+*{margin-block-start:var(--rhythm-group)}.prose>*+h2{margin-block-start:var(--rhythm-section)}.prose>*+h3,.prose>*+h4{margin-block-start:var(--rhythm-subsection)}.prose>h1+*,.prose>h2+*,.prose>h3+*,.prose>h4+*{margin-block-start:var(--rhythm-para)}.prose>p+p{margin-block-start:var(--rhythm-para)}.prose>p+ul,.prose>p+ol,.prose>p+blockquote{margin-block-start:var(--rhythm-para)}.prose li+li{margin-block-start:var(--rhythm-list)}.prose li>ul,.prose li>ol{margin-block-start:var(--rhythm-list)}.prose li>*+*,.prose blockquote>*+*{margin-block-start:var(--rhythm-para)}
4
4
  html{scrollbar-gutter:stable}
5
- </style></head> <body> <header class="studio__chrome"> <div class="studio__bar"> <div class="studio__chrome-inner"> <nav class="studio__nav" aria-label="Site"> <a class="studio__brand" href="/__pyric/ui/" aria-label="Pyric">pyric</a> <a class="studio__nav-tab" href="/__pyric/ui/"> Home </a><a class="studio__nav-tab" href="/__pyric/ui/docs" aria-current="page"> Docs </a><a class="studio__nav-tab" href="/__pyric/ui/studio"> Studio </a> </nav> </div> </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/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/"> Conformance scores </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/" aria-current="page"> Storage </a> </li><li> <a href="/__pyric/ui/docs/messaging-compat/"> 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-reference-api/"> pyric-admin </a> </li><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 class="docs-nav-section"> <h2 class="docs-nav-heading">@pyric/cli</h2> <ul> <li> <a href="/__pyric/ui/docs/reference/cli/"> CLI </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/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/"> Conformance scores </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/" aria-current="page"> Storage </a> </li><li> <a href="/__pyric/ui/docs/messaging-compat/"> 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-reference-api/"> pyric-admin </a> </li><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 class="docs-nav-section"> <h2 class="docs-nav-heading">@pyric/cli</h2> <ul> <li> <a href="/__pyric/ui/docs/reference/cli/"> CLI </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">Storage</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. -->
5
+ </style></head> <body> <header class="studio__chrome"> <div class="studio__bar"> <div class="studio__chrome-inner"> <nav class="studio__nav" aria-label="Site"> <a class="studio__brand" href="/__pyric/ui/" aria-label="Pyric">pyric</a> <a class="studio__nav-tab" href="/__pyric/ui/"> Home </a><a class="studio__nav-tab" href="/__pyric/ui/docs" aria-current="page"> Docs </a><a class="studio__nav-tab" href="/__pyric/ui/studio"> Studio </a> </nav> </div> </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/backend-bundlers/"> Backend bundlers </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/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/"> Conformance scores </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/" aria-current="page"> Storage </a> </li><li> <a href="/__pyric/ui/docs/messaging-compat/"> 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><li> <a href="/__pyric/ui/docs/firestore-flutter-compat/"> Firestore · Flutter </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-firestore-lite-reference-api/"> pyric/firestore/lite </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><li> <a href="/__pyric/ui/docs/pyric-app-check-reference-api/"> pyric/app-check </a> </li><li> <a href="/__pyric/ui/docs/pyric-functions-reference-api/"> pyric/functions </a> </li><li> <a href="/__pyric/ui/docs/pyric-analytics-reference-api/"> pyric/analytics </a> </li><li> <a href="/__pyric/ui/docs/pyric-performance-reference-api/"> pyric/performance </a> </li><li> <a href="/__pyric/ui/docs/pyric-remote-config-reference-api/"> pyric/remote-config </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-reference-api/"> pyric-admin </a> </li><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-bundler-reference-api/"> @pyric/cli/bundler </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 class="docs-nav-section"> <h2 class="docs-nav-heading">@pyric/cli</h2> <ul> <li> <a href="/__pyric/ui/docs/reference/cli/"> CLI </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/backend-bundlers/"> Backend bundlers </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/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/"> Conformance scores </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/" aria-current="page"> Storage </a> </li><li> <a href="/__pyric/ui/docs/messaging-compat/"> 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><li> <a href="/__pyric/ui/docs/firestore-flutter-compat/"> Firestore · Flutter </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-firestore-lite-reference-api/"> pyric/firestore/lite </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><li> <a href="/__pyric/ui/docs/pyric-app-check-reference-api/"> pyric/app-check </a> </li><li> <a href="/__pyric/ui/docs/pyric-functions-reference-api/"> pyric/functions </a> </li><li> <a href="/__pyric/ui/docs/pyric-analytics-reference-api/"> pyric/analytics </a> </li><li> <a href="/__pyric/ui/docs/pyric-performance-reference-api/"> pyric/performance </a> </li><li> <a href="/__pyric/ui/docs/pyric-remote-config-reference-api/"> pyric/remote-config </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-reference-api/"> pyric-admin </a> </li><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-bundler-reference-api/"> @pyric/cli/bundler </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 class="docs-nav-section"> <h2 class="docs-nav-heading">@pyric/cli</h2> <ul> <li> <a href="/__pyric/ui/docs/reference/cli/"> CLI </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">Storage</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. -->
6
6
  <h1 id="pyricstorage-compatibility-matrix"><code>pyric/storage</code> compatibility matrix</h1>
7
7
  <div class="compat-stat">
8
8
  <p class="compat-stat-figure">
@@ -32,7 +32,7 @@ html{scrollbar-gutter:stable}
32
32
  </details>
33
33
  <details class="compat-row" data-status="ok">
34
34
  <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">getStorage(app, bucketUrl?)<code> / </code>getStorageSandbox(target, options?)</code><span class="compat-sub"><span class="compat-behavior"><code>getStorage(app)</code> returns the sandbox handle selected by package resolution</span></span></span></summary>
35
- <div class="compat-evidence"><div class="compat-probe"><code>entry-path:storage</code> runs the canonical <code>initializeApp</code> → <code>getStorage(app)</code> → <code>ref</code> → <code>uploadBytes</code> flow (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/entry-path/storage.ts#L6" target="_blank" rel="noopener noreferrer"><code>storage.ts</code></a>)</div></div>
35
+ <div class="compat-evidence"><div class="compat-probe"><code>entry-path:storage</code> runs the canonical <code>initializeApp</code> → <code>getStorage(app)</code> → <code>ref</code> → <code>uploadBytes</code> flow (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/entry-path/storage.ts#L16" target="_blank" rel="noopener noreferrer"><code>storage.ts</code></a>)</div></div>
36
36
  </details>
37
37
  <details class="compat-row" data-status="ok">
38
38
  <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">getStorage(app, bucketUrl?)<code> / </code>getStorageSandbox(target, options?)</code><span class="compat-sub"><span class="compat-behavior">Two <code>getStorageSandbox(ctx)</code> calls on the same context return the SAME wrapper (identity-stable)</span></span></span></summary>
@@ -72,7 +72,7 @@ html{scrollbar-gutter:stable}
72
72
  </details>
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">getStorage(app, bucketUrl?)<code> / </code>getStorageSandbox(target, options?)</code><span class="compat-sub"><span class="compat-behavior">The served <code>firebase/storage</code> entry accepts bare <code>getStorage()</code> and returns the page's shared sandbox handle</span></span></span></summary>
75
- <div class="compat-evidence"><div class="compat-probe">The canonical served entry supplies the page sandbox when the app argument is omitted; the entry-path and bundler suites execute the public package shape. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/entry-path/storage.ts#L6" target="_blank" rel="noopener noreferrer"><code>storage.ts</code></a>, <a href="https://github.com/davideast/pyric/blob/main/packages/cli/test/serve/bundler.test.ts#L448" target="_blank" rel="noopener noreferrer"><code>bundler.test.ts</code></a>)</div></div>
75
+ <div class="compat-evidence"><div class="compat-probe">The canonical served entry supplies the page sandbox when the app argument is omitted; the entry-path and bundler suites execute the public package shape. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/entry-path/storage.ts#L16" target="_blank" rel="noopener noreferrer"><code>storage.ts</code></a>, <a href="https://github.com/davideast/pyric/blob/main/packages/cli/test/serve/bundler.test.ts#L448" target="_blank" rel="noopener noreferrer"><code>bundler.test.ts</code></a>)</div></div>
76
76
  </details>
77
77
  </div>
78
78
  <h2 id="refstorage-path--refparent-path--reference-constructor"><code>ref(storage[, path])</code> / <code>ref(parent, path)</code> — reference constructor</h2>
@@ -198,7 +198,7 @@ html{scrollbar-gutter:stable}
198
198
  </details>
199
199
  <details class="compat-row" data-status="diverged">
200
200
  <summary class="compat-line"><span class="compat-dot" data-status="diverged" role="img" aria-label="Diverged (documented)" title="Diverged (documented)"></span><span class="compat-main"><code class="compat-api">uploadString(ref, value, format?, metadata?)</code><span class="compat-sub"><span class="compat-behavior">Sandbox: <code>format='base64url'</code> (or any unknown format) rejected with <code>storage/invalid-format</code> naming the bad format. Prod: <code>base64url</code> is ACCEPTED (upload succeeds); a genuinely-unrecognized format throws <code>storage/unknown</code></span></span></span></summary>
201
- <div class="compat-evidence"><div class="compat-probe">divergence, both halves oracle-locked by <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/storage/storage-uploadstring-unknown-format.json" target="_blank" rel="noopener noreferrer"><code>packages/conformance/observations/storage/storage-uploadstring-unknown-format.json</code></a>: prod accepts <code>base64url</code> (<code>base64urlOk: true</code>) and throws <code>storage/unknown</code> for an unrecognized format — not <code>storage/invalid-format</code>. The v1 sandbox ships only <code>raw</code>/<code>base64</code>/<code>data_url</code> (matches <code>StringFormat</code>) and throws <code>storage/invalid-format</code> for anything else (ST-B3 replaced the old mis-parse-as-data_url behavior). Both sides pinned in <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/storage/oracle-conformance.test.ts#L129" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>; sandbox code path documented in <code>upload.ts</code>'s <code>decodeString</code>. Implementing base64url decoding is still one line in <code>decodeString</code>. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/storage/error-codes.test.ts#L25" target="_blank" rel="noopener noreferrer"><code>error-codes.test.ts</code></a>)</div></div>
201
+ <div class="compat-evidence"><div class="compat-probe">divergence, both halves oracle-locked by <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/storage/storage-uploadstring-unknown-format.json" target="_blank" rel="noopener noreferrer"><code>packages/conformance/observations/storage/storage-uploadstring-unknown-format.json</code></a>: prod accepts <code>base64url</code> (<code>base64urlOk: true</code>) and throws <code>storage/unknown</code> for an unrecognized format — not <code>storage/invalid-format</code>. The v1 sandbox ships only <code>raw</code>/<code>base64</code>/<code>data_url</code> (matches <code>StringFormat</code>) and throws <code>storage/invalid-format</code> for anything else (ST-B3 replaced the old mis-parse-as-data_url behavior). Both sides pinned in <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/storage/oracle-conformance.test.ts#L138" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>; sandbox code path documented in <code>upload.ts</code>'s <code>decodeString</code>. Implementing base64url decoding is still one line in <code>decodeString</code>. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/storage/error-codes.test.ts#L25" target="_blank" rel="noopener noreferrer"><code>error-codes.test.ts</code></a>)</div></div>
202
202
  </details>
203
203
  <details class="compat-row" data-status="ok">
204
204
  <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">uploadString(ref, value, format?, metadata?)</code><span class="compat-sub"><span class="compat-behavior"><code>format='data_url'</code>: parses <code>data:&#x3C;mime>;base64,&#x3C;payload></code>, infers <code>contentType</code> from prefix</span></span></span></summary>
@@ -218,7 +218,7 @@ html{scrollbar-gutter:stable}
218
218
  </details>
219
219
  <details class="compat-row" data-status="ok">
220
220
  <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">uploadString(ref, value, format?, metadata?)</code><span class="compat-sub"><span class="compat-behavior"><code>uploadString(ref, value, 'base64')</code> round-trips via <code>getDownloadURL</code> + fetch across in-page sandbox and SharedWorker mode</span></span></span></summary>
221
- <div class="compat-evidence"><div class="compat-probe">oracle: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/storage/storage-uploadstring-base64-roundtrip.json" target="_blank" rel="noopener noreferrer"><code>packages/conformance/observations/storage/storage-uploadstring-base64-roundtrip.json</code></a> (<code>'aGVsbG8='</code> → <code>'hello'</code> against blockingfun, fb-js-sdk 12.13.0; <code>textMatches: true</code>). Sandbox oracle replay matches production behavior in-page, and client↔host integration proves SharedWorker mode decodes and transfers string payloads faithfully over the worker port. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/storage/oracle-conformance.test.ts#L192" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>, <a href="https://github.com/davideast/pyric/blob/main/packages/cli/test/serve/worker/integration.test.ts#L252" target="_blank" rel="noopener noreferrer"><code>integration.test.ts</code></a>)</div></div>
221
+ <div class="compat-evidence"><div class="compat-probe">oracle: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/storage/storage-uploadstring-base64-roundtrip.json" target="_blank" rel="noopener noreferrer"><code>packages/conformance/observations/storage/storage-uploadstring-base64-roundtrip.json</code></a> (<code>'aGVsbG8='</code> → <code>'hello'</code> against blockingfun, fb-js-sdk 12.13.0; <code>textMatches: true</code>). Sandbox oracle replay matches production behavior in-page, and client↔host integration proves SharedWorker mode decodes and transfers string payloads faithfully over the worker port. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/storage/oracle-conformance.test.ts#L201" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>, <a href="https://github.com/davideast/pyric/blob/main/packages/cli/test/serve/worker/integration.test.ts#L281" target="_blank" rel="noopener noreferrer"><code>integration.test.ts</code></a>)</div></div>
222
222
  </details>
223
223
  </div>
224
224
  <h2 id="uploadbytesresumableref-data-metadata--resumable-upload--task-observers"><code>uploadBytesResumable(ref, data, metadata?)</code> — resumable upload + task observers</h2>
@@ -244,11 +244,11 @@ html{scrollbar-gutter:stable}
244
244
  <div class="compat-list">
245
245
  <details class="compat-row" data-status="diverged">
246
246
  <summary class="compat-line"><span class="compat-dot" data-status="diverged" role="img" aria-label="Diverged (documented)" title="Diverged (documented)"></span><span class="compat-main"><code class="compat-api">getDownloadURL(ref)</code><span class="compat-sub"><span class="compat-behavior">Exported by <code>firebase/storage</code>; returns a token-signed HTTPS URL that fetches the blob</span></span></span></summary>
247
- <div class="compat-evidence"><div class="compat-probe">Implemented with a two-sided pin. Production observation <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/storage/storage-upload-bytes-roundtrip.json" target="_blank" rel="noopener noreferrer"><code>storage-upload-bytes-roundtrip</code></a> records <code>urlIsHttps: true</code> and a byte-identical fetch. The sandbox oracle replay now calls the same public <code>getDownloadURL</code> + <code>fetch</code> path and proves byte-identical content, while explicitly asserting its URL starts with <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/storage/oracle-conformance.test.ts#L170" target="_blank" rel="noopener noreferrer"><code>blob:</code></a>. The client↔host integration proves SharedWorker mode creates that URL in the calling page after the rules-checked Blob crosses the port. The remaining divergence is URL identity and lifetime: the sandbox URL is a page-local snapshot, not token-signed HTTPS and not shareable outside that page. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/cli/test/serve/worker/integration.test.ts#L237" target="_blank" rel="noopener noreferrer"><code>integration.test.ts</code></a>)</div></div>
247
+ <div class="compat-evidence"><div class="compat-probe">Implemented with a two-sided pin. Production observation <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/storage/storage-upload-bytes-roundtrip.json" target="_blank" rel="noopener noreferrer"><code>storage-upload-bytes-roundtrip</code></a> records <code>urlIsHttps: true</code> and a byte-identical fetch. The sandbox oracle replay now calls the same public <code>getDownloadURL</code> + <code>fetch</code> path and proves byte-identical content, while explicitly asserting its URL starts with <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/storage/oracle-conformance.test.ts#L179" target="_blank" rel="noopener noreferrer"><code>blob:</code></a>. The client↔host integration proves SharedWorker mode creates that URL in the calling page after the rules-checked Blob crosses the port. The remaining divergence is URL identity and lifetime: the sandbox URL is a page-local snapshot, not token-signed HTTPS and not shareable outside that page. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/cli/test/serve/worker/integration.test.ts#L266" target="_blank" rel="noopener noreferrer"><code>integration.test.ts</code></a>)</div></div>
248
248
  </details>
249
249
  <details class="compat-row" data-status="ok">
250
250
  <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">getDownloadURL(ref)</code><span class="compat-sub"><span class="compat-behavior">Throws <code>storage/object-not-found</code> for missing objects</span></span></span></summary>
251
- <div class="compat-evidence"><div class="compat-probe">Production observation <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/storage/storage-delete-then-get-throws.json" target="_blank" rel="noopener noreferrer"><code>storage-delete-then-get-throws</code></a> records <code>getDownloadURL</code> throwing <code>storage/object-not-found</code> after deletion. The sandbox oracle replay now invokes <code>getDownloadURL</code> itself and matches that code; the public error-code suite also pins the never-existing-object case. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/storage/error-codes.test.ts#L28" target="_blank" rel="noopener noreferrer"><code>error-codes.test.ts</code></a>, <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/storage/oracle-conformance.test.ts#L110" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
251
+ <div class="compat-evidence"><div class="compat-probe">Production observation <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/storage/storage-delete-then-get-throws.json" target="_blank" rel="noopener noreferrer"><code>storage-delete-then-get-throws</code></a> records <code>getDownloadURL</code> throwing <code>storage/object-not-found</code> after deletion. The sandbox oracle replay now invokes <code>getDownloadURL</code> itself and matches that code; the public error-code suite also pins the never-existing-object case. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/storage/error-codes.test.ts#L28" target="_blank" rel="noopener noreferrer"><code>error-codes.test.ts</code></a>, <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/storage/oracle-conformance.test.ts#L119" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
252
252
  </details>
253
253
  </div>
254
254
  <h2 id="getbytesref-maxdownloadsize--read-as-arraybuffer"><code>getBytes(ref, maxDownloadSize?)</code> — read as ArrayBuffer</h2>
@@ -308,7 +308,7 @@ html{scrollbar-gutter:stable}
308
308
  </details>
309
309
  <details class="compat-row" data-status="diverged">
310
310
  <summary class="compat-line"><span class="compat-dot" data-status="diverged" role="img" aria-label="Diverged (documented)" title="Diverged (documented)"></span><span class="compat-main"><code class="compat-api">deleteObject(ref)</code><span class="compat-sub"><span class="compat-behavior">Sandbox: no-op on missing path (does NOT throw)</span></span></span></summary>
311
- <div class="compat-evidence"><div class="compat-probe">divergence: sandbox is no-op via <code>persistence.ts</code>'s <code>delete</code>. Prod's <code>deleteObject</code> on a missing path throws <code>storage/object-not-found</code>. Oracle-locked: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/storage/storage-delete-missing-throws.json" target="_blank" rel="noopener noreferrer"><code>packages/conformance/observations/storage/storage-delete-missing-throws.json</code></a> (<code>code: 'storage/object-not-found'</code>, <code>name: 'FirebaseError'</code> against blockingfun, fb-js-sdk 12.13.0). Both sides pinned in <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/storage/oracle-conformance.test.ts#L91" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>; documented in <code>download.ts</code>.</div></div>
311
+ <div class="compat-evidence"><div class="compat-probe">divergence: sandbox is no-op via <code>persistence.ts</code>'s <code>delete</code>. Prod's <code>deleteObject</code> on a missing path throws <code>storage/object-not-found</code>. Oracle-locked: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/storage/storage-delete-missing-throws.json" target="_blank" rel="noopener noreferrer"><code>packages/conformance/observations/storage/storage-delete-missing-throws.json</code></a> (<code>code: 'storage/object-not-found'</code>, <code>name: 'FirebaseError'</code> against blockingfun, fb-js-sdk 12.13.0). Both sides pinned in <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/storage/oracle-conformance.test.ts#L100" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>; documented in <code>download.ts</code>.</div></div>
312
312
  </details>
313
313
  <details class="compat-row" data-status="ok">
314
314
  <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">deleteObject(ref)</code><span class="compat-sub"><span class="compat-behavior">Throws <code>storage/invalid-root-operation</code> on the root reference</span></span></span></summary>
@@ -432,7 +432,7 @@ html{scrollbar-gutter:stable}
432
432
  </details>
433
433
  <details class="compat-row" data-status="diverged">
434
434
  <summary class="compat-line"><span class="compat-dot" data-status="diverged" role="img" aria-label="Diverged (documented)" title="Diverged (documented)"></span><span class="compat-main"><code class="compat-api">getMetadata(ref)<code> / </code>updateMetadata(ref, metadata)</code><span class="compat-sub"><span class="compat-behavior"><code>FullMetadata.md5Hash</code> populated on uploads</span></span></span></summary>
435
- <div class="compat-evidence"><div class="compat-probe">divergence: sandbox does NOT compute <code>md5Hash</code>. Oracle-locked: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/storage/storage-upload-then-getmetadata.json" target="_blank" rel="noopener noreferrer"><code>packages/conformance/observations/storage/storage-upload-then-getmetadata.json</code></a> confirms prod sets <code>md5Hash</code> (<code>hasMd5Hash: true</code> after a vanilla <code>uploadBytes</code>). Both sides pinned in <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/storage/oracle-conformance.test.ts#L207" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>. Aligning the sandbox is a one-spot fix in <code>upload.ts</code>'s <code>buildStoredMetadata</code>.</div></div>
435
+ <div class="compat-evidence"><div class="compat-probe">divergence: sandbox does NOT compute <code>md5Hash</code>. Oracle-locked: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/storage/storage-upload-then-getmetadata.json" target="_blank" rel="noopener noreferrer"><code>packages/conformance/observations/storage/storage-upload-then-getmetadata.json</code></a> confirms prod sets <code>md5Hash</code> (<code>hasMd5Hash: true</code> after a vanilla <code>uploadBytes</code>). Both sides pinned in <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/storage/oracle-conformance.test.ts#L216" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>. Aligning the sandbox is a one-spot fix in <code>upload.ts</code>'s <code>buildStoredMetadata</code>.</div></div>
436
436
  </details>
437
437
  <details class="compat-row" data-status="unsupported">
438
438
  <summary class="compat-line"><span class="compat-dot" data-status="unsupported" role="img" aria-label="Not implemented yet" title="Not implemented yet"></span><span class="compat-main"><code class="compat-api">getMetadata(ref)<code> / </code>updateMetadata(ref, metadata)</code><span class="compat-sub"><span class="compat-behavior"><code>FullMetadata.ref</code> lazy population (prod populates lazily)</span></span></span></summary>
@@ -480,7 +480,7 @@ API) moved to the native <code>storage-rules</code> surface (<code>docs/rules/CO
480
480
  <details class="compat-row" data-status="diverged"><summary class="compat-line"><span class="compat-dot" data-status="diverged" role="img" aria-label="Diverged (documented)" title="Diverged (documented)"></span><span class="compat-main"><code class="compat-api">getStorage(app, bucketUrl?)` / `getStorageSandbox(target, options?)</code><span class="compat-sub"><span class="compat-behavior"><code>getStorage(app, bucketUrl?)</code> accepts Firebase's bucket argument; the sandbox remains bound to its configured single bucket</span></span></span></summary>
481
481
  <div class="compat-evidence"><div class="compat-note">Package resolution owns production selection. The sandbox accepts the canonical argument but does not model production multi-bucket routing; <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/storage/service.test.ts#L4" target="_blank" rel="noopener noreferrer"><code>unit:service.test.ts</code></a> pins the configured <code>pyric-default</code> bucket.</div></div></details>
482
482
  <details class="compat-row" data-status="diverged"><summary class="compat-line"><span class="compat-dot" data-status="diverged" role="img" aria-label="Diverged (documented)" title="Diverged (documented)"></span><span class="compat-main"><code class="compat-api">uploadString(ref, value, format?, metadata?)</code><span class="compat-sub"><span class="compat-behavior">Sandbox: <code>format='base64url'</code> (or any unknown format) rejected with <code>storage/invalid-format</code> naming the bad format. Prod: <code>base64url</code> is ACCEPTED (upload succeeds); a genuinely-unrecognized format throws <code>storage/unknown</code></span></span></span></summary>
483
- <div class="compat-evidence"><div class="compat-note">divergence, both halves oracle-locked by <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/storage/storage-uploadstring-unknown-format.json" target="_blank" rel="noopener noreferrer"><code>packages/conformance/observations/storage/storage-uploadstring-unknown-format.json</code></a>: prod accepts <code>base64url</code> (<code>base64urlOk: true</code>) and throws <code>storage/unknown</code> for an unrecognized format — not <code>storage/invalid-format</code>. The v1 sandbox ships only <code>raw</code>/<code>base64</code>/<code>data_url</code> (matches <code>StringFormat</code>) and throws <code>storage/invalid-format</code> for anything else (ST-B3 replaced the old mis-parse-as-data_url behavior). Both sides pinned in <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/storage/oracle-conformance.test.ts#L129" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>; sandbox code path documented in <code>upload.ts</code>'s <code>decodeString</code>. Implementing base64url decoding is still one line in <code>decodeString</code>. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/storage/error-codes.test.ts#L25" target="_blank" rel="noopener noreferrer"><code>error-codes.test.ts</code></a>)</div></div></details>
483
+ <div class="compat-evidence"><div class="compat-note">divergence, both halves oracle-locked by <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/storage/storage-uploadstring-unknown-format.json" target="_blank" rel="noopener noreferrer"><code>packages/conformance/observations/storage/storage-uploadstring-unknown-format.json</code></a>: prod accepts <code>base64url</code> (<code>base64urlOk: true</code>) and throws <code>storage/unknown</code> for an unrecognized format — not <code>storage/invalid-format</code>. The v1 sandbox ships only <code>raw</code>/<code>base64</code>/<code>data_url</code> (matches <code>StringFormat</code>) and throws <code>storage/invalid-format</code> for anything else (ST-B3 replaced the old mis-parse-as-data_url behavior). Both sides pinned in <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/storage/oracle-conformance.test.ts#L138" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>; sandbox code path documented in <code>upload.ts</code>'s <code>decodeString</code>. Implementing base64url decoding is still one line in <code>decodeString</code>. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/storage/error-codes.test.ts#L25" target="_blank" rel="noopener noreferrer"><code>error-codes.test.ts</code></a>)</div></div></details>
484
484
  <details class="compat-row" data-status="diverged"><summary class="compat-line"><span class="compat-dot" data-status="diverged" role="img" aria-label="Diverged (documented)" title="Diverged (documented)"></span><span class="compat-main"><code class="compat-api">uploadBytesResumable(ref, data, metadata?)</code><span class="compat-sub"><span class="compat-behavior">Exported by <code>firebase/storage</code>; returns an <code>UploadTask</code> with <code>pause()</code> / <code>resume()</code> / <code>cancel()</code></span></span></span></summary>
485
485
  <div class="compat-evidence"><div class="compat-note"><a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/storage/resumable-upload.test.ts#L14" target="_blank" rel="noopener noreferrer"><code>unit:resumable-upload.test.ts</code></a> confirms <code>uploadBytesResumable(ref, data)</code> returns an <code>UploadTask</code> supporting <code>pause()</code>, <code>resume()</code>, and <code>cancel()</code> over synthetic microtask steps.</div></div></details>
486
486
  <details class="compat-row" data-status="diverged"><summary class="compat-line"><span class="compat-dot" data-status="diverged" role="img" aria-label="Diverged (documented)" title="Diverged (documented)"></span><span class="compat-main"><code class="compat-api">uploadBytesResumable(ref, data, metadata?)</code><span class="compat-sub"><span class="compat-behavior"><code>task.on('state_changed', next, error, complete)</code> fires <code>next</code> with <code>{bytesTransferred, totalBytes, state}</code> snapshots</span></span></span></summary>
@@ -490,13 +490,13 @@ API) moved to the native <code>storage-rules</code> surface (<code>docs/rules/CO
490
490
  <details class="compat-row" data-status="diverged"><summary class="compat-line"><span class="compat-dot" data-status="diverged" role="img" aria-label="Diverged (documented)" title="Diverged (documented)"></span><span class="compat-main"><code class="compat-api">uploadBytesResumable(ref, data, metadata?)</code><span class="compat-sub"><span class="compat-behavior"><code>task.cancel()</code> rejects the upload with <code>storage/canceled</code></span></span></span></summary>
491
491
  <div class="compat-evidence"><div class="compat-note"><a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/storage/resumable-upload.test.ts#L14" target="_blank" rel="noopener noreferrer"><code>unit:resumable-upload.test.ts</code></a> confirms cancellation rejects with <code>storage/canceled</code> and leaves no falsely completed object in storage.</div></div></details>
492
492
  <details class="compat-row" data-status="diverged"><summary class="compat-line"><span class="compat-dot" data-status="diverged" role="img" aria-label="Diverged (documented)" title="Diverged (documented)"></span><span class="compat-main"><code class="compat-api">getDownloadURL(ref)</code><span class="compat-sub"><span class="compat-behavior">Exported by <code>firebase/storage</code>; returns a token-signed HTTPS URL that fetches the blob</span></span></span></summary>
493
- <div class="compat-evidence"><div class="compat-note">Implemented with a two-sided pin. Production observation <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/storage/storage-upload-bytes-roundtrip.json" target="_blank" rel="noopener noreferrer"><code>storage-upload-bytes-roundtrip</code></a> records <code>urlIsHttps: true</code> and a byte-identical fetch. The sandbox oracle replay now calls the same public <code>getDownloadURL</code> + <code>fetch</code> path and proves byte-identical content, while explicitly asserting its URL starts with <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/storage/oracle-conformance.test.ts#L170" target="_blank" rel="noopener noreferrer"><code>blob:</code></a>. The client↔host integration proves SharedWorker mode creates that URL in the calling page after the rules-checked Blob crosses the port. The remaining divergence is URL identity and lifetime: the sandbox URL is a page-local snapshot, not token-signed HTTPS and not shareable outside that page. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/cli/test/serve/worker/integration.test.ts#L237" target="_blank" rel="noopener noreferrer"><code>integration.test.ts</code></a>)</div></div></details>
493
+ <div class="compat-evidence"><div class="compat-note">Implemented with a two-sided pin. Production observation <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/storage/storage-upload-bytes-roundtrip.json" target="_blank" rel="noopener noreferrer"><code>storage-upload-bytes-roundtrip</code></a> records <code>urlIsHttps: true</code> and a byte-identical fetch. The sandbox oracle replay now calls the same public <code>getDownloadURL</code> + <code>fetch</code> path and proves byte-identical content, while explicitly asserting its URL starts with <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/storage/oracle-conformance.test.ts#L179" target="_blank" rel="noopener noreferrer"><code>blob:</code></a>. The client↔host integration proves SharedWorker mode creates that URL in the calling page after the rules-checked Blob crosses the port. The remaining divergence is URL identity and lifetime: the sandbox URL is a page-local snapshot, not token-signed HTTPS and not shareable outside that page. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/cli/test/serve/worker/integration.test.ts#L266" target="_blank" rel="noopener noreferrer"><code>integration.test.ts</code></a>)</div></div></details>
494
494
  <details class="compat-row" data-status="diverged"><summary class="compat-line"><span class="compat-dot" data-status="diverged" role="img" aria-label="Diverged (documented)" title="Diverged (documented)"></span><span class="compat-main"><code class="compat-api">deleteObject(ref)</code><span class="compat-sub"><span class="compat-behavior">Sandbox: no-op on missing path (does NOT throw)</span></span></span></summary>
495
- <div class="compat-evidence"><div class="compat-note">divergence: sandbox is no-op via <code>persistence.ts</code>'s <code>delete</code>. Prod's <code>deleteObject</code> on a missing path throws <code>storage/object-not-found</code>. Oracle-locked: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/storage/storage-delete-missing-throws.json" target="_blank" rel="noopener noreferrer"><code>packages/conformance/observations/storage/storage-delete-missing-throws.json</code></a> (<code>code: 'storage/object-not-found'</code>, <code>name: 'FirebaseError'</code> against blockingfun, fb-js-sdk 12.13.0). Both sides pinned in <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/storage/oracle-conformance.test.ts#L91" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>; documented in <code>download.ts</code>.</div></div></details>
495
+ <div class="compat-evidence"><div class="compat-note">divergence: sandbox is no-op via <code>persistence.ts</code>'s <code>delete</code>. Prod's <code>deleteObject</code> on a missing path throws <code>storage/object-not-found</code>. Oracle-locked: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/storage/storage-delete-missing-throws.json" target="_blank" rel="noopener noreferrer"><code>packages/conformance/observations/storage/storage-delete-missing-throws.json</code></a> (<code>code: 'storage/object-not-found'</code>, <code>name: 'FirebaseError'</code> against blockingfun, fb-js-sdk 12.13.0). Both sides pinned in <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/storage/oracle-conformance.test.ts#L100" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>; documented in <code>download.ts</code>.</div></div></details>
496
496
  <details class="compat-row" data-status="diverged"><summary class="compat-line"><span class="compat-dot" data-status="diverged" role="img" aria-label="Diverged (documented)" title="Diverged (documented)"></span><span class="compat-main"><code class="compat-api">getMetadata(ref)` / `updateMetadata(ref, metadata)</code><span class="compat-sub"><span class="compat-behavior"><code>updateMetadata</code> with <code>undefined</code> field values preserves the prior value (does NOT clear it)</span></span></span></summary>
497
497
  <div class="compat-evidence"><div class="compat-note">divergence: prod accepts <code>null</code> to explicitly clear a field. Sandbox doesn't model <code>null</code>-clear (per <code>metadata.ts</code> doc comment). Documented; not probe-locked.</div></div></details>
498
498
  <details class="compat-row" data-status="diverged"><summary class="compat-line"><span class="compat-dot" data-status="diverged" role="img" aria-label="Diverged (documented)" title="Diverged (documented)"></span><span class="compat-main"><code class="compat-api">getMetadata(ref)` / `updateMetadata(ref, metadata)</code><span class="compat-sub"><span class="compat-behavior"><code>FullMetadata.md5Hash</code> populated on uploads</span></span></span></summary>
499
- <div class="compat-evidence"><div class="compat-note">divergence: sandbox does NOT compute <code>md5Hash</code>. Oracle-locked: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/storage/storage-upload-then-getmetadata.json" target="_blank" rel="noopener noreferrer"><code>packages/conformance/observations/storage/storage-upload-then-getmetadata.json</code></a> confirms prod sets <code>md5Hash</code> (<code>hasMd5Hash: true</code> after a vanilla <code>uploadBytes</code>). Both sides pinned in <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/storage/oracle-conformance.test.ts#L207" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>. Aligning the sandbox is a one-spot fix in <code>upload.ts</code>'s <code>buildStoredMetadata</code>.</div></div></details>
499
+ <div class="compat-evidence"><div class="compat-note">divergence: sandbox does NOT compute <code>md5Hash</code>. Oracle-locked: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/storage/storage-upload-then-getmetadata.json" target="_blank" rel="noopener noreferrer"><code>packages/conformance/observations/storage/storage-upload-then-getmetadata.json</code></a> confirms prod sets <code>md5Hash</code> (<code>hasMd5Hash: true</code> after a vanilla <code>uploadBytes</code>). Both sides pinned in <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/storage/oracle-conformance.test.ts#L216" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>. Aligning the sandbox is a one-spot fix in <code>upload.ts</code>'s <code>buildStoredMetadata</code>.</div></div></details>
500
500
  </div>
501
501
  <h3 id="not-implemented-yet">Not implemented yet</h3>
502
502
  <p>Tracked behavior that is not implemented in the current contract.</p>