@pyric/cli 0.1.0-alpha.9
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.
- package/LICENSE +216 -0
- package/README.md +156 -0
- package/README.md.orig +138 -0
- package/dist/assurance/attachment.d.ts +24 -0
- package/dist/assurance/attachment.d.ts.map +1 -0
- package/dist/assurance/attachment.js +138 -0
- package/dist/assurance/attachment.js.map +1 -0
- package/dist/assurance/browser.d.ts +7 -0
- package/dist/assurance/browser.d.ts.map +1 -0
- package/dist/assurance/browser.js +68 -0
- package/dist/assurance/browser.js.map +1 -0
- package/dist/assurance/campaign.d.ts +41 -0
- package/dist/assurance/campaign.d.ts.map +1 -0
- package/dist/assurance/campaign.js +364 -0
- package/dist/assurance/campaign.js.map +1 -0
- package/dist/assurance/capabilities.d.ts +7 -0
- package/dist/assurance/capabilities.d.ts.map +1 -0
- package/dist/assurance/capabilities.js +295 -0
- package/dist/assurance/capabilities.js.map +1 -0
- package/dist/assurance/cases.d.ts +14 -0
- package/dist/assurance/cases.d.ts.map +1 -0
- package/dist/assurance/cases.js +27 -0
- package/dist/assurance/cases.js.map +1 -0
- package/dist/assurance/generated-capabilities.d.ts +52 -0
- package/dist/assurance/generated-capabilities.d.ts.map +1 -0
- package/dist/assurance/generated-capabilities.js +329 -0
- package/dist/assurance/generated-capabilities.js.map +1 -0
- package/dist/assurance/index.d.ts +11 -0
- package/dist/assurance/index.d.ts.map +1 -0
- package/dist/assurance/index.js +9 -0
- package/dist/assurance/index.js.map +1 -0
- package/dist/assurance/runner.d.ts +3 -0
- package/dist/assurance/runner.d.ts.map +1 -0
- package/dist/assurance/runner.js +633 -0
- package/dist/assurance/runner.js.map +1 -0
- package/dist/assurance/tool-names.d.ts +4 -0
- package/dist/assurance/tool-names.d.ts.map +1 -0
- package/dist/assurance/tool-names.js +14 -0
- package/dist/assurance/tool-names.js.map +1 -0
- package/dist/assurance/tools.d.ts +19 -0
- package/dist/assurance/tools.d.ts.map +1 -0
- package/dist/assurance/tools.js +740 -0
- package/dist/assurance/tools.js.map +1 -0
- package/dist/assurance/types.d.ts +348 -0
- package/dist/assurance/types.d.ts.map +1 -0
- package/dist/assurance/types.js +7 -0
- package/dist/assurance/types.js.map +1 -0
- package/dist/assurance/validation.d.ts +8 -0
- package/dist/assurance/validation.d.ts.map +1 -0
- package/dist/assurance/validation.js +269 -0
- package/dist/assurance/validation.js.map +1 -0
- package/dist/bridge/client/bridge.d.ts +133 -0
- package/dist/bridge/client/bridge.d.ts.map +1 -0
- package/dist/bridge/client/bridge.js +429 -0
- package/dist/bridge/client/bridge.js.map +1 -0
- package/dist/bridge/client/dispatch.d.ts +41 -0
- package/dist/bridge/client/dispatch.d.ts.map +1 -0
- package/dist/bridge/client/dispatch.js +111 -0
- package/dist/bridge/client/dispatch.js.map +1 -0
- package/dist/bridge/client.d.ts +24 -0
- package/dist/bridge/client.d.ts.map +1 -0
- package/dist/bridge/client.js +26 -0
- package/dist/bridge/client.js.map +1 -0
- package/dist/bridge/protocol.d.ts +227 -0
- package/dist/bridge/protocol.d.ts.map +1 -0
- package/dist/bridge/protocol.js +131 -0
- package/dist/bridge/protocol.js.map +1 -0
- package/dist/bridge/server/audit.d.ts +19 -0
- package/dist/bridge/server/audit.d.ts.map +1 -0
- package/dist/bridge/server/audit.js +46 -0
- package/dist/bridge/server/audit.js.map +1 -0
- package/dist/bridge/server/bridge.d.ts +126 -0
- package/dist/bridge/server/bridge.d.ts.map +1 -0
- package/dist/bridge/server/bridge.js +383 -0
- package/dist/bridge/server/bridge.js.map +1 -0
- package/dist/bridge/server/headless.d.ts +36 -0
- package/dist/bridge/server/headless.d.ts.map +1 -0
- package/dist/bridge/server/headless.js +142 -0
- package/dist/bridge/server/headless.js.map +1 -0
- package/dist/bridge/server/json-schema-to-zod.d.ts +37 -0
- package/dist/bridge/server/json-schema-to-zod.d.ts.map +1 -0
- package/dist/bridge/server/json-schema-to-zod.js +93 -0
- package/dist/bridge/server/json-schema-to-zod.js.map +1 -0
- package/dist/bridge/server/local-bridge.d.ts +33 -0
- package/dist/bridge/server/local-bridge.d.ts.map +1 -0
- package/dist/bridge/server/local-bridge.js +41 -0
- package/dist/bridge/server/local-bridge.js.map +1 -0
- package/dist/bridge/server/logger.d.ts +28 -0
- package/dist/bridge/server/logger.d.ts.map +1 -0
- package/dist/bridge/server/logger.js +42 -0
- package/dist/bridge/server/logger.js.map +1 -0
- package/dist/bridge/server/mcp-contract.d.ts +21 -0
- package/dist/bridge/server/mcp-contract.d.ts.map +1 -0
- package/dist/bridge/server/mcp-contract.js +62 -0
- package/dist/bridge/server/mcp-contract.js.map +1 -0
- package/dist/bridge/server/mcp.d.ts +26 -0
- package/dist/bridge/server/mcp.d.ts.map +1 -0
- package/dist/bridge/server/mcp.js +102 -0
- package/dist/bridge/server/mcp.js.map +1 -0
- package/dist/bridge/server/peer.d.ts +39 -0
- package/dist/bridge/server/peer.d.ts.map +1 -0
- package/dist/bridge/server/peer.js +189 -0
- package/dist/bridge/server/peer.js.map +1 -0
- package/dist/bridge/server/standalone.d.ts +49 -0
- package/dist/bridge/server/standalone.d.ts.map +1 -0
- package/dist/bridge/server/standalone.js +267 -0
- package/dist/bridge/server/standalone.js.map +1 -0
- package/dist/bridge/server/tool-metadata.d.ts +38 -0
- package/dist/bridge/server/tool-metadata.d.ts.map +1 -0
- package/dist/bridge/server/tool-metadata.js +81 -0
- package/dist/bridge/server/tool-metadata.js.map +1 -0
- package/dist/bridge/server.d.ts +21 -0
- package/dist/bridge/server.d.ts.map +1 -0
- package/dist/bridge/server.js +18 -0
- package/dist/bridge/server.js.map +1 -0
- package/dist/cli/database-rules.d.ts +43 -0
- package/dist/cli/database-rules.d.ts.map +1 -0
- package/dist/cli/database-rules.js +261 -0
- package/dist/cli/database-rules.js.map +1 -0
- package/dist/cli/dev-runner.d.ts +112 -0
- package/dist/cli/dev-runner.d.ts.map +1 -0
- package/dist/cli/dev-runner.js +239 -0
- package/dist/cli/dev-runner.js.map +1 -0
- package/dist/cli/firebase-json.d.ts +66 -0
- package/dist/cli/firebase-json.d.ts.map +1 -0
- package/dist/cli/firebase-json.js +60 -0
- package/dist/cli/firebase-json.js.map +1 -0
- package/dist/cli/firestore-indexes.d.ts +21 -0
- package/dist/cli/firestore-indexes.d.ts.map +1 -0
- package/dist/cli/firestore-indexes.js +39 -0
- package/dist/cli/firestore-indexes.js.map +1 -0
- package/dist/cli/index.d.ts +56 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +379 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/init.d.ts +50 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +182 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/mcp-proxy.d.ts +10 -0
- package/dist/cli/mcp-proxy.d.ts.map +1 -0
- package/dist/cli/mcp-proxy.js +129 -0
- package/dist/cli/mcp-proxy.js.map +1 -0
- package/dist/cli/parse-args.d.ts +20 -0
- package/dist/cli/parse-args.d.ts.map +1 -0
- package/dist/cli/parse-args.js +69 -0
- package/dist/cli/parse-args.js.map +1 -0
- package/dist/cli/rules.d.ts +55 -0
- package/dist/cli/rules.d.ts.map +1 -0
- package/dist/cli/rules.js +199 -0
- package/dist/cli/rules.js.map +1 -0
- package/dist/cli/scope.d.ts +12 -0
- package/dist/cli/scope.d.ts.map +1 -0
- package/dist/cli/scope.js +44 -0
- package/dist/cli/scope.js.map +1 -0
- package/dist/cli/serve.d.ts +122 -0
- package/dist/cli/serve.d.ts.map +1 -0
- package/dist/cli/serve.js +844 -0
- package/dist/cli/serve.js.map +1 -0
- package/dist/cli/service-commands.d.ts +8 -0
- package/dist/cli/service-commands.d.ts.map +1 -0
- package/dist/cli/service-commands.js +58 -0
- package/dist/cli/service-commands.js.map +1 -0
- package/dist/cli/snapshot.d.ts +22 -0
- package/dist/cli/snapshot.d.ts.map +1 -0
- package/dist/cli/snapshot.js +139 -0
- package/dist/cli/snapshot.js.map +1 -0
- package/dist/cli/storage-rules.d.ts +21 -0
- package/dist/cli/storage-rules.d.ts.map +1 -0
- package/dist/cli/storage-rules.js +121 -0
- package/dist/cli/storage-rules.js.map +1 -0
- package/dist/cli/verify.d.ts +23 -0
- package/dist/cli/verify.d.ts.map +1 -0
- package/dist/cli/verify.js +349 -0
- package/dist/cli/verify.js.map +1 -0
- package/dist/credentials/core/memoize-ttl.d.ts +58 -0
- package/dist/credentials/core/memoize-ttl.d.ts.map +1 -0
- package/dist/credentials/core/memoize-ttl.js +88 -0
- package/dist/credentials/core/memoize-ttl.js.map +1 -0
- package/dist/credentials/core/types.d.ts +11 -0
- package/dist/credentials/core/types.d.ts.map +1 -0
- package/dist/credentials/core/types.js +2 -0
- package/dist/credentials/core/types.js.map +1 -0
- package/dist/credentials/node/from-adc.d.ts +10 -0
- package/dist/credentials/node/from-adc.d.ts.map +1 -0
- package/dist/credentials/node/from-adc.js +76 -0
- package/dist/credentials/node/from-adc.js.map +1 -0
- package/dist/credentials/node/from-service-account.d.ts +24 -0
- package/dist/credentials/node/from-service-account.d.ts.map +1 -0
- package/dist/credentials/node/from-service-account.js +108 -0
- package/dist/credentials/node/from-service-account.js.map +1 -0
- package/dist/credentials/node/index.d.ts +7 -0
- package/dist/credentials/node/index.d.ts.map +1 -0
- package/dist/credentials/node/index.js +7 -0
- package/dist/credentials/node/index.js.map +1 -0
- package/dist/discover/concurrency.d.ts +42 -0
- package/dist/discover/concurrency.d.ts.map +1 -0
- package/dist/discover/concurrency.js +113 -0
- package/dist/discover/concurrency.js.map +1 -0
- package/dist/discover/crawler-adapter.d.ts +48 -0
- package/dist/discover/crawler-adapter.d.ts.map +1 -0
- package/dist/discover/crawler-adapter.js +92 -0
- package/dist/discover/crawler-adapter.js.map +1 -0
- package/dist/discover/crawler.d.ts +294 -0
- package/dist/discover/crawler.d.ts.map +1 -0
- package/dist/discover/crawler.js +764 -0
- package/dist/discover/crawler.js.map +1 -0
- package/dist/discover/credential-free.d.ts +19 -0
- package/dist/discover/credential-free.d.ts.map +1 -0
- package/dist/discover/credential-free.js +18 -0
- package/dist/discover/credential-free.js.map +1 -0
- package/dist/discover/findCollectionGroup.d.ts +44 -0
- package/dist/discover/findCollectionGroup.d.ts.map +1 -0
- package/dist/discover/findCollectionGroup.js +81 -0
- package/dist/discover/findCollectionGroup.js.map +1 -0
- package/dist/discover/firestore-source.d.ts +60 -0
- package/dist/discover/firestore-source.d.ts.map +1 -0
- package/dist/discover/firestore-source.js +11 -0
- package/dist/discover/firestore-source.js.map +1 -0
- package/dist/discover/index.d.ts +3 -0
- package/dist/discover/index.d.ts.map +1 -0
- package/dist/discover/index.js +5 -0
- package/dist/discover/index.js.map +1 -0
- package/dist/discover/merge.d.ts +108 -0
- package/dist/discover/merge.d.ts.map +1 -0
- package/dist/discover/merge.js +394 -0
- package/dist/discover/merge.js.map +1 -0
- package/dist/discover/session.d.ts +116 -0
- package/dist/discover/session.d.ts.map +1 -0
- package/dist/discover/session.js +331 -0
- package/dist/discover/session.js.map +1 -0
- package/dist/discover/tools.d.ts +58 -0
- package/dist/discover/tools.d.ts.map +1 -0
- package/dist/discover/tools.js +115 -0
- package/dist/discover/tools.js.map +1 -0
- package/dist/discover/types.d.ts +190 -0
- package/dist/discover/types.d.ts.map +1 -0
- package/dist/discover/types.js +12 -0
- package/dist/discover/types.js.map +1 -0
- package/dist/discover/wire.d.ts +70 -0
- package/dist/discover/wire.d.ts.map +1 -0
- package/dist/discover/wire.js +309 -0
- package/dist/discover/wire.js.map +1 -0
- package/dist/functions-rtdb/child.d.ts +52 -0
- package/dist/functions-rtdb/child.d.ts.map +1 -0
- package/dist/functions-rtdb/child.js +283 -0
- package/dist/functions-rtdb/child.js.map +1 -0
- package/dist/functions-rtdb/delivery.d.ts +4 -0
- package/dist/functions-rtdb/delivery.d.ts.map +1 -0
- package/dist/functions-rtdb/delivery.js +2 -0
- package/dist/functions-rtdb/delivery.js.map +1 -0
- package/dist/functions-rtdb/discovery.d.ts +41 -0
- package/dist/functions-rtdb/discovery.d.ts.map +1 -0
- package/dist/functions-rtdb/discovery.js +86 -0
- package/dist/functions-rtdb/discovery.js.map +1 -0
- package/dist/functions-rtdb/event.d.ts +20 -0
- package/dist/functions-rtdb/event.d.ts.map +1 -0
- package/dist/functions-rtdb/event.js +45 -0
- package/dist/functions-rtdb/event.js.map +1 -0
- package/dist/functions-rtdb/execution.d.ts +20 -0
- package/dist/functions-rtdb/execution.d.ts.map +1 -0
- package/dist/functions-rtdb/execution.js +70 -0
- package/dist/functions-rtdb/execution.js.map +1 -0
- package/dist/functions-rtdb/in-memory-delivery.d.ts +9 -0
- package/dist/functions-rtdb/in-memory-delivery.d.ts.map +1 -0
- package/dist/functions-rtdb/in-memory-delivery.js +36 -0
- package/dist/functions-rtdb/in-memory-delivery.js.map +1 -0
- package/dist/functions-rtdb/project.d.ts +7 -0
- package/dist/functions-rtdb/project.d.ts.map +1 -0
- package/dist/functions-rtdb/project.js +54 -0
- package/dist/functions-rtdb/project.js.map +1 -0
- package/dist/functions-rtdb/projection.d.ts +14 -0
- package/dist/functions-rtdb/projection.d.ts.map +1 -0
- package/dist/functions-rtdb/projection.js +65 -0
- package/dist/functions-rtdb/projection.js.map +1 -0
- package/dist/functions-rtdb/reference-pattern.d.ts +5 -0
- package/dist/functions-rtdb/reference-pattern.d.ts.map +1 -0
- package/dist/functions-rtdb/reference-pattern.js +14 -0
- package/dist/functions-rtdb/reference-pattern.js.map +1 -0
- package/dist/functions-rtdb/remote-delivery.d.ts +9 -0
- package/dist/functions-rtdb/remote-delivery.d.ts.map +1 -0
- package/dist/functions-rtdb/remote-delivery.js +11 -0
- package/dist/functions-rtdb/remote-delivery.js.map +1 -0
- package/dist/pkg-version.d.ts +2 -0
- package/dist/pkg-version.d.ts.map +1 -0
- package/dist/pkg-version.js +47 -0
- package/dist/pkg-version.js.map +1 -0
- package/dist/register/esm-exports.d.ts +26 -0
- package/dist/register/esm-exports.d.ts.map +1 -0
- package/dist/register/esm-exports.js +61 -0
- package/dist/register/esm-exports.js.map +1 -0
- package/dist/register/hooks.d.ts +13 -0
- package/dist/register/hooks.d.ts.map +1 -0
- package/dist/register/hooks.js +15 -0
- package/dist/register/hooks.js.map +1 -0
- package/dist/register/index.d.ts +5 -0
- package/dist/register/index.d.ts.map +1 -0
- package/dist/register/index.js +124 -0
- package/dist/register/index.js.map +1 -0
- package/dist/register/mapping.d.ts +19 -0
- package/dist/register/mapping.d.ts.map +1 -0
- package/dist/register/mapping.js +35 -0
- package/dist/register/mapping.js.map +1 -0
- package/dist/remote/index.d.ts +232 -0
- package/dist/remote/index.d.ts.map +1 -0
- package/dist/remote/index.js +720 -0
- package/dist/remote/index.js.map +1 -0
- package/dist/rtdb/crawl-snapshot.d.ts +17 -0
- package/dist/rtdb/crawl-snapshot.d.ts.map +1 -0
- package/dist/rtdb/crawl-snapshot.js +72 -0
- package/dist/rtdb/crawl-snapshot.js.map +1 -0
- package/dist/rtdb/inspection.d.ts +8 -0
- package/dist/rtdb/inspection.d.ts.map +1 -0
- package/dist/rtdb/inspection.js +111 -0
- package/dist/rtdb/inspection.js.map +1 -0
- package/dist/rtdb/load-rules-document.d.ts +25 -0
- package/dist/rtdb/load-rules-document.d.ts.map +1 -0
- package/dist/rtdb/load-rules-document.js +38 -0
- package/dist/rtdb/load-rules-document.js.map +1 -0
- package/dist/rtdb/rules-generation-tool.d.ts +4 -0
- package/dist/rtdb/rules-generation-tool.d.ts.map +1 -0
- package/dist/rtdb/rules-generation-tool.js +35 -0
- package/dist/rtdb/rules-generation-tool.js.map +1 -0
- package/dist/rtdb/rules-json.d.ts +8 -0
- package/dist/rtdb/rules-json.d.ts.map +1 -0
- package/dist/rtdb/rules-json.js +17 -0
- package/dist/rtdb/rules-json.js.map +1 -0
- package/dist/serve/bridge-mount.d.ts +36 -0
- package/dist/serve/bridge-mount.d.ts.map +1 -0
- package/dist/serve/bridge-mount.js +162 -0
- package/dist/serve/bridge-mount.js.map +1 -0
- package/dist/serve/bundler.d.ts +110 -0
- package/dist/serve/bundler.d.ts.map +1 -0
- package/dist/serve/bundler.js +432 -0
- package/dist/serve/bundler.js.map +1 -0
- package/dist/serve/capture-store.d.ts +27 -0
- package/dist/serve/capture-store.d.ts.map +1 -0
- package/dist/serve/capture-store.js +47 -0
- package/dist/serve/capture-store.js.map +1 -0
- package/dist/serve/discovery.d.ts +71 -0
- package/dist/serve/discovery.d.ts.map +1 -0
- package/dist/serve/discovery.js +158 -0
- package/dist/serve/discovery.js.map +1 -0
- package/dist/serve/docs-ui/_astro/_slug_.CQYSemvw.css +1 -0
- package/dist/serve/docs-ui/docs/_rhythm/index.html +99 -0
- package/dist/serve/docs-ui/docs/_rhythm.md +101 -0
- package/dist/serve/docs-ui/docs/api-reference/index.html +64 -0
- package/dist/serve/docs-ui/docs/api-reference.md +67 -0
- package/dist/serve/docs-ui/docs/audit-your-rules/index.html +34 -0
- package/dist/serve/docs-ui/docs/audit-your-rules.md +50 -0
- package/dist/serve/docs-ui/docs/create-pyric-reference-api/index.html +498 -0
- package/dist/serve/docs-ui/docs/create-pyric-reference-api.md +345 -0
- package/dist/serve/docs-ui/docs/firestore-rules-limits/index.html +59 -0
- package/dist/serve/docs-ui/docs/firestore-rules-limits.md +54 -0
- package/dist/serve/docs-ui/docs/how-the-swap-works/index.html +47 -0
- package/dist/serve/docs-ui/docs/how-the-swap-works.md +43 -0
- package/dist/serve/docs-ui/docs/how-we-know-it-matches-firebase/index.html +131 -0
- package/dist/serve/docs-ui/docs/how-we-know-it-matches-firebase.md +169 -0
- package/dist/serve/docs-ui/docs/index.html +2 -0
- package/dist/serve/docs-ui/docs/index.json +18637 -0
- package/dist/serve/docs-ui/docs/overview/index.html +23 -0
- package/dist/serve/docs-ui/docs/overview.md +40 -0
- package/dist/serve/docs-ui/docs/pyric-admin-app/index.html +19 -0
- package/dist/serve/docs-ui/docs/pyric-admin-app-reference-api/index.html +185 -0
- package/dist/serve/docs-ui/docs/pyric-admin-app-reference-api.md +206 -0
- package/dist/serve/docs-ui/docs/pyric-admin-app.md +27 -0
- package/dist/serve/docs-ui/docs/pyric-admin-auth/index.html +24 -0
- package/dist/serve/docs-ui/docs/pyric-admin-auth-reference-api/index.html +617 -0
- package/dist/serve/docs-ui/docs/pyric-admin-auth-reference-api.md +441 -0
- package/dist/serve/docs-ui/docs/pyric-admin-auth.md +29 -0
- package/dist/serve/docs-ui/docs/pyric-admin-database/index.html +26 -0
- package/dist/serve/docs-ui/docs/pyric-admin-database-reference-api/index.html +583 -0
- package/dist/serve/docs-ui/docs/pyric-admin-database-reference-api.md +597 -0
- package/dist/serve/docs-ui/docs/pyric-admin-database.md +31 -0
- package/dist/serve/docs-ui/docs/pyric-admin-firestore/index.html +38 -0
- package/dist/serve/docs-ui/docs/pyric-admin-firestore-explanation-error-translation/index.html +57 -0
- package/dist/serve/docs-ui/docs/pyric-admin-firestore-explanation-error-translation.md +95 -0
- package/dist/serve/docs-ui/docs/pyric-admin-firestore-explanation-per-call-delegate/index.html +58 -0
- package/dist/serve/docs-ui/docs/pyric-admin-firestore-explanation-per-call-delegate.md +94 -0
- package/dist/serve/docs-ui/docs/pyric-admin-firestore-explanation-why-mirror-admin-shape/index.html +59 -0
- package/dist/serve/docs-ui/docs/pyric-admin-firestore-explanation-why-mirror-admin-shape.md +88 -0
- package/dist/serve/docs-ui/docs/pyric-admin-firestore-how-to-run-a-transaction/index.html +53 -0
- package/dist/serve/docs-ui/docs/pyric-admin-firestore-how-to-run-a-transaction.md +76 -0
- package/dist/serve/docs-ui/docs/pyric-admin-firestore-how-to-seed-and-set-rules/index.html +62 -0
- package/dist/serve/docs-ui/docs/pyric-admin-firestore-how-to-seed-and-set-rules.md +96 -0
- package/dist/serve/docs-ui/docs/pyric-admin-firestore-how-to-translate-denials/index.html +80 -0
- package/dist/serve/docs-ui/docs/pyric-admin-firestore-how-to-translate-denials.md +98 -0
- package/dist/serve/docs-ui/docs/pyric-admin-firestore-how-to-use-onsnapshot/index.html +57 -0
- package/dist/serve/docs-ui/docs/pyric-admin-firestore-how-to-use-onsnapshot.md +88 -0
- package/dist/serve/docs-ui/docs/pyric-admin-firestore-how-to-write-a-batch/index.html +50 -0
- package/dist/serve/docs-ui/docs/pyric-admin-firestore-how-to-write-a-batch.md +73 -0
- package/dist/serve/docs-ui/docs/pyric-admin-firestore-reference-api/index.html +32 -0
- package/dist/serve/docs-ui/docs/pyric-admin-firestore-reference-api.md +30 -0
- package/dist/serve/docs-ui/docs/pyric-admin-firestore-reference-onsnapshot/index.html +68 -0
- package/dist/serve/docs-ui/docs/pyric-admin-firestore-reference-onsnapshot.md +81 -0
- package/dist/serve/docs-ui/docs/pyric-admin-firestore-reference-re-exported-types/index.html +76 -0
- package/dist/serve/docs-ui/docs/pyric-admin-firestore-reference-re-exported-types.md +103 -0
- package/dist/serve/docs-ui/docs/pyric-admin-firestore-reference-sandbox-firestore/index.html +40 -0
- package/dist/serve/docs-ui/docs/pyric-admin-firestore-reference-sandbox-firestore.md +77 -0
- package/dist/serve/docs-ui/docs/pyric-admin-firestore-tutorials-01-first-admin-session/index.html +118 -0
- package/dist/serve/docs-ui/docs/pyric-admin-firestore-tutorials-01-first-admin-session.md +166 -0
- package/dist/serve/docs-ui/docs/pyric-admin-firestore.md +53 -0
- package/dist/serve/docs-ui/docs/pyric-admin-storage/index.html +25 -0
- package/dist/serve/docs-ui/docs/pyric-admin-storage-reference-api/index.html +317 -0
- package/dist/serve/docs-ui/docs/pyric-admin-storage-reference-api.md +285 -0
- package/dist/serve/docs-ui/docs/pyric-admin-storage.md +30 -0
- package/dist/serve/docs-ui/docs/pyric-ai-compat/index.html +436 -0
- package/dist/serve/docs-ui/docs/pyric-ai-compat.md +471 -0
- package/dist/serve/docs-ui/docs/pyric-ai-reference-api/index.html +5831 -0
- package/dist/serve/docs-ui/docs/pyric-ai-reference-api.md +5440 -0
- package/dist/serve/docs-ui/docs/pyric-ai-scripting-reference-api/index.html +159 -0
- package/dist/serve/docs-ui/docs/pyric-ai-scripting-reference-api.md +122 -0
- package/dist/serve/docs-ui/docs/pyric-app-compat/index.html +180 -0
- package/dist/serve/docs-ui/docs/pyric-app-compat.md +199 -0
- package/dist/serve/docs-ui/docs/pyric-app-reference-api/index.html +420 -0
- package/dist/serve/docs-ui/docs/pyric-app-reference-api.md +326 -0
- package/dist/serve/docs-ui/docs/pyric-auth/index.html +59 -0
- package/dist/serve/docs-ui/docs/pyric-auth-compat/index.html +804 -0
- package/dist/serve/docs-ui/docs/pyric-auth-compat.md +847 -0
- package/dist/serve/docs-ui/docs/pyric-auth-reference-api/index.html +5452 -0
- package/dist/serve/docs-ui/docs/pyric-auth-reference-api.md +5271 -0
- package/dist/serve/docs-ui/docs/pyric-auth-reference-feature-matrix/index.html +781 -0
- package/dist/serve/docs-ui/docs/pyric-auth-reference-feature-matrix.md +198 -0
- package/dist/serve/docs-ui/docs/pyric-auth-reference-sandbox-test-driver/index.html +71 -0
- package/dist/serve/docs-ui/docs/pyric-auth-reference-sandbox-test-driver.md +108 -0
- package/dist/serve/docs-ui/docs/pyric-auth.md +86 -0
- package/dist/serve/docs-ui/docs/pyric-cli/index.html +40 -0
- package/dist/serve/docs-ui/docs/pyric-cli-assurance-browser-reference-api/index.html +98 -0
- package/dist/serve/docs-ui/docs/pyric-cli-assurance-browser-reference-api.md +88 -0
- package/dist/serve/docs-ui/docs/pyric-cli-assurance-reference-api/index.html +2355 -0
- package/dist/serve/docs-ui/docs/pyric-cli-assurance-reference-api.md +1554 -0
- package/dist/serve/docs-ui/docs/pyric-cli-bridge/index.html +69 -0
- package/dist/serve/docs-ui/docs/pyric-cli-bridge-client-reference-api/index.html +546 -0
- package/dist/serve/docs-ui/docs/pyric-cli-bridge-client-reference-api.md +485 -0
- package/dist/serve/docs-ui/docs/pyric-cli-bridge-reference-api/index.html +506 -0
- package/dist/serve/docs-ui/docs/pyric-cli-bridge-reference-api.md +419 -0
- package/dist/serve/docs-ui/docs/pyric-cli-bridge.md +99 -0
- package/dist/serve/docs-ui/docs/pyric-cli-credentials-node-reference-api/index.html +67 -0
- package/dist/serve/docs-ui/docs/pyric-cli-credentials-node-reference-api.md +59 -0
- package/dist/serve/docs-ui/docs/pyric-cli-discover-reference-api/index.html +2355 -0
- package/dist/serve/docs-ui/docs/pyric-cli-discover-reference-api.md +2036 -0
- package/dist/serve/docs-ui/docs/pyric-cli-functions-rtdb-compat/index.html +112 -0
- package/dist/serve/docs-ui/docs/pyric-cli-functions-rtdb-compat.md +124 -0
- package/dist/serve/docs-ui/docs/pyric-cli-how-to-build-a-standalone-binary/index.html +91 -0
- package/dist/serve/docs-ui/docs/pyric-cli-how-to-build-a-standalone-binary.md +105 -0
- package/dist/serve/docs-ui/docs/pyric-cli-how-to-promote-sandbox-state-to-a-fixture/index.html +52 -0
- package/dist/serve/docs-ui/docs/pyric-cli-how-to-promote-sandbox-state-to-a-fixture.md +98 -0
- package/dist/serve/docs-ui/docs/pyric-cli-how-to-run-rtdb-onvaluecreated/index.html +66 -0
- package/dist/serve/docs-ui/docs/pyric-cli-how-to-run-rtdb-onvaluecreated.md +100 -0
- package/dist/serve/docs-ui/docs/pyric-cli-how-to-serve-persistence-and-multi-tab/index.html +228 -0
- package/dist/serve/docs-ui/docs/pyric-cli-how-to-serve-persistence-and-multi-tab.md +179 -0
- package/dist/serve/docs-ui/docs/pyric-cli-how-to-use-the-vite-plugin/index.html +341 -0
- package/dist/serve/docs-ui/docs/pyric-cli-how-to-use-the-vite-plugin.md +309 -0
- package/dist/serve/docs-ui/docs/pyric-cli-how-to-verify-against-a-captured-session/index.html +128 -0
- package/dist/serve/docs-ui/docs/pyric-cli-how-to-verify-against-a-captured-session.md +207 -0
- package/dist/serve/docs-ui/docs/pyric-cli-reference-cli/index.html +404 -0
- package/dist/serve/docs-ui/docs/pyric-cli-reference-cli.md +249 -0
- package/dist/serve/docs-ui/docs/pyric-cli-reference-package-and-resolution/index.html +93 -0
- package/dist/serve/docs-ui/docs/pyric-cli-reference-package-and-resolution.md +65 -0
- package/dist/serve/docs-ui/docs/pyric-cli-reference-verify/index.html +81 -0
- package/dist/serve/docs-ui/docs/pyric-cli-reference-verify.md +110 -0
- package/dist/serve/docs-ui/docs/pyric-cli-register-reference-api/index.html +10 -0
- package/dist/serve/docs-ui/docs/pyric-cli-register-reference-api.md +16 -0
- package/dist/serve/docs-ui/docs/pyric-cli-remote-reference-api/index.html +1044 -0
- package/dist/serve/docs-ui/docs/pyric-cli-remote-reference-api.md +952 -0
- package/dist/serve/docs-ui/docs/pyric-cli-serve-worker-reference-api/index.html +5041 -0
- package/dist/serve/docs-ui/docs/pyric-cli-serve-worker-reference-api.md +4739 -0
- package/dist/serve/docs-ui/docs/pyric-cli-tutorials-server-adoption/index.html +219 -0
- package/dist/serve/docs-ui/docs/pyric-cli-tutorials-server-adoption.md +251 -0
- package/dist/serve/docs-ui/docs/pyric-cli-tutorials-wire-claude-code/index.html +136 -0
- package/dist/serve/docs-ui/docs/pyric-cli-tutorials-wire-claude-code.md +217 -0
- package/dist/serve/docs-ui/docs/pyric-cli-verify-reference-api/index.html +926 -0
- package/dist/serve/docs-ui/docs/pyric-cli-verify-reference-api.md +586 -0
- package/dist/serve/docs-ui/docs/pyric-cli-vite-reference-api/index.html +102 -0
- package/dist/serve/docs-ui/docs/pyric-cli-vite-reference-api.md +76 -0
- package/dist/serve/docs-ui/docs/pyric-cli.md +42 -0
- package/dist/serve/docs-ui/docs/pyric-conformance-scores/index.html +180 -0
- package/dist/serve/docs-ui/docs/pyric-conformance-scores.md +184 -0
- package/dist/serve/docs-ui/docs/pyric-database/index.html +43 -0
- package/dist/serve/docs-ui/docs/pyric-database-compat/index.html +1224 -0
- package/dist/serve/docs-ui/docs/pyric-database-compat.md +1289 -0
- package/dist/serve/docs-ui/docs/pyric-database-explanation-rules-authoring-and-deploy-are-separate/index.html +16 -0
- package/dist/serve/docs-ui/docs/pyric-database-explanation-rules-authoring-and-deploy-are-separate.md +23 -0
- package/dist/serve/docs-ui/docs/pyric-database-reference-api/index.html +1851 -0
- package/dist/serve/docs-ui/docs/pyric-database-reference-api.md +1842 -0
- package/dist/serve/docs-ui/docs/pyric-database-reference-constraints/index.html +381 -0
- package/dist/serve/docs-ui/docs/pyric-database-reference-constraints.md +168 -0
- package/dist/serve/docs-ui/docs/pyric-database-reference-rules-tooling/index.html +218 -0
- package/dist/serve/docs-ui/docs/pyric-database-reference-rules-tooling.md +303 -0
- package/dist/serve/docs-ui/docs/pyric-database-tutorials-01-author-rtdb-rules-with-constraints/index.html +125 -0
- package/dist/serve/docs-ui/docs/pyric-database-tutorials-01-author-rtdb-rules-with-constraints.md +171 -0
- package/dist/serve/docs-ui/docs/pyric-database.md +26 -0
- package/dist/serve/docs-ui/docs/pyric-explanation-versioning-and-compatibility/index.html +40 -0
- package/dist/serve/docs-ui/docs/pyric-explanation-versioning-and-compatibility.md +68 -0
- package/dist/serve/docs-ui/docs/pyric-firestore/index.html +48 -0
- package/dist/serve/docs-ui/docs/pyric-firestore-compat/index.html +868 -0
- package/dist/serve/docs-ui/docs/pyric-firestore-compat.md +939 -0
- package/dist/serve/docs-ui/docs/pyric-firestore-explanation-rules-tooling-is-separate/index.html +92 -0
- package/dist/serve/docs-ui/docs/pyric-firestore-explanation-rules-tooling-is-separate.md +70 -0
- package/dist/serve/docs-ui/docs/pyric-firestore-explanation-target-symbol-opacity/index.html +59 -0
- package/dist/serve/docs-ui/docs/pyric-firestore-explanation-target-symbol-opacity.md +91 -0
- package/dist/serve/docs-ui/docs/pyric-firestore-explanation-two-backends-one-surface/index.html +43 -0
- package/dist/serve/docs-ui/docs/pyric-firestore-explanation-two-backends-one-surface.md +58 -0
- package/dist/serve/docs-ui/docs/pyric-firestore-how-to-migrate-from-firebase-firestore/index.html +58 -0
- package/dist/serve/docs-ui/docs/pyric-firestore-how-to-migrate-from-firebase-firestore.md +86 -0
- package/dist/serve/docs-ui/docs/pyric-firestore-how-to-pick-a-backend/index.html +52 -0
- package/dist/serve/docs-ui/docs/pyric-firestore-how-to-pick-a-backend.md +83 -0
- package/dist/serve/docs-ui/docs/pyric-firestore-how-to-run-a-transaction/index.html +42 -0
- package/dist/serve/docs-ui/docs/pyric-firestore-how-to-run-a-transaction.md +59 -0
- package/dist/serve/docs-ui/docs/pyric-firestore-how-to-use-onsnapshot/index.html +66 -0
- package/dist/serve/docs-ui/docs/pyric-firestore-how-to-use-onsnapshot.md +96 -0
- package/dist/serve/docs-ui/docs/pyric-firestore-how-to-use-sandbox-ops/index.html +61 -0
- package/dist/serve/docs-ui/docs/pyric-firestore-how-to-use-sandbox-ops.md +92 -0
- package/dist/serve/docs-ui/docs/pyric-firestore-reference-api/index.html +3623 -0
- package/dist/serve/docs-ui/docs/pyric-firestore-reference-api.md +3399 -0
- package/dist/serve/docs-ui/docs/pyric-firestore-reference-feature-matrix/index.html +80 -0
- package/dist/serve/docs-ui/docs/pyric-firestore-reference-feature-matrix.md +66 -0
- package/dist/serve/docs-ui/docs/pyric-firestore-reference-getfirestore/index.html +46 -0
- package/dist/serve/docs-ui/docs/pyric-firestore-reference-getfirestore.md +73 -0
- package/dist/serve/docs-ui/docs/pyric-firestore-reference-query-constraints/index.html +80 -0
- package/dist/serve/docs-ui/docs/pyric-firestore-reference-query-constraints.md +129 -0
- package/dist/serve/docs-ui/docs/pyric-firestore-reference-sandbox-ops/index.html +58 -0
- package/dist/serve/docs-ui/docs/pyric-firestore-reference-sandbox-ops.md +88 -0
- package/dist/serve/docs-ui/docs/pyric-firestore-reference-tool-factories/index.html +51 -0
- package/dist/serve/docs-ui/docs/pyric-firestore-reference-tool-factories.md +71 -0
- package/dist/serve/docs-ui/docs/pyric-firestore-tutorials-01-write-a-sandbox-demo/index.html +130 -0
- package/dist/serve/docs-ui/docs/pyric-firestore-tutorials-01-write-a-sandbox-demo.md +180 -0
- package/dist/serve/docs-ui/docs/pyric-firestore-tutorials-02-swap-to-prod-backend/index.html +59 -0
- package/dist/serve/docs-ui/docs/pyric-firestore-tutorials-02-swap-to-prod-backend.md +92 -0
- package/dist/serve/docs-ui/docs/pyric-firestore-values-reference-api/index.html +30 -0
- package/dist/serve/docs-ui/docs/pyric-firestore-values-reference-api.md +30 -0
- package/dist/serve/docs-ui/docs/pyric-firestore.md +72 -0
- package/dist/serve/docs-ui/docs/pyric-messaging-compat/index.html +300 -0
- package/dist/serve/docs-ui/docs/pyric-messaging-compat.md +321 -0
- package/dist/serve/docs-ui/docs/pyric-messaging-reference-api/index.html +508 -0
- package/dist/serve/docs-ui/docs/pyric-messaging-reference-api.md +374 -0
- package/dist/serve/docs-ui/docs/pyric-messaging-sw-reference-api/index.html +482 -0
- package/dist/serve/docs-ui/docs/pyric-messaging-sw-reference-api.md +348 -0
- package/dist/serve/docs-ui/docs/pyric-rules/index.html +87 -0
- package/dist/serve/docs-ui/docs/pyric-rules-compat/index.html +328 -0
- package/dist/serve/docs-ui/docs/pyric-rules-compat.md +347 -0
- package/dist/serve/docs-ui/docs/pyric-rules-explanation-agent-failure-modes/index.html +50 -0
- package/dist/serve/docs-ui/docs/pyric-rules-explanation-agent-failure-modes.md +78 -0
- package/dist/serve/docs-ui/docs/pyric-rules-explanation-lint-vs-validate-vs-simulate-vs-test/index.html +79 -0
- package/dist/serve/docs-ui/docs/pyric-rules-explanation-lint-vs-validate-vs-simulate-vs-test.md +69 -0
- package/dist/serve/docs-ui/docs/pyric-rules-explanation-runtime-budget-and-shared-gates/index.html +67 -0
- package/dist/serve/docs-ui/docs/pyric-rules-explanation-runtime-budget-and-shared-gates.md +75 -0
- package/dist/serve/docs-ui/docs/pyric-rules-explanation-sentinel-expression-engine/index.html +49 -0
- package/dist/serve/docs-ui/docs/pyric-rules-explanation-sentinel-expression-engine.md +74 -0
- package/dist/serve/docs-ui/docs/pyric-rules-explanation-simulator-vs-rules-test-api/index.html +95 -0
- package/dist/serve/docs-ui/docs/pyric-rules-explanation-simulator-vs-rules-test-api.md +80 -0
- package/dist/serve/docs-ui/docs/pyric-rules-explanation-the-2-plus-modules-extension/index.html +58 -0
- package/dist/serve/docs-ui/docs/pyric-rules-explanation-the-2-plus-modules-extension.md +79 -0
- package/dist/serve/docs-ui/docs/pyric-rules-explanation-value-wrappers-design/index.html +63 -0
- package/dist/serve/docs-ui/docs/pyric-rules-explanation-value-wrappers-design.md +84 -0
- package/dist/serve/docs-ui/docs/pyric-rules-explanation-why-this-package-exists/index.html +34 -0
- package/dist/serve/docs-ui/docs/pyric-rules-explanation-why-this-package-exists.md +43 -0
- package/dist/serve/docs-ui/docs/pyric-rules-how-to-compare-rulesets-for-weakening/index.html +55 -0
- package/dist/serve/docs-ui/docs/pyric-rules-how-to-compare-rulesets-for-weakening.md +77 -0
- package/dist/serve/docs-ui/docs/pyric-rules-how-to-inspect-rules-via-the-ast/index.html +90 -0
- package/dist/serve/docs-ui/docs/pyric-rules-how-to-inspect-rules-via-the-ast.md +129 -0
- package/dist/serve/docs-ui/docs/pyric-rules-how-to-lint-rules-source/index.html +55 -0
- package/dist/serve/docs-ui/docs/pyric-rules-how-to-lint-rules-source.md +84 -0
- package/dist/serve/docs-ui/docs/pyric-rules-how-to-pin-request-time/index.html +49 -0
- package/dist/serve/docs-ui/docs/pyric-rules-how-to-pin-request-time.md +64 -0
- package/dist/serve/docs-ui/docs/pyric-rules-how-to-register-tools-with-an-agent/index.html +61 -0
- package/dist/serve/docs-ui/docs/pyric-rules-how-to-register-tools-with-an-agent.md +87 -0
- package/dist/serve/docs-ui/docs/pyric-rules-how-to-resolve-module-imports/index.html +93 -0
- package/dist/serve/docs-ui/docs/pyric-rules-how-to-resolve-module-imports.md +105 -0
- package/dist/serve/docs-ui/docs/pyric-rules-how-to-simulate-rules-locally/index.html +89 -0
- package/dist/serve/docs-ui/docs/pyric-rules-how-to-simulate-rules-locally.md +134 -0
- package/dist/serve/docs-ui/docs/pyric-rules-how-to-test-rules-against-firebase/index.html +66 -0
- package/dist/serve/docs-ui/docs/pyric-rules-how-to-test-rules-against-firebase.md +102 -0
- package/dist/serve/docs-ui/docs/pyric-rules-reference-api/index.html +2629 -0
- package/dist/serve/docs-ui/docs/pyric-rules-reference-api.md +2213 -0
- package/dist/serve/docs-ui/docs/pyric-rules-reference-ast/index.html +85 -0
- package/dist/serve/docs-ui/docs/pyric-rules-reference-ast.md +121 -0
- package/dist/serve/docs-ui/docs/pyric-rules-reference-conformance-gaps/index.html +277 -0
- package/dist/serve/docs-ui/docs/pyric-rules-reference-conformance-gaps.md +360 -0
- package/dist/serve/docs-ui/docs/pyric-rules-reference-errors/index.html +76 -0
- package/dist/serve/docs-ui/docs/pyric-rules-reference-errors.md +123 -0
- package/dist/serve/docs-ui/docs/pyric-rules-reference-lint-rules/index.html +148 -0
- package/dist/serve/docs-ui/docs/pyric-rules-reference-lint-rules.md +159 -0
- package/dist/serve/docs-ui/docs/pyric-rules-reference-simulator-context/index.html +66 -0
- package/dist/serve/docs-ui/docs/pyric-rules-reference-simulator-context.md +104 -0
- package/dist/serve/docs-ui/docs/pyric-rules-reference-stdlib-modules/index.html +241 -0
- package/dist/serve/docs-ui/docs/pyric-rules-reference-stdlib-modules.md +143 -0
- package/dist/serve/docs-ui/docs/pyric-rules-reference-test-case-schema/index.html +94 -0
- package/dist/serve/docs-ui/docs/pyric-rules-reference-test-case-schema.md +121 -0
- package/dist/serve/docs-ui/docs/pyric-rules-reference-validator-findings/index.html +87 -0
- package/dist/serve/docs-ui/docs/pyric-rules-reference-validator-findings.md +117 -0
- package/dist/serve/docs-ui/docs/pyric-rules-reference-value-wrappers/index.html +102 -0
- package/dist/serve/docs-ui/docs/pyric-rules-reference-value-wrappers.md +152 -0
- package/dist/serve/docs-ui/docs/pyric-rules.md +93 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox/index.html +67 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-database-reference-api/index.html +120 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-database-reference-api.md +110 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-explanation-every-op-is-a-request/index.html +141 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-explanation-every-op-is-a-request.md +161 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-explanation-identity-is-a-context/index.html +66 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-explanation-identity-is-a-context.md +110 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-explanation-internal-adapter-protocol/index.html +71 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-explanation-internal-adapter-protocol.md +111 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-explanation-listener-re-evaluation/index.html +56 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-explanation-listener-re-evaluation.md +82 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-explanation-local-backend-vs-firestore-offline/index.html +64 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-explanation-local-backend-vs-firestore-offline.md +56 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-explanation-why-adapters-are-siblings/index.html +92 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-explanation-why-adapters-are-siblings.md +90 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-explanation-why-this-package-exists/index.html +69 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-explanation-why-this-package-exists.md +57 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-firestore-reference-api/index.html +202 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-firestore-reference-api.md +134 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-how-to-multiple-isolated-sandboxes/index.html +63 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-how-to-multiple-isolated-sandboxes.md +89 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-how-to-observe-events/index.html +159 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-how-to-observe-events.md +168 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-how-to-pick-an-adapter/index.html +79 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-how-to-pick-an-adapter.md +75 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-how-to-replay-events/index.html +88 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-how-to-replay-events.md +92 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-how-to-reset-between-tests/index.html +68 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-how-to-reset-between-tests.md +92 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-how-to-seed-data-and-rules/index.html +91 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-how-to-seed-data-and-rules.md +122 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-how-to-switch-users/index.html +50 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-how-to-switch-users.md +78 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-how-to-use-admin-reads/index.html +54 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-how-to-use-admin-reads.md +85 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-reference-api/index.html +5019 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-reference-api.md +4060 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-reference-divergences/index.html +125 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-reference-divergences.md +151 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-reference-error-codes/index.html +110 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-reference-error-codes.md +118 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-reference-internal-protocol/index.html +72 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-reference-internal-protocol.md +109 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-reference-sandbox-and-context/index.html +90 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-reference-sandbox-and-context.md +140 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-reference-sandbox-event/index.html +146 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-reference-sandbox-event.md +204 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-reference-snapshot-and-admin/index.html +53 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-reference-snapshot-and-admin.md +89 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-tutorials-01-your-first-sandbox-session/index.html +115 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox-tutorials-01-your-first-sandbox-session.md +176 -0
- package/dist/serve/docs-ui/docs/pyric-sandbox.md +69 -0
- package/dist/serve/docs-ui/docs/pyric-storage/index.html +65 -0
- package/dist/serve/docs-ui/docs/pyric-storage-compat/index.html +676 -0
- package/dist/serve/docs-ui/docs/pyric-storage-compat.md +699 -0
- package/dist/serve/docs-ui/docs/pyric-storage-explanation-implementation-scope/index.html +52 -0
- package/dist/serve/docs-ui/docs/pyric-storage-explanation-implementation-scope.md +85 -0
- package/dist/serve/docs-ui/docs/pyric-storage-explanation-session-archive-use-case/index.html +58 -0
- package/dist/serve/docs-ui/docs/pyric-storage-explanation-session-archive-use-case.md +82 -0
- package/dist/serve/docs-ui/docs/pyric-storage-explanation-why-indexeddb/index.html +50 -0
- package/dist/serve/docs-ui/docs/pyric-storage-explanation-why-indexeddb.md +82 -0
- package/dist/serve/docs-ui/docs/pyric-storage-how-to-enforce-rules/index.html +120 -0
- package/dist/serve/docs-ui/docs/pyric-storage-how-to-enforce-rules.md +127 -0
- package/dist/serve/docs-ui/docs/pyric-storage-how-to-list-and-delete/index.html +53 -0
- package/dist/serve/docs-ui/docs/pyric-storage-how-to-list-and-delete.md +86 -0
- package/dist/serve/docs-ui/docs/pyric-storage-how-to-switch-backends/index.html +43 -0
- package/dist/serve/docs-ui/docs/pyric-storage-how-to-switch-backends.md +65 -0
- package/dist/serve/docs-ui/docs/pyric-storage-how-to-test-rule-expressions/index.html +70 -0
- package/dist/serve/docs-ui/docs/pyric-storage-how-to-test-rule-expressions.md +88 -0
- package/dist/serve/docs-ui/docs/pyric-storage-reference-api/index.html +2120 -0
- package/dist/serve/docs-ui/docs/pyric-storage-reference-api.md +1687 -0
- package/dist/serve/docs-ui/docs/pyric-storage-reference-conformance-gaps/index.html +137 -0
- package/dist/serve/docs-ui/docs/pyric-storage-reference-conformance-gaps.md +171 -0
- package/dist/serve/docs-ui/docs/pyric-storage-reference-error-codes/index.html +37 -0
- package/dist/serve/docs-ui/docs/pyric-storage-reference-error-codes.md +57 -0
- package/dist/serve/docs-ui/docs/pyric-storage-reference-rules-subset/index.html +96 -0
- package/dist/serve/docs-ui/docs/pyric-storage-reference-rules-subset.md +134 -0
- package/dist/serve/docs-ui/docs/pyric-storage-reference-storage-options/index.html +39 -0
- package/dist/serve/docs-ui/docs/pyric-storage-reference-storage-options.md +61 -0
- package/dist/serve/docs-ui/docs/pyric-storage.md +67 -0
- package/dist/serve/docs-ui/docs/pyric-ui-agents-reference-api/index.html +638 -0
- package/dist/serve/docs-ui/docs/pyric-ui-agents-reference-api.md +430 -0
- package/dist/serve/docs-ui/docs/pyric-ui-auth-hooks-reference-api/index.html +813 -0
- package/dist/serve/docs-ui/docs/pyric-ui-auth-hooks-reference-api.md +634 -0
- package/dist/serve/docs-ui/docs/pyric-ui-auth-reference-api/index.html +1708 -0
- package/dist/serve/docs-ui/docs/pyric-ui-auth-reference-api.md +1300 -0
- package/dist/serve/docs-ui/docs/pyric-ui-events-hooks-reference-api/index.html +177 -0
- package/dist/serve/docs-ui/docs/pyric-ui-events-hooks-reference-api.md +111 -0
- package/dist/serve/docs-ui/docs/pyric-ui-events-reference-api/index.html +1542 -0
- package/dist/serve/docs-ui/docs/pyric-ui-events-reference-api.md +903 -0
- package/dist/serve/docs-ui/docs/pyric-ui-firestore-hooks-reference-api/index.html +1024 -0
- package/dist/serve/docs-ui/docs/pyric-ui-firestore-hooks-reference-api.md +640 -0
- package/dist/serve/docs-ui/docs/pyric-ui-firestore-reference-api/index.html +2753 -0
- package/dist/serve/docs-ui/docs/pyric-ui-firestore-reference-api.md +2171 -0
- package/dist/serve/docs-ui/docs/pyric-ui-primitives-reference-api/index.html +1005 -0
- package/dist/serve/docs-ui/docs/pyric-ui-primitives-reference-api.md +693 -0
- package/dist/serve/docs-ui/docs/pyric-ui-rtdb-reference-api/index.html +1388 -0
- package/dist/serve/docs-ui/docs/pyric-ui-rtdb-reference-api.md +1340 -0
- package/dist/serve/docs-ui/docs/pyric-ui-rules-hooks-reference-api/index.html +131 -0
- package/dist/serve/docs-ui/docs/pyric-ui-rules-hooks-reference-api.md +76 -0
- package/dist/serve/docs-ui/docs/pyric-ui-rules-reference-api/index.html +648 -0
- package/dist/serve/docs-ui/docs/pyric-ui-rules-reference-api.md +508 -0
- package/dist/serve/docs-ui/docs/pyric-ui-storage-hooks-reference-api/index.html +1457 -0
- package/dist/serve/docs-ui/docs/pyric-ui-storage-hooks-reference-api.md +1029 -0
- package/dist/serve/docs-ui/docs/pyric-ui-storage-reference-api/index.html +2476 -0
- package/dist/serve/docs-ui/docs/pyric-ui-storage-reference-api.md +1919 -0
- package/dist/serve/docs-ui/docs/pyric-ui-traffic-hooks-reference-api/index.html +1241 -0
- package/dist/serve/docs-ui/docs/pyric-ui-traffic-hooks-reference-api.md +817 -0
- package/dist/serve/docs-ui/docs/pyric-ui-traffic-reference-api/index.html +2289 -0
- package/dist/serve/docs-ui/docs/pyric-ui-traffic-reference-api.md +1489 -0
- package/dist/serve/docs-ui/docs/read-a-denial/index.html +40 -0
- package/dist/serve/docs-ui/docs/read-a-denial.md +62 -0
- package/dist/serve/docs-ui/docs/receive-messages/index.html +28 -0
- package/dist/serve/docs-ui/docs/receive-messages.md +43 -0
- package/dist/serve/docs-ui/docs/rtdb-rules-in-typescript/index.html +67 -0
- package/dist/serve/docs-ui/docs/rtdb-rules-in-typescript.md +101 -0
- package/dist/serve/docs-ui/docs/rules-patterns/index.html +68 -0
- package/dist/serve/docs-ui/docs/rules-patterns.md +104 -0
- package/dist/serve/docs-ui/docs/rules-standard-library/index.html +87 -0
- package/dist/serve/docs-ui/docs/rules-standard-library.md +93 -0
- package/dist/serve/docs-ui/docs/run-ai-logic-locally/index.html +27 -0
- package/dist/serve/docs-ui/docs/run-ai-logic-locally.md +43 -0
- package/dist/serve/docs-ui/docs/secure-it-with-rules/index.html +69 -0
- package/dist/serve/docs-ui/docs/secure-it-with-rules.md +101 -0
- package/dist/serve/docs-ui/docs/see-whats-happening/index.html +73 -0
- package/dist/serve/docs-ui/docs/see-whats-happening.md +77 -0
- package/dist/serve/docs-ui/docs/set-up-the-project/index.html +14 -0
- package/dist/serve/docs-ui/docs/set-up-the-project.md +19 -0
- package/dist/serve/docs-ui/docs/set-up-your-agent/index.html +42 -0
- package/dist/serve/docs-ui/docs/set-up-your-agent.md +86 -0
- package/dist/serve/docs-ui/docs/shape-your-data/index.html +44 -0
- package/dist/serve/docs-ui/docs/shape-your-data.md +88 -0
- package/dist/serve/docs-ui/docs/ship-to-production/index.html +36 -0
- package/dist/serve/docs-ui/docs/ship-to-production.md +80 -0
- package/dist/serve/docs-ui/docs/sign-in-and-manage-users/index.html +31 -0
- package/dist/serve/docs-ui/docs/sign-in-and-manage-users.md +50 -0
- package/dist/serve/docs-ui/docs/simulate-and-lint/index.html +95 -0
- package/dist/serve/docs-ui/docs/simulate-and-lint.md +99 -0
- package/dist/serve/docs-ui/docs/skills/index.html +20 -0
- package/dist/serve/docs-ui/docs/skills.md +34 -0
- package/dist/serve/docs-ui/docs/start-building/index.html +32 -0
- package/dist/serve/docs-ui/docs/start-building.md +64 -0
- package/dist/serve/docs-ui/docs/store-and-query-data/index.html +16 -0
- package/dist/serve/docs-ui/docs/store-and-query-data.md +33 -0
- package/dist/serve/docs-ui/docs/store-files/index.html +13 -0
- package/dist/serve/docs-ui/docs/store-files.md +25 -0
- package/dist/serve/docs-ui/docs/sync-realtime-data/index.html +15 -0
- package/dist/serve/docs-ui/docs/sync-realtime-data.md +27 -0
- package/dist/serve/docs-ui/docs/test-in-node/index.html +74 -0
- package/dist/serve/docs-ui/docs/test-in-node.md +100 -0
- package/dist/serve/docs-ui/docs/ui/index.html +76 -0
- package/dist/serve/docs-ui/docs/ui-auth-authsigninhelper/index.html +194 -0
- package/dist/serve/docs-ui/docs/ui-auth-authsigninhelper.md +114 -0
- package/dist/serve/docs-ui/docs/ui-auth-authusers/index.html +263 -0
- package/dist/serve/docs-ui/docs/ui-auth-authusers.md +183 -0
- package/dist/serve/docs-ui/docs/ui-firestore-collectionlist/index.html +92 -0
- package/dist/serve/docs-ui/docs/ui-firestore-collectionlist.md +79 -0
- package/dist/serve/docs-ui/docs/ui-firestore-deletewithconfirm/index.html +128 -0
- package/dist/serve/docs-ui/docs/ui-firestore-deletewithconfirm.md +104 -0
- package/dist/serve/docs-ui/docs/ui-firestore-documenteditor/index.html +154 -0
- package/dist/serve/docs-ui/docs/ui-firestore-documenteditor.md +117 -0
- package/dist/serve/docs-ui/docs/ui-firestore-documentlist/index.html +132 -0
- package/dist/serve/docs-ui/docs/ui-firestore-documentlist.md +92 -0
- package/dist/serve/docs-ui/docs/ui-firestore-documentpreview/index.html +159 -0
- package/dist/serve/docs-ui/docs/ui-firestore-documentpreview.md +84 -0
- package/dist/serve/docs-ui/docs/ui-firestore-querybuilder/index.html +104 -0
- package/dist/serve/docs-ui/docs/ui-firestore-querybuilder.md +103 -0
- package/dist/serve/docs-ui/docs/ui-firestore-referencepicker/index.html +113 -0
- package/dist/serve/docs-ui/docs/ui-firestore-referencepicker.md +93 -0
- package/dist/serve/docs-ui/docs/ui-primitives-badge/index.html +56 -0
- package/dist/serve/docs-ui/docs/ui-primitives-badge.md +40 -0
- package/dist/serve/docs-ui/docs/ui-primitives-confirmdialog/index.html +140 -0
- package/dist/serve/docs-ui/docs/ui-primitives-confirmdialog.md +108 -0
- package/dist/serve/docs-ui/docs/ui-primitives-copybutton/index.html +58 -0
- package/dist/serve/docs-ui/docs/ui-primitives-copybutton.md +37 -0
- package/dist/serve/docs-ui/docs/ui-primitives-jsonview/index.html +58 -0
- package/dist/serve/docs-ui/docs/ui-primitives-jsonview.md +47 -0
- package/dist/serve/docs-ui/docs/ui-primitives-segmentedcontrol/index.html +70 -0
- package/dist/serve/docs-ui/docs/ui-primitives-segmentedcontrol.md +50 -0
- package/dist/serve/docs-ui/docs/ui-primitives-toast/index.html +87 -0
- package/dist/serve/docs-ui/docs/ui-primitives-toast.md +82 -0
- package/dist/serve/docs-ui/docs/ui-primitives-virtuallist/index.html +85 -0
- package/dist/serve/docs-ui/docs/ui-primitives-virtuallist.md +54 -0
- package/dist/serve/docs-ui/docs/ui-storage/index.html +150 -0
- package/dist/serve/docs-ui/docs/ui-storage-deleteselectionwithconfirm/index.html +126 -0
- package/dist/serve/docs-ui/docs/ui-storage-deleteselectionwithconfirm.md +88 -0
- package/dist/serve/docs-ui/docs/ui-storage-objectbrowser/index.html +137 -0
- package/dist/serve/docs-ui/docs/ui-storage-objectbrowser.md +90 -0
- package/dist/serve/docs-ui/docs/ui-storage-objectinspector/index.html +139 -0
- package/dist/serve/docs-ui/docs/ui-storage-objectinspector.md +93 -0
- package/dist/serve/docs-ui/docs/ui-storage-pathbreadcrumb/index.html +72 -0
- package/dist/serve/docs-ui/docs/ui-storage-pathbreadcrumb.md +57 -0
- package/dist/serve/docs-ui/docs/ui-storage-rules-aware-affordances/index.html +60 -0
- package/dist/serve/docs-ui/docs/ui-storage-rules-aware-affordances.md +52 -0
- package/dist/serve/docs-ui/docs/ui-storage-uploaddropzone/index.html +93 -0
- package/dist/serve/docs-ui/docs/ui-storage-uploaddropzone.md +78 -0
- package/dist/serve/docs-ui/docs/ui-storage-usestoragerulesgate/index.html +144 -0
- package/dist/serve/docs-ui/docs/ui-storage-usestoragerulesgate.md +101 -0
- package/dist/serve/docs-ui/docs/ui-storage.md +165 -0
- package/dist/serve/docs-ui/docs/ui-traffic/index.html +88 -0
- package/dist/serve/docs-ui/docs/ui-traffic-ruleheatmap/index.html +79 -0
- package/dist/serve/docs-ui/docs/ui-traffic-ruleheatmap.md +60 -0
- package/dist/serve/docs-ui/docs/ui-traffic-trafficdetail/index.html +78 -0
- package/dist/serve/docs-ui/docs/ui-traffic-trafficdetail.md +59 -0
- package/dist/serve/docs-ui/docs/ui-traffic-trafficlog/index.html +118 -0
- package/dist/serve/docs-ui/docs/ui-traffic-trafficlog.md +69 -0
- package/dist/serve/docs-ui/docs/ui-traffic-trafficstats/index.html +51 -0
- package/dist/serve/docs-ui/docs/ui-traffic-trafficstats.md +46 -0
- package/dist/serve/docs-ui/docs/ui-traffic.md +102 -0
- package/dist/serve/docs-ui/docs/ui.md +90 -0
- package/dist/serve/docs-ui/docs/watch-and-review/index.html +25 -0
- package/dist/serve/docs-ui/docs/watch-and-review.md +40 -0
- package/dist/serve/docs-ui/docs/what-your-agent-can-do/index.html +81 -0
- package/dist/serve/docs-ui/docs/what-your-agent-can-do.md +78 -0
- package/dist/serve/docs-ui/docs/whats-experimental/index.html +22 -0
- package/dist/serve/docs-ui/docs/whats-experimental.md +33 -0
- package/dist/serve/docs-ui/docs/whats-possible/index.html +63 -0
- package/dist/serve/docs-ui/docs/whats-possible.md +53 -0
- package/dist/serve/docs-ui/docs/which-data-service/index.html +8 -0
- package/dist/serve/docs-ui/docs/which-data-service.md +11 -0
- package/dist/serve/docs-ui/docs/write-a-rules-test-suite/index.html +85 -0
- package/dist/serve/docs-ui/docs/write-a-rules-test-suite.md +119 -0
- package/dist/serve/docs-ui/index.html +1 -0
- package/dist/serve/docs-ui/llms.txt +308 -0
- package/dist/serve/entries/ai.d.ts +4 -0
- package/dist/serve/entries/ai.d.ts.map +1 -0
- package/dist/serve/entries/ai.js +184 -0
- package/dist/serve/entries/ai.js.map +1 -0
- package/dist/serve/entries/app-backend.d.ts +2 -0
- package/dist/serve/entries/app-backend.d.ts.map +1 -0
- package/dist/serve/entries/app-backend.js +4 -0
- package/dist/serve/entries/app-backend.js.map +1 -0
- package/dist/serve/entries/app-client.d.ts +5 -0
- package/dist/serve/entries/app-client.d.ts.map +1 -0
- package/dist/serve/entries/app-client.js +23 -0
- package/dist/serve/entries/app-client.js.map +1 -0
- package/dist/serve/entries/app-session-store.d.ts +14 -0
- package/dist/serve/entries/app-session-store.d.ts.map +1 -0
- package/dist/serve/entries/app-session-store.js +37 -0
- package/dist/serve/entries/app-session-store.js.map +1 -0
- package/dist/serve/entries/app.d.ts +2 -0
- package/dist/serve/entries/app.d.ts.map +1 -0
- package/dist/serve/entries/app.js +10 -0
- package/dist/serve/entries/app.js.map +1 -0
- package/dist/serve/entries/auth-helper-core.d.ts +52 -0
- package/dist/serve/entries/auth-helper-core.d.ts.map +1 -0
- package/dist/serve/entries/auth-helper-core.js +118 -0
- package/dist/serve/entries/auth-helper-core.js.map +1 -0
- package/dist/serve/entries/auth-helper-dom.d.ts +14 -0
- package/dist/serve/entries/auth-helper-dom.d.ts.map +1 -0
- package/dist/serve/entries/auth-helper-dom.js +116 -0
- package/dist/serve/entries/auth-helper-dom.js.map +1 -0
- package/dist/serve/entries/auth-helper-runtime.d.ts +5 -0
- package/dist/serve/entries/auth-helper-runtime.d.ts.map +1 -0
- package/dist/serve/entries/auth-helper-runtime.js +11 -0
- package/dist/serve/entries/auth-helper-runtime.js.map +1 -0
- package/dist/serve/entries/auth.d.ts +77 -0
- package/dist/serve/entries/auth.d.ts.map +1 -0
- package/dist/serve/entries/auth.js +201 -0
- package/dist/serve/entries/auth.js.map +1 -0
- package/dist/serve/entries/bridge-url.d.ts +25 -0
- package/dist/serve/entries/bridge-url.d.ts.map +1 -0
- package/dist/serve/entries/bridge-url.js +30 -0
- package/dist/serve/entries/bridge-url.js.map +1 -0
- package/dist/serve/entries/database.d.ts +46 -0
- package/dist/serve/entries/database.d.ts.map +1 -0
- package/dist/serve/entries/database.js +80 -0
- package/dist/serve/entries/database.js.map +1 -0
- package/dist/serve/entries/firestore.d.ts +104 -0
- package/dist/serve/entries/firestore.d.ts.map +1 -0
- package/dist/serve/entries/firestore.js +202 -0
- package/dist/serve/entries/firestore.js.map +1 -0
- package/dist/serve/entries/init.d.ts +2 -0
- package/dist/serve/entries/init.d.ts.map +1 -0
- package/dist/serve/entries/init.js +40 -0
- package/dist/serve/entries/init.js.map +1 -0
- package/dist/serve/entries/keepalive.d.ts +20 -0
- package/dist/serve/entries/keepalive.d.ts.map +1 -0
- package/dist/serve/entries/keepalive.js +38 -0
- package/dist/serve/entries/keepalive.js.map +1 -0
- package/dist/serve/entries/messaging-sw.d.ts +10 -0
- package/dist/serve/entries/messaging-sw.d.ts.map +1 -0
- package/dist/serve/entries/messaging-sw.js +36 -0
- package/dist/serve/entries/messaging-sw.js.map +1 -0
- package/dist/serve/entries/messaging.d.ts +11 -0
- package/dist/serve/entries/messaging.d.ts.map +1 -0
- package/dist/serve/entries/messaging.js +53 -0
- package/dist/serve/entries/messaging.js.map +1 -0
- package/dist/serve/entries/runtime.d.ts +46 -0
- package/dist/serve/entries/runtime.d.ts.map +1 -0
- package/dist/serve/entries/runtime.js +435 -0
- package/dist/serve/entries/runtime.js.map +1 -0
- package/dist/serve/entries/session-store.d.ts +48 -0
- package/dist/serve/entries/session-store.d.ts.map +1 -0
- package/dist/serve/entries/session-store.js +82 -0
- package/dist/serve/entries/session-store.js.map +1 -0
- package/dist/serve/entries/storage.d.ts +25 -0
- package/dist/serve/entries/storage.d.ts.map +1 -0
- package/dist/serve/entries/storage.js +61 -0
- package/dist/serve/entries/storage.js.map +1 -0
- package/dist/serve/entries/tab-sync-wiring.d.ts +88 -0
- package/dist/serve/entries/tab-sync-wiring.d.ts.map +1 -0
- package/dist/serve/entries/tab-sync-wiring.js +217 -0
- package/dist/serve/entries/tab-sync-wiring.js.map +1 -0
- package/dist/serve/entries/worker-runtime.d.ts +10 -0
- package/dist/serve/entries/worker-runtime.d.ts.map +1 -0
- package/dist/serve/entries/worker-runtime.js +59 -0
- package/dist/serve/entries/worker-runtime.js.map +1 -0
- package/dist/serve/init-payload.d.ts +21 -0
- package/dist/serve/init-payload.d.ts.map +1 -0
- package/dist/serve/init-payload.js +2 -0
- package/dist/serve/init-payload.js.map +1 -0
- package/dist/serve/namespace.d.ts +73 -0
- package/dist/serve/namespace.d.ts.map +1 -0
- package/dist/serve/namespace.js +470 -0
- package/dist/serve/namespace.js.map +1 -0
- package/dist/serve/open-browser.d.ts +23 -0
- package/dist/serve/open-browser.d.ts.map +1 -0
- package/dist/serve/open-browser.js +58 -0
- package/dist/serve/open-browser.js.map +1 -0
- package/dist/serve/rules.d.ts +77 -0
- package/dist/serve/rules.d.ts.map +1 -0
- package/dist/serve/rules.js +202 -0
- package/dist/serve/rules.js.map +1 -0
- package/dist/serve/sandbox-marker.d.ts +9 -0
- package/dist/serve/sandbox-marker.d.ts.map +1 -0
- package/dist/serve/sandbox-marker.js +31 -0
- package/dist/serve/sandbox-marker.js.map +1 -0
- package/dist/serve/server.d.ts +135 -0
- package/dist/serve/server.d.ts.map +1 -0
- package/dist/serve/server.js +328 -0
- package/dist/serve/server.js.map +1 -0
- package/dist/serve/standalone-assets.d.ts +67 -0
- package/dist/serve/standalone-assets.d.ts.map +1 -0
- package/dist/serve/standalone-assets.js +134 -0
- package/dist/serve/standalone-assets.js.map +1 -0
- package/dist/serve/state-store.d.ts +45 -0
- package/dist/serve/state-store.d.ts.map +1 -0
- package/dist/serve/state-store.js +120 -0
- package/dist/serve/state-store.js.map +1 -0
- package/dist/serve/studio/disk-project-store.d.ts +9 -0
- package/dist/serve/studio/disk-project-store.d.ts.map +1 -0
- package/dist/serve/studio/disk-project-store.js +173 -0
- package/dist/serve/studio/disk-project-store.js.map +1 -0
- package/dist/serve/studio/disk-workspace.d.ts +14 -0
- package/dist/serve/studio/disk-workspace.d.ts.map +1 -0
- package/dist/serve/studio/disk-workspace.js +152 -0
- package/dist/serve/studio/disk-workspace.js.map +1 -0
- package/dist/serve/studio/index.d.ts +10 -0
- package/dist/serve/studio/index.d.ts.map +1 -0
- package/dist/serve/studio/index.js +9 -0
- package/dist/serve/studio/index.js.map +1 -0
- package/dist/serve/studio/routes.d.ts +40 -0
- package/dist/serve/studio/routes.d.ts.map +1 -0
- package/dist/serve/studio/routes.js +182 -0
- package/dist/serve/studio/routes.js.map +1 -0
- package/dist/serve/studio/store-types.d.ts +45 -0
- package/dist/serve/studio/store-types.d.ts.map +1 -0
- package/dist/serve/studio/store-types.js +11 -0
- package/dist/serve/studio/store-types.js.map +1 -0
- package/dist/serve/studio-ui/assets/RulesCodeEditor-BZpD57II.js +23 -0
- package/dist/serve/studio-ui/assets/index-Bsa-TQNK.css +1 -0
- package/dist/serve/studio-ui/assets/index-DGaVuOhE.js +1211 -0
- package/dist/serve/studio-ui/assets/seed-CTmn6YuO.js +2 -0
- package/dist/serve/studio-ui/index.html +32 -0
- package/dist/serve/studio-ui/pyric-logo.svg +76 -0
- package/dist/serve/vite-plugin.d.ts +57 -0
- package/dist/serve/vite-plugin.d.ts.map +1 -0
- package/dist/serve/vite-plugin.js +658 -0
- package/dist/serve/vite-plugin.js.map +1 -0
- package/dist/serve/worker/client/admin-firestore.d.ts +18 -0
- package/dist/serve/worker/client/admin-firestore.d.ts.map +1 -0
- package/dist/serve/worker/client/admin-firestore.js +26 -0
- package/dist/serve/worker/client/admin-firestore.js.map +1 -0
- package/dist/serve/worker/client/ai.d.ts +31 -0
- package/dist/serve/worker/client/ai.d.ts.map +1 -0
- package/dist/serve/worker/client/ai.js +89 -0
- package/dist/serve/worker/client/ai.js.map +1 -0
- package/dist/serve/worker/client/auth.d.ts +168 -0
- package/dist/serve/worker/client/auth.d.ts.map +1 -0
- package/dist/serve/worker/client/auth.js +322 -0
- package/dist/serve/worker/client/auth.js.map +1 -0
- package/dist/serve/worker/client/connection.d.ts +80 -0
- package/dist/serve/worker/client/connection.d.ts.map +1 -0
- package/dist/serve/worker/client/connection.js +148 -0
- package/dist/serve/worker/client/connection.js.map +1 -0
- package/dist/serve/worker/client/core.d.ts +109 -0
- package/dist/serve/worker/client/core.d.ts.map +1 -0
- package/dist/serve/worker/client/core.js +248 -0
- package/dist/serve/worker/client/core.js.map +1 -0
- package/dist/serve/worker/client/disconnect.d.ts +7 -0
- package/dist/serve/worker/client/disconnect.d.ts.map +1 -0
- package/dist/serve/worker/client/disconnect.js +26 -0
- package/dist/serve/worker/client/disconnect.js.map +1 -0
- package/dist/serve/worker/client/firestore-reads.d.ts +49 -0
- package/dist/serve/worker/client/firestore-reads.d.ts.map +1 -0
- package/dist/serve/worker/client/firestore-reads.js +139 -0
- package/dist/serve/worker/client/firestore-reads.js.map +1 -0
- package/dist/serve/worker/client/firestore-refs.d.ts +54 -0
- package/dist/serve/worker/client/firestore-refs.d.ts.map +1 -0
- package/dist/serve/worker/client/firestore-refs.js +167 -0
- package/dist/serve/worker/client/firestore-refs.js.map +1 -0
- package/dist/serve/worker/client/firestore-writes.d.ts +70 -0
- package/dist/serve/worker/client/firestore-writes.d.ts.map +1 -0
- package/dist/serve/worker/client/firestore-writes.js +169 -0
- package/dist/serve/worker/client/firestore-writes.js.map +1 -0
- package/dist/serve/worker/client/handles.d.ts +73 -0
- package/dist/serve/worker/client/handles.d.ts.map +1 -0
- package/dist/serve/worker/client/handles.js +4 -0
- package/dist/serve/worker/client/handles.js.map +1 -0
- package/dist/serve/worker/client/messaging.d.ts +16 -0
- package/dist/serve/worker/client/messaging.d.ts.map +1 -0
- package/dist/serve/worker/client/messaging.js +60 -0
- package/dist/serve/worker/client/messaging.js.map +1 -0
- package/dist/serve/worker/client/presence.d.ts +43 -0
- package/dist/serve/worker/client/presence.d.ts.map +1 -0
- package/dist/serve/worker/client/presence.js +132 -0
- package/dist/serve/worker/client/presence.js.map +1 -0
- package/dist/serve/worker/client/rtdb.d.ts +36 -0
- package/dist/serve/worker/client/rtdb.d.ts.map +1 -0
- package/dist/serve/worker/client/rtdb.js +241 -0
- package/dist/serve/worker/client/rtdb.js.map +1 -0
- package/dist/serve/worker/client/rules.d.ts +24 -0
- package/dist/serve/worker/client/rules.d.ts.map +1 -0
- package/dist/serve/worker/client/rules.js +44 -0
- package/dist/serve/worker/client/rules.js.map +1 -0
- package/dist/serve/worker/client/service-worker-connection.d.ts +3 -0
- package/dist/serve/worker/client/service-worker-connection.d.ts.map +1 -0
- package/dist/serve/worker/client/service-worker-connection.js +53 -0
- package/dist/serve/worker/client/service-worker-connection.js.map +1 -0
- package/dist/serve/worker/client/snapshots.d.ts +32 -0
- package/dist/serve/worker/client/snapshots.d.ts.map +1 -0
- package/dist/serve/worker/client/snapshots.js +46 -0
- package/dist/serve/worker/client/snapshots.js.map +1 -0
- package/dist/serve/worker/client/storage.d.ts +64 -0
- package/dist/serve/worker/client/storage.d.ts.map +1 -0
- package/dist/serve/worker/client/storage.js +125 -0
- package/dist/serve/worker/client/storage.js.map +1 -0
- package/dist/serve/worker/client/studio.d.ts +32 -0
- package/dist/serve/worker/client/studio.d.ts.map +1 -0
- package/dist/serve/worker/client/studio.js +61 -0
- package/dist/serve/worker/client/studio.js.map +1 -0
- package/dist/serve/worker/client.d.ts +43 -0
- package/dist/serve/worker/client.d.ts.map +1 -0
- package/dist/serve/worker/client.js +44 -0
- package/dist/serve/worker/client.js.map +1 -0
- package/dist/serve/worker/entry.d.ts +40 -0
- package/dist/serve/worker/entry.d.ts.map +1 -0
- package/dist/serve/worker/entry.js +144 -0
- package/dist/serve/worker/entry.js.map +1 -0
- package/dist/serve/worker/host/admin-firestore.d.ts +17 -0
- package/dist/serve/worker/host/admin-firestore.d.ts.map +1 -0
- package/dist/serve/worker/host/admin-firestore.js +92 -0
- package/dist/serve/worker/host/admin-firestore.js.map +1 -0
- package/dist/serve/worker/host/connection.d.ts +40 -0
- package/dist/serve/worker/host/connection.d.ts.map +1 -0
- package/dist/serve/worker/host/connection.js +153 -0
- package/dist/serve/worker/host/connection.js.map +1 -0
- package/dist/serve/worker/host/core.d.ts +159 -0
- package/dist/serve/worker/host/core.d.ts.map +1 -0
- package/dist/serve/worker/host/core.js +296 -0
- package/dist/serve/worker/host/core.js.map +1 -0
- package/dist/serve/worker/host/dispatch.d.ts +34 -0
- package/dist/serve/worker/host/dispatch.d.ts.map +1 -0
- package/dist/serve/worker/host/dispatch.js +267 -0
- package/dist/serve/worker/host/dispatch.js.map +1 -0
- package/dist/serve/worker/host/firestore-reads.d.ts +17 -0
- package/dist/serve/worker/host/firestore-reads.d.ts.map +1 -0
- package/dist/serve/worker/host/firestore-reads.js +108 -0
- package/dist/serve/worker/host/firestore-reads.js.map +1 -0
- package/dist/serve/worker/host/firestore-writes.d.ts +37 -0
- package/dist/serve/worker/host/firestore-writes.d.ts.map +1 -0
- package/dist/serve/worker/host/firestore-writes.js +409 -0
- package/dist/serve/worker/host/firestore-writes.js.map +1 -0
- package/dist/serve/worker/host/presence.d.ts +38 -0
- package/dist/serve/worker/host/presence.d.ts.map +1 -0
- package/dist/serve/worker/host/presence.js +280 -0
- package/dist/serve/worker/host/presence.js.map +1 -0
- package/dist/serve/worker/host/rtdb.d.ts +18 -0
- package/dist/serve/worker/host/rtdb.d.ts.map +1 -0
- package/dist/serve/worker/host/rtdb.js +128 -0
- package/dist/serve/worker/host/rtdb.js.map +1 -0
- package/dist/serve/worker/host/rules.d.ts +17 -0
- package/dist/serve/worker/host/rules.d.ts.map +1 -0
- package/dist/serve/worker/host/rules.js +118 -0
- package/dist/serve/worker/host/rules.js.map +1 -0
- package/dist/serve/worker/host/storage.d.ts +19 -0
- package/dist/serve/worker/host/storage.d.ts.map +1 -0
- package/dist/serve/worker/host/storage.js +260 -0
- package/dist/serve/worker/host/storage.js.map +1 -0
- package/dist/serve/worker/host/studio.d.ts +13 -0
- package/dist/serve/worker/host/studio.d.ts.map +1 -0
- package/dist/serve/worker/host/studio.js +30 -0
- package/dist/serve/worker/host/studio.js.map +1 -0
- package/dist/serve/worker/host/subscriptions.d.ts +21 -0
- package/dist/serve/worker/host/subscriptions.d.ts.map +1 -0
- package/dist/serve/worker/host/subscriptions.js +162 -0
- package/dist/serve/worker/host/subscriptions.js.map +1 -0
- package/dist/serve/worker/host-ai.d.ts +59 -0
- package/dist/serve/worker/host-ai.d.ts.map +1 -0
- package/dist/serve/worker/host-ai.js +158 -0
- package/dist/serve/worker/host-ai.js.map +1 -0
- package/dist/serve/worker/host-auth.d.ts +47 -0
- package/dist/serve/worker/host-auth.d.ts.map +1 -0
- package/dist/serve/worker/host-auth.js +464 -0
- package/dist/serve/worker/host-auth.js.map +1 -0
- package/dist/serve/worker/host-context.d.ts +220 -0
- package/dist/serve/worker/host-context.d.ts.map +1 -0
- package/dist/serve/worker/host-context.js +45 -0
- package/dist/serve/worker/host-context.js.map +1 -0
- package/dist/serve/worker/host-events.d.ts +21 -0
- package/dist/serve/worker/host-events.d.ts.map +1 -0
- package/dist/serve/worker/host-events.js +87 -0
- package/dist/serve/worker/host-events.js.map +1 -0
- package/dist/serve/worker/host-messaging.d.ts +60 -0
- package/dist/serve/worker/host-messaging.d.ts.map +1 -0
- package/dist/serve/worker/host-messaging.js +226 -0
- package/dist/serve/worker/host-messaging.js.map +1 -0
- package/dist/serve/worker/host.d.ts +36 -0
- package/dist/serve/worker/host.d.ts.map +1 -0
- package/dist/serve/worker/host.js +39 -0
- package/dist/serve/worker/host.js.map +1 -0
- package/dist/serve/worker/index.d.ts +22 -0
- package/dist/serve/worker/index.d.ts.map +1 -0
- package/dist/serve/worker/index.js +61 -0
- package/dist/serve/worker/index.js.map +1 -0
- package/dist/serve/worker/presence-timing.d.ts +14 -0
- package/dist/serve/worker/presence-timing.d.ts.map +1 -0
- package/dist/serve/worker/presence-timing.js +14 -0
- package/dist/serve/worker/presence-timing.js.map +1 -0
- package/dist/serve/worker/protocol.d.ts +1150 -0
- package/dist/serve/worker/protocol.d.ts.map +1 -0
- package/dist/serve/worker/protocol.js +228 -0
- package/dist/serve/worker/protocol.js.map +1 -0
- package/dist/serve/worker/serve-init.d.ts +201 -0
- package/dist/serve/worker/serve-init.d.ts.map +1 -0
- package/dist/serve/worker/serve-init.js +579 -0
- package/dist/serve/worker/serve-init.js.map +1 -0
- package/dist/serve/worker/service-worker-channel.d.ts +23 -0
- package/dist/serve/worker/service-worker-channel.d.ts.map +1 -0
- package/dist/serve/worker/service-worker-channel.js +9 -0
- package/dist/serve/worker/service-worker-channel.js.map +1 -0
- package/dist/serve/worker/service-worker-relay.d.ts +22 -0
- package/dist/serve/worker/service-worker-relay.d.ts.map +1 -0
- package/dist/serve/worker/service-worker-relay.js +63 -0
- package/dist/serve/worker/service-worker-relay.js.map +1 -0
- package/dist/serve/writer-lock.d.ts +32 -0
- package/dist/serve/writer-lock.d.ts.map +1 -0
- package/dist/serve/writer-lock.js +43 -0
- package/dist/serve/writer-lock.js.map +1 -0
- package/dist/verify/cases.d.ts +37 -0
- package/dist/verify/cases.d.ts.map +1 -0
- package/dist/verify/cases.js +173 -0
- package/dist/verify/cases.js.map +1 -0
- package/dist/verify/fixture.d.ts +100 -0
- package/dist/verify/fixture.d.ts.map +1 -0
- package/dist/verify/fixture.js +156 -0
- package/dist/verify/fixture.js.map +1 -0
- package/dist/verify/index.d.ts +102 -0
- package/dist/verify/index.d.ts.map +1 -0
- package/dist/verify/index.js +318 -0
- package/dist/verify/index.js.map +1 -0
- package/dist/verify/tools.d.ts +7 -0
- package/dist/verify/tools.d.ts.map +1 -0
- package/dist/verify/tools.js +83 -0
- package/dist/verify/tools.js.map +1 -0
- package/dist/version/compat-target.d.ts +18 -0
- package/dist/version/compat-target.d.ts.map +1 -0
- package/dist/version/compat-target.js +18 -0
- package/dist/version/compat-target.js.map +1 -0
- package/dist/vite.d.ts +12 -0
- package/dist/vite.d.ts.map +1 -0
- package/dist/vite.js +16 -0
- package/dist/vite.js.map +1 -0
- package/package.json +133 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
|
|
2
|
+
# Run Firebase Authentication locally
|
|
3
|
+
|
|
4
|
+
Keep using the Firebase Authentication Web API:
|
|
5
|
+
|
|
6
|
+
```ts
|
|
7
|
+
import { getAuth, signInAnonymously } from 'firebase/auth';
|
|
8
|
+
|
|
9
|
+
const auth = getAuth(app);
|
|
10
|
+
await signInAnonymously(auth);
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
During development, this creates and signs into a local identity. A production build runs the same call through Firebase. Use the [Firebase Authentication documentation](https://firebase.google.com/docs/auth/web/start) for normal sign-in, account, provider, and observer APIs.
|
|
14
|
+
|
|
15
|
+
## What changes locally
|
|
16
|
+
|
|
17
|
+
The sandbox owns the user database and active sessions. No identity is created in a Firebase project. Auth state remains available to Firestore, Realtime Database, and Storage Security Rules through the same Firebase-shaped user and token fields used by the application.
|
|
18
|
+
|
|
19
|
+
Popup and redirect providers do not contact Google, GitHub, or another identity provider. Pyric presents a local identity picker so provider-dependent application paths can run without OAuth configuration or external accounts.
|
|
20
|
+
|
|
21
|
+
Pyric Studio shows the local users and current authentication state. It can create, edit, select, and remove test identities without adding those controls to application code.
|
|
22
|
+
|
|
23
|
+
## Seed identities for tests
|
|
24
|
+
|
|
25
|
+
Sandbox-only identity controls belong in test or setup code, never in the application path that ships:
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
import { initializeSandbox } from 'pyric/sandbox';
|
|
29
|
+
import { getAuth, sandbox as authSandbox } from 'pyric/auth';
|
|
30
|
+
|
|
31
|
+
const sandbox = initializeSandbox();
|
|
32
|
+
const auth = getAuth(sandbox);
|
|
33
|
+
|
|
34
|
+
authSandbox.seedUsers(auth, [
|
|
35
|
+
{
|
|
36
|
+
uid: 'alice',
|
|
37
|
+
email: 'alice@example.com',
|
|
38
|
+
password: 'local-only',
|
|
39
|
+
customClaims: { role: 'editor' },
|
|
40
|
+
},
|
|
41
|
+
]);
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Those claims reach `request.auth.token` when local Security Rules evaluate an operation.
|
|
45
|
+
|
|
46
|
+
## Check the supported boundary
|
|
47
|
+
|
|
48
|
+
Authentication is not a complete reimplementation of every Firebase Auth feature. Read the generated [Auth conformance matrix](../pyric-auth-compat/) for the current public surface, verified behavior, documented differences, unsupported APIs, and unverified rows.
|
|
49
|
+
|
|
50
|
+
Continue with [Store and query data](../store-and-query-data/) or [inspect a local operation](../see-whats-happening/).
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
<!DOCTYPE html><html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Simulate and lint Security Rules before deployment · Pyric Studio</title><meta name="description" content="Get a rules verdict and a lint report locally, before production answers with an unexplained 400 or 403."><link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500;700&display=swap" rel="stylesheet"><link rel="stylesheet" href="/__pyric/ui/_astro/_slug_.CQYSemvw.css"></head> <body> <header class="studio__bar"> <div class="studio__bar-inner"> <a class="studio__brand" href="/__pyric/ui/" aria-label="Pyric Studio">Pyric</a> <nav class="studio__nav" aria-label="Studio tabs"> <a class="studio__nav-tab" href="/__pyric/ui/"> Home </a><a class="studio__nav-tab" href="/__pyric/ui/firestore"> Firestore </a><a class="studio__nav-tab" href="/__pyric/ui/auth"> Auth </a><a class="studio__nav-tab" href="/__pyric/ui/rtdb"> RTDB </a><a class="studio__nav-tab" href="/__pyric/ui/storage"> Storage </a><a class="studio__nav-tab" href="/__pyric/ui/traffic"> Traffic </a><a class="studio__nav-tab" href="/__pyric/ui/settings"> Settings </a><a class="studio__nav-tab" href="/__pyric/ui/docs" aria-current="page"> Docs </a> </nav> </div> </header> <div class="docs-shell"> <details class="docs-nav-drawer"> <summary>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> <a class="docs-nav-toplink" href="/__pyric/ui/docs/overview/"> Overview </a><details class="docs-nav-group"> <summary>Run locally</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/start-building/"> Quickstart </a> </li><li> <a href="/__pyric/ui/docs/how-the-swap-works/"> How the swap works </a> </li><li> <a href="/__pyric/ui/docs/set-up-your-agent/"> Connect an agent </a> </li><li> <a href="/__pyric/ui/docs/test-in-node/"> Test in Node </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Develop with Firebase APIs</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/sign-in-and-manage-users/"> Sign in and manage users </a> </li><li> <a href="/__pyric/ui/docs/store-and-query-data/"> Store and query data </a> </li><li> <a href="/__pyric/ui/docs/sync-realtime-data/"> Sync realtime data </a> </li><li> <a href="/__pyric/ui/docs/store-files/"> Store files </a> </li><li> <a href="/__pyric/ui/docs/receive-messages/"> Receive messages </a> </li><li> <a href="/__pyric/ui/docs/run-ai-logic-locally/"> Run AI Logic locally </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-how-to-run-rtdb-onvaluecreated/"> Run an RTDB function locally </a> </li><li> <a href="/__pyric/ui/docs/which-data-service/"> Which data service? </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" open> <summary>Inspect and correct</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <h2 class="docs-nav-heading"> Inspect the sandbox </h2> <ul> <li> <a href="/__pyric/ui/docs/see-whats-happening/"> Traffic & rule verdicts </a> </li><li> <a href="/__pyric/ui/docs/read-a-denial/"> Read a denial and understand it </a> </li><li> <a href="/__pyric/ui/docs/shape-your-data/"> Seed, snapshot, replay </a> </li><li> <a href="/__pyric/ui/docs/watch-and-review/"> Review agent activity </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading"> Correct Security Rules </h2> <ul> <li> <a href="/__pyric/ui/docs/secure-it-with-rules/"> Security Rules </a> </li><li> <a href="/__pyric/ui/docs/simulate-and-lint/" aria-current="page"> Simulate and lint before you deploy </a> </li><li> <a href="/__pyric/ui/docs/rules-patterns/"> Rules patterns </a> </li><li> <a href="/__pyric/ui/docs/rules-standard-library/"> The rules standard library </a> </li><li> <a href="/__pyric/ui/docs/rtdb-rules-in-typescript/"> RTDB rules in TypeScript </a> </li><li> <a href="/__pyric/ui/docs/firestore-rules-limits/"> Rules limits </a> </li><li> <a href="/__pyric/ui/docs/whats-possible/"> Case studies </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading"> Work with an agent </h2> <ul> <li> <a href="/__pyric/ui/docs/what-your-agent-can-do/"> Work through an agent </a> </li><li> <a href="/__pyric/ui/docs/skills/"> Agent skills </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Verify the boundary</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/pyric-cli-how-to-verify-against-a-captured-session/"> Verify a captured session </a> </li><li> <a href="/__pyric/ui/docs/write-a-rules-test-suite/"> Write a rules test suite </a> </li><li> <a href="/__pyric/ui/docs/audit-your-rules/"> Audit rules and data </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Ship unchanged</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/ship-to-production/"> Ship to production </a> </li><li> <a href="/__pyric/ui/docs/set-up-the-project/"> Set up the Firebase project </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Conformance</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/how-we-know-it-matches-firebase/"> Conformance </a> </li><li> <a href="/__pyric/ui/docs/whats-experimental/"> What's experimental </a> </li><li> <a href="/__pyric/ui/docs/pyric-conformance-scores/"> Conformance scores </a> </li><li> <a href="/__pyric/ui/docs/pyric-app-compat/"> App </a> </li><li> <a href="/__pyric/ui/docs/pyric-firestore-compat/"> Firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-auth-compat/"> Auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-database-compat/"> Realtime Database </a> </li><li> <a href="/__pyric/ui/docs/pyric-storage-compat/"> Storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-rules-compat/"> Rules </a> </li><li> <a href="/__pyric/ui/docs/pyric-messaging-compat/"> Messaging </a> </li><li> <a href="/__pyric/ui/docs/pyric-ai-compat/"> AI Logic </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-functions-rtdb-compat/"> Functions · RTDB </a> </li> </ul> </div> </div> </details> <details class="docs-nav-group"> <summary>Reference</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/pyric-cli/"> @pyric/cli </a> </li><li> <a href="/__pyric/ui/docs/pyric-explanation-versioning-and-compatibility/"> pyric </a> </li><li> <a href="/__pyric/ui/docs/pyric-firestore/"> pyric / firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-rules/"> pyric / rules </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox/"> pyric / sandbox </a> </li><li> <a href="/__pyric/ui/docs/pyric-storage/"> pyric / storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-auth/"> pyric / auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-database/"> pyric / database </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-app/"> pyric-admin / app </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-firestore/"> pyric-admin / firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-auth/"> pyric-admin / auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-database/"> pyric-admin / database </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-storage/"> pyric-admin / storage </a> </li><li> <a href="/__pyric/ui/docs/ui/"> @pyric/ui </a> </li><li> <a href="/__pyric/ui/docs/api-reference/"> API reference </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> <a class="docs-nav-toplink" href="/__pyric/ui/docs/overview/" id="nav-group-overview"> Overview </a><details class="docs-nav-group" id="nav-group-run-locally"> <summary>Run locally</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/start-building/"> Quickstart </a> </li><li> <a href="/__pyric/ui/docs/how-the-swap-works/"> How the swap works </a> </li><li> <a href="/__pyric/ui/docs/set-up-your-agent/"> Connect an agent </a> </li><li> <a href="/__pyric/ui/docs/test-in-node/"> Test in Node </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-develop-with-firebase-apis"> <summary>Develop with Firebase APIs</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/sign-in-and-manage-users/"> Sign in and manage users </a> </li><li> <a href="/__pyric/ui/docs/store-and-query-data/"> Store and query data </a> </li><li> <a href="/__pyric/ui/docs/sync-realtime-data/"> Sync realtime data </a> </li><li> <a href="/__pyric/ui/docs/store-files/"> Store files </a> </li><li> <a href="/__pyric/ui/docs/receive-messages/"> Receive messages </a> </li><li> <a href="/__pyric/ui/docs/run-ai-logic-locally/"> Run AI Logic locally </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-how-to-run-rtdb-onvaluecreated/"> Run an RTDB function locally </a> </li><li> <a href="/__pyric/ui/docs/which-data-service/"> Which data service? </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-inspect-and-correct" open> <summary>Inspect and correct</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <h2 class="docs-nav-heading" id="nav-section-inspect-and-correct-inspect-the-sandbox"> Inspect the sandbox </h2> <ul> <li> <a href="/__pyric/ui/docs/see-whats-happening/"> Traffic & rule verdicts </a> </li><li> <a href="/__pyric/ui/docs/read-a-denial/"> Read a denial and understand it </a> </li><li> <a href="/__pyric/ui/docs/shape-your-data/"> Seed, snapshot, replay </a> </li><li> <a href="/__pyric/ui/docs/watch-and-review/"> Review agent activity </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading" id="nav-section-inspect-and-correct-correct-security-rules"> Correct Security Rules </h2> <ul> <li> <a href="/__pyric/ui/docs/secure-it-with-rules/"> Security Rules </a> </li><li> <a href="/__pyric/ui/docs/simulate-and-lint/" aria-current="page"> Simulate and lint before you deploy </a> </li><li> <a href="/__pyric/ui/docs/rules-patterns/"> Rules patterns </a> </li><li> <a href="/__pyric/ui/docs/rules-standard-library/"> The rules standard library </a> </li><li> <a href="/__pyric/ui/docs/rtdb-rules-in-typescript/"> RTDB rules in TypeScript </a> </li><li> <a href="/__pyric/ui/docs/firestore-rules-limits/"> Rules limits </a> </li><li> <a href="/__pyric/ui/docs/whats-possible/"> Case studies </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading" id="nav-section-inspect-and-correct-work-with-an-agent"> Work with an agent </h2> <ul> <li> <a href="/__pyric/ui/docs/what-your-agent-can-do/"> Work through an agent </a> </li><li> <a href="/__pyric/ui/docs/skills/"> Agent skills </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-verify-the-boundary"> <summary>Verify the boundary</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/pyric-cli-how-to-verify-against-a-captured-session/"> Verify a captured session </a> </li><li> <a href="/__pyric/ui/docs/write-a-rules-test-suite/"> Write a rules test suite </a> </li><li> <a href="/__pyric/ui/docs/audit-your-rules/"> Audit rules and data </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-ship-unchanged"> <summary>Ship unchanged</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/ship-to-production/"> Ship to production </a> </li><li> <a href="/__pyric/ui/docs/set-up-the-project/"> Set up the Firebase project </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-conformance"> <summary>Conformance</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/how-we-know-it-matches-firebase/"> Conformance </a> </li><li> <a href="/__pyric/ui/docs/whats-experimental/"> What's experimental </a> </li><li> <a href="/__pyric/ui/docs/pyric-conformance-scores/"> Conformance scores </a> </li><li> <a href="/__pyric/ui/docs/pyric-app-compat/"> App </a> </li><li> <a href="/__pyric/ui/docs/pyric-firestore-compat/"> Firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-auth-compat/"> Auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-database-compat/"> Realtime Database </a> </li><li> <a href="/__pyric/ui/docs/pyric-storage-compat/"> Storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-rules-compat/"> Rules </a> </li><li> <a href="/__pyric/ui/docs/pyric-messaging-compat/"> Messaging </a> </li><li> <a href="/__pyric/ui/docs/pyric-ai-compat/"> AI Logic </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-functions-rtdb-compat/"> Functions · RTDB </a> </li> </ul> </div> </div> </details> <details class="docs-nav-group" id="nav-group-reference"> <summary>Reference</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/pyric-cli/"> @pyric/cli </a> </li><li> <a href="/__pyric/ui/docs/pyric-explanation-versioning-and-compatibility/"> pyric </a> </li><li> <a href="/__pyric/ui/docs/pyric-firestore/"> pyric / firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-rules/"> pyric / rules </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox/"> pyric / sandbox </a> </li><li> <a href="/__pyric/ui/docs/pyric-storage/"> pyric / storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-auth/"> pyric / auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-database/"> pyric / database </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-app/"> pyric-admin / app </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-firestore/"> pyric-admin / firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-auth/"> pyric-admin / auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-database/"> pyric-admin / database </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-storage/"> pyric-admin / storage </a> </li><li> <a href="/__pyric/ui/docs/ui/"> @pyric/ui </a> </li><li> <a href="/__pyric/ui/docs/api-reference/"> API reference </a> </li> </ul> </div> </div> </details> </nav> <main class="doc-main"> <nav class="docs-breadcrumbs" aria-label="Breadcrumb"> <ol> <li> <a href="#nav-group-inspect-and-correct">Inspect and correct</a> </li><li> <span class="docs-breadcrumbs-sep" aria-hidden="true">/</span> <a href="#nav-section-inspect-and-correct-correct-security-rules">Correct Security Rules</a> </li><li> <span class="docs-breadcrumbs-sep" aria-hidden="true">/</span> <span aria-current="page">Simulate and lint before you deploy</span> </li> </ol> </nav> <article class="prose"> <h1 id="simulate-and-lint-security-rules-before-deployment">Simulate and lint Security Rules before deployment</h1>
|
|
2
|
+
<p>A broken ruleset fails late: a <code>400</code> at deploy time, or a <code>403</code> at runtime. Pyric moves both failures to your machine, before the deploy.</p>
|
|
3
|
+
<p>Simulation tells you what a rule decides. Linting tells you what the production compiler and runtime will reject, and why, in the language of the mistake you made.</p>
|
|
4
|
+
<h2 id="simulate-a-hypothetical-request">Simulate a hypothetical request</h2>
|
|
5
|
+
<p>Ask the simulator whether a specific request would be allowed. It runs in-process, no network, no project:</p>
|
|
6
|
+
<pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">import</span><span style="color:#ABB2BF"> { </span><span style="color:#E06C75">SimulateFirestoreRulesHandler</span><span style="color:#ABB2BF"> } </span><span style="color:#C678DD">from</span><span style="color:#98C379"> 'pyric/rules'</span><span style="color:#ABB2BF">;</span></span>
|
|
7
|
+
<span class="line"></span>
|
|
8
|
+
<span class="line"><span style="color:#C678DD">const</span><span style="color:#E5C07B"> sim</span><span style="color:#56B6C2"> =</span><span style="color:#C678DD"> new</span><span style="color:#61AFEF"> SimulateFirestoreRulesHandler</span><span style="color:#ABB2BF">();</span></span>
|
|
9
|
+
<span class="line"><span style="color:#C678DD">const</span><span style="color:#E5C07B"> result</span><span style="color:#56B6C2"> =</span><span style="color:#E5C07B"> sim</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">simulate</span><span style="color:#ABB2BF">(</span><span style="color:#E06C75">source</span><span style="color:#ABB2BF">, [</span></span>
|
|
10
|
+
<span class="line"><span style="color:#ABB2BF"> {</span></span>
|
|
11
|
+
<span class="line"><span style="color:#E06C75"> description</span><span style="color:#ABB2BF">: </span><span style="color:#98C379">'unauthenticated read is denied'</span><span style="color:#ABB2BF">,</span></span>
|
|
12
|
+
<span class="line"><span style="color:#E06C75"> expectation</span><span style="color:#ABB2BF">: </span><span style="color:#98C379">'DENY'</span><span style="color:#ABB2BF">,</span></span>
|
|
13
|
+
<span class="line"><span style="color:#E06C75"> method</span><span style="color:#ABB2BF">: </span><span style="color:#98C379">'get'</span><span style="color:#ABB2BF">,</span></span>
|
|
14
|
+
<span class="line"><span style="color:#E06C75"> path</span><span style="color:#ABB2BF">: </span><span style="color:#98C379">'notes/n1'</span><span style="color:#ABB2BF">,</span></span>
|
|
15
|
+
<span class="line"><span style="color:#ABB2BF"> },</span></span>
|
|
16
|
+
<span class="line"><span style="color:#ABB2BF">]);</span></span></code></pre>
|
|
17
|
+
<p>Each result is <code>PASSED</code>, <code>FAILED</code>, or <code>UNSUPPORTED</code>, and each carries <code>debugMessages</code>, a trace naming the rule that decided:</p>
|
|
18
|
+
<pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="plaintext"><code><span class="line"><span>Rule #0 (read) → deny</span></span>
|
|
19
|
+
<span class="line"><span>Simulated: DENY</span></span></code></pre>
|
|
20
|
+
<p><code>UNSUPPORTED</code> means the simulator hit a feature it does not implement and abstained rather than guessed. Those cases can be routed to Google’s own engine. See <a href="../write-a-rules-test-suite/">write a rules test suite</a>.</p>
|
|
21
|
+
<p>The same simulator is on the command line as <code>pyric firestore rules simulate</code>, and it is what evaluates every operation inside your running sandbox.</p>
|
|
22
|
+
<h2 id="lint-before-firebase-rejects-the-rules">Lint before Firebase rejects the rules</h2>
|
|
23
|
+
<pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="bash"><code><span class="line"><span style="color:#61AFEF">pyric</span><span style="color:#98C379"> firestore</span><span style="color:#98C379"> rules</span><span style="color:#98C379"> lint</span><span style="color:#98C379"> firestore.rules</span></span></code></pre>
|
|
24
|
+
<p>Or in code:</p>
|
|
25
|
+
<pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">import</span><span style="color:#ABB2BF"> { </span><span style="color:#E06C75">lintFirestoreRules</span><span style="color:#ABB2BF"> } </span><span style="color:#C678DD">from</span><span style="color:#98C379"> 'pyric/rules'</span><span style="color:#ABB2BF">;</span></span>
|
|
26
|
+
<span class="line"></span>
|
|
27
|
+
<span class="line"><span style="color:#C678DD">const</span><span style="color:#ABB2BF"> { </span><span style="color:#E5C07B">warnings</span><span style="color:#ABB2BF">, </span><span style="color:#E5C07B">metrics</span><span style="color:#ABB2BF"> } </span><span style="color:#56B6C2">=</span><span style="color:#61AFEF"> lintFirestoreRules</span><span style="color:#ABB2BF">(</span><span style="color:#E06C75">source</span><span style="color:#ABB2BF">);</span></span></code></pre>
|
|
28
|
+
<p>The linter checks two different kinds of failure.</p>
|
|
29
|
+
<p><strong>The production limits.</strong> The rules compiler enforces hard caps: a 256 KB source ceiling, a boolean chain depth of 98, 11 <code>let</code> bindings per function, <code>get()</code> call counts, and a runtime evaluation budget that fails as a silent <code>permission-denied</code> under load. The linter carries each cap as an exact threshold, measured by probing the production engine. The numbers live in <a href="../firestore-rules-limits/">the measured Firestore Rules limits</a>.</p>
|
|
30
|
+
<p><strong>JS-in-rules mistakes.</strong> The rules language looks like JavaScript, and that resemblance is a trap. Models fall into it constantly, and humans do too.</p>
|
|
31
|
+
<p>Code like <code>resource.data.tags.includes('x')</code> parses fine and then fails at runtime as a bare <code>permission-denied</code>. The linter knows the specific ways this goes wrong and maps each one to the rules-language fix:</p>
|
|
32
|
+
<div class="table-scroll">
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
<table><thead><tr><th>You wrote</th><th>The rules language wants</th></tr></thead><tbody><tr><td><code>list.includes(x)</code></td><td><code>x in list</code></td></tr><tr><td><code>.toLowerCase()</code> / <code>.toUpperCase()</code></td><td><code>.lower()</code> / <code>.upper()</code></td></tr><tr><td><code>.filter(...)</code> / <code>.map(...)</code></td><td>nothing; lists are not transformable, restructure the logic</td></tr><tr><td><code>.length</code></td><td><code>.size()</code>, a method with parentheses</td></tr><tr><td><code>obj?.field</code></td><td><code>'field' in obj && obj.field</code></td></tr><tr><td><code>x => ...</code></td><td><code>function name() { return ...; }</code></td></tr><tr><td><code>a === b</code></td><td><code>a == b</code></td></tr><tr><td><code>Object.keys(data)</code></td><td><code>data.keys()</code></td></tr><tr><td><code>request.data</code></td><td><code>request.resource.data</code></td></tr><tr><td><code>undefined</code></td><td><code>null</code></td></tr></tbody></table></div>
|
|
82
|
+
<p>Each of these emits a warning that names the mistake:</p>
|
|
83
|
+
<pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="plaintext"><code><span class="line"><span>[HALLUCINATED_METHOD] `.includes()` does not exist in Firestore rules.</span></span>
|
|
84
|
+
<span class="line"><span> Use `x in list` instead of `list.includes(x)`</span></span></code></pre>
|
|
85
|
+
<p>The syntax-level catches (<code>===</code>, <code>?.</code>, <code>??</code>, arrow functions, backtick strings) fire even when the file fails to parse, because the parse error alone would point you at a stray parenthesis instead of the actual cause.</p>
|
|
86
|
+
<h2 id="block-shipping-on-rules-errors">Block shipping on Rules errors</h2>
|
|
87
|
+
<p>Warnings carry a severity. Gate CI (and refuse to <code>firebase deploy</code>) when any finding has <code>severity: 'error'</code>:</p>
|
|
88
|
+
<pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">const</span><span style="color:#E5C07B"> errors</span><span style="color:#56B6C2"> =</span><span style="color:#61AFEF"> lintFirestoreRules</span><span style="color:#ABB2BF">(</span><span style="color:#E06C75">source</span><span style="color:#ABB2BF">).</span><span style="color:#E06C75">warnings</span></span>
|
|
89
|
+
<span class="line"><span style="color:#ABB2BF"> .</span><span style="color:#61AFEF">filter</span><span style="color:#ABB2BF">((</span><span style="color:#E06C75;font-style:italic">w</span><span style="color:#ABB2BF">) </span><span style="color:#C678DD">=></span><span style="color:#E5C07B"> w</span><span style="color:#ABB2BF">.</span><span style="color:#E06C75">severity</span><span style="color:#56B6C2"> ===</span><span style="color:#98C379"> 'error'</span><span style="color:#ABB2BF">);</span></span>
|
|
90
|
+
<span class="line"><span style="color:#C678DD">if</span><span style="color:#ABB2BF"> (</span><span style="color:#E5C07B">errors</span><span style="color:#ABB2BF">.</span><span style="color:#E06C75">length</span><span style="color:#56B6C2"> ></span><span style="color:#D19A66"> 0</span><span style="color:#ABB2BF">) </span><span style="color:#E5C07B">process</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">exit</span><span style="color:#ABB2BF">(</span><span style="color:#D19A66">1</span><span style="color:#ABB2BF">);</span></span></code></pre>
|
|
91
|
+
<p>A hallucinated method is always an error, because the named method literally does not exist. Blocking on it is never a false alarm.</p>
|
|
92
|
+
<h2 id="correct-rules-through-an-agent">Correct Rules through an agent</h2>
|
|
93
|
+
<p>This is the loop that keeps an agent honest. It calls <code>firestore_lint_rules</code> on the rules it wrote, reads the fixes in the warnings, and corrects itself before anything deploys. Then <code>firestore_simulate_rules</code> confirms the behavior. The mistakes the linter catches are, in large part, the mistakes models make. See <a href="../skills/">what your agent can do</a>.</p>
|
|
94
|
+
<h2 id="where-to-go-next">Where to go next</h2>
|
|
95
|
+
<p>The exact numbers behind the limit checks are in <a href="../firestore-rules-limits/">the measured Firestore Rules limits</a>. To make simulation a habit rather than a one-off, <a href="../write-a-rules-test-suite/">write a rules test suite</a>.</p> </article> </main> <aside class="doc-toc" aria-label="On this page"> <h2 class="doc-toc-heading">On this page</h2> <ul> <li data-depth="2"> <a href="#simulate-a-hypothetical-request">Simulate a hypothetical request</a> </li><li data-depth="2"> <a href="#lint-before-firebase-rejects-the-rules">Lint before Firebase rejects the rules</a> </li><li data-depth="2"> <a href="#block-shipping-on-rules-errors">Block shipping on Rules errors</a> </li><li data-depth="2"> <a href="#correct-rules-through-an-agent">Correct Rules through an agent</a> </li><li data-depth="2"> <a href="#where-to-go-next">Where to go next</a> </li> </ul> </aside> </div> <script type="module">const a=document.querySelector("[data-api-symbol-filter]"),d=[...document.querySelectorAll("[data-api-symbol-group]")],n=document.querySelector("[data-api-symbol-empty]");a?.addEventListener("input",()=>{const t=a.value.trim().toLowerCase();let o=0;for(const i of d){let e=0;i.querySelectorAll("[data-api-symbol]").forEach(l=>{const r=!t||(l.dataset.apiSymbol??"").includes(t);l.hidden=!r,r&&e++}),i.hidden=e===0,o+=e}n&&(n.hidden=o>0)});</script> <script type="module">const s=new Map;document.querySelectorAll('.doc-toc a[href^="#"]').forEach(t=>s.set(decodeURIComponent(t.hash.slice(1)),t));if(s.size>0){const t=new Set,n=()=>{let o=null;for(const e of s.keys())if(t.has(e)){o=e;break}s.forEach((e,c)=>e.classList.toggle("active",c===o))},r=new IntersectionObserver(o=>{for(const e of o)e.isIntersecting?t.add(e.target.id):t.delete(e.target.id);n()},{rootMargin:"-72px 0px -60% 0px"});s.forEach((o,e)=>{const c=document.getElementById(e);c&&r.observe(c)})}</script> <script type="module">document.querySelector('.studio__nav [aria-current="page"]')?.scrollIntoView({block:"nearest",inline:"center"});</script> </body> </html>
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
|
|
2
|
+
# Simulate and lint Security Rules before deployment
|
|
3
|
+
|
|
4
|
+
A broken ruleset fails late: a `400` at deploy time, or a `403` at runtime. Pyric moves both failures to your machine, before the deploy.
|
|
5
|
+
|
|
6
|
+
Simulation tells you what a rule decides. Linting tells you what the production compiler and runtime will reject, and why, in the language of the mistake you made.
|
|
7
|
+
|
|
8
|
+
## Simulate a hypothetical request
|
|
9
|
+
|
|
10
|
+
Ask the simulator whether a specific request would be allowed. It runs in-process, no network, no project:
|
|
11
|
+
|
|
12
|
+
```ts
|
|
13
|
+
import { SimulateFirestoreRulesHandler } from 'pyric/rules';
|
|
14
|
+
|
|
15
|
+
const sim = new SimulateFirestoreRulesHandler();
|
|
16
|
+
const result = sim.simulate(source, [
|
|
17
|
+
{
|
|
18
|
+
description: 'unauthenticated read is denied',
|
|
19
|
+
expectation: 'DENY',
|
|
20
|
+
method: 'get',
|
|
21
|
+
path: 'notes/n1',
|
|
22
|
+
},
|
|
23
|
+
]);
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Each result is `PASSED`, `FAILED`, or `UNSUPPORTED`, and each carries `debugMessages`, a trace naming the rule that decided:
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
Rule #0 (read) → deny
|
|
30
|
+
Simulated: DENY
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
`UNSUPPORTED` means the simulator hit a feature it does not implement and abstained rather than guessed. Those cases can be routed to Google's own engine. See [write a rules test suite](../write-a-rules-test-suite/).
|
|
34
|
+
|
|
35
|
+
The same simulator is on the command line as `pyric firestore rules simulate`, and it is what evaluates every operation inside your running sandbox.
|
|
36
|
+
|
|
37
|
+
## Lint before Firebase rejects the rules
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
pyric firestore rules lint firestore.rules
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Or in code:
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
import { lintFirestoreRules } from 'pyric/rules';
|
|
47
|
+
|
|
48
|
+
const { warnings, metrics } = lintFirestoreRules(source);
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
The linter checks two different kinds of failure.
|
|
52
|
+
|
|
53
|
+
**The production limits.** The rules compiler enforces hard caps: a 256 KB source ceiling, a boolean chain depth of 98, 11 `let` bindings per function, `get()` call counts, and a runtime evaluation budget that fails as a silent `permission-denied` under load. The linter carries each cap as an exact threshold, measured by probing the production engine. The numbers live in [the measured Firestore Rules limits](../firestore-rules-limits/).
|
|
54
|
+
|
|
55
|
+
**JS-in-rules mistakes.** The rules language looks like JavaScript, and that resemblance is a trap. Models fall into it constantly, and humans do too.
|
|
56
|
+
|
|
57
|
+
Code like `resource.data.tags.includes('x')` parses fine and then fails at runtime as a bare `permission-denied`. The linter knows the specific ways this goes wrong and maps each one to the rules-language fix:
|
|
58
|
+
|
|
59
|
+
| You wrote | The rules language wants |
|
|
60
|
+
|---|---|
|
|
61
|
+
| `list.includes(x)` | `x in list` |
|
|
62
|
+
| `.toLowerCase()` / `.toUpperCase()` | `.lower()` / `.upper()` |
|
|
63
|
+
| `.filter(...)` / `.map(...)` | nothing; lists are not transformable, restructure the logic |
|
|
64
|
+
| `.length` | `.size()`, a method with parentheses |
|
|
65
|
+
| `obj?.field` | `'field' in obj && obj.field` |
|
|
66
|
+
| `x => ...` | `function name() { return ...; }` |
|
|
67
|
+
| `a === b` | `a == b` |
|
|
68
|
+
| `Object.keys(data)` | `data.keys()` |
|
|
69
|
+
| `request.data` | `request.resource.data` |
|
|
70
|
+
| `undefined` | `null` |
|
|
71
|
+
|
|
72
|
+
Each of these emits a warning that names the mistake:
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
[HALLUCINATED_METHOD] `.includes()` does not exist in Firestore rules.
|
|
76
|
+
Use `x in list` instead of `list.includes(x)`
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
The syntax-level catches (`===`, `?.`, `??`, arrow functions, backtick strings) fire even when the file fails to parse, because the parse error alone would point you at a stray parenthesis instead of the actual cause.
|
|
80
|
+
|
|
81
|
+
## Block shipping on Rules errors
|
|
82
|
+
|
|
83
|
+
Warnings carry a severity. Gate CI (and refuse to `firebase deploy`) when any finding has `severity: 'error'`:
|
|
84
|
+
|
|
85
|
+
```ts
|
|
86
|
+
const errors = lintFirestoreRules(source).warnings
|
|
87
|
+
.filter((w) => w.severity === 'error');
|
|
88
|
+
if (errors.length > 0) process.exit(1);
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
A hallucinated method is always an error, because the named method literally does not exist. Blocking on it is never a false alarm.
|
|
92
|
+
|
|
93
|
+
## Correct Rules through an agent
|
|
94
|
+
|
|
95
|
+
This is the loop that keeps an agent honest. It calls `firestore_lint_rules` on the rules it wrote, reads the fixes in the warnings, and corrects itself before anything deploys. Then `firestore_simulate_rules` confirms the behavior. The mistakes the linter catches are, in large part, the mistakes models make. See [what your agent can do](../skills/).
|
|
96
|
+
|
|
97
|
+
## Where to go next
|
|
98
|
+
|
|
99
|
+
The exact numbers behind the limit checks are in [the measured Firestore Rules limits](../firestore-rules-limits/). To make simulation a habit rather than a one-off, [write a rules test suite](../write-a-rules-test-suite/).
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<!DOCTYPE html><html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Give an agent methods for Firebase tasks · Pyric Studio</title><meta name="description" content="Packaged expert procedures for the problems that need a method, not more tools."><link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500;700&display=swap" rel="stylesheet"><link rel="stylesheet" href="/__pyric/ui/_astro/_slug_.CQYSemvw.css"></head> <body> <header class="studio__bar"> <div class="studio__bar-inner"> <a class="studio__brand" href="/__pyric/ui/" aria-label="Pyric Studio">Pyric</a> <nav class="studio__nav" aria-label="Studio tabs"> <a class="studio__nav-tab" href="/__pyric/ui/"> Home </a><a class="studio__nav-tab" href="/__pyric/ui/firestore"> Firestore </a><a class="studio__nav-tab" href="/__pyric/ui/auth"> Auth </a><a class="studio__nav-tab" href="/__pyric/ui/rtdb"> RTDB </a><a class="studio__nav-tab" href="/__pyric/ui/storage"> Storage </a><a class="studio__nav-tab" href="/__pyric/ui/traffic"> Traffic </a><a class="studio__nav-tab" href="/__pyric/ui/settings"> Settings </a><a class="studio__nav-tab" href="/__pyric/ui/docs" aria-current="page"> Docs </a> </nav> </div> </header> <div class="docs-shell"> <details class="docs-nav-drawer"> <summary>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> <a class="docs-nav-toplink" href="/__pyric/ui/docs/overview/"> Overview </a><details class="docs-nav-group"> <summary>Run locally</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/start-building/"> Quickstart </a> </li><li> <a href="/__pyric/ui/docs/how-the-swap-works/"> How the swap works </a> </li><li> <a href="/__pyric/ui/docs/set-up-your-agent/"> Connect an agent </a> </li><li> <a href="/__pyric/ui/docs/test-in-node/"> Test in Node </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Develop with Firebase APIs</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/sign-in-and-manage-users/"> Sign in and manage users </a> </li><li> <a href="/__pyric/ui/docs/store-and-query-data/"> Store and query data </a> </li><li> <a href="/__pyric/ui/docs/sync-realtime-data/"> Sync realtime data </a> </li><li> <a href="/__pyric/ui/docs/store-files/"> Store files </a> </li><li> <a href="/__pyric/ui/docs/receive-messages/"> Receive messages </a> </li><li> <a href="/__pyric/ui/docs/run-ai-logic-locally/"> Run AI Logic locally </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-how-to-run-rtdb-onvaluecreated/"> Run an RTDB function locally </a> </li><li> <a href="/__pyric/ui/docs/which-data-service/"> Which data service? </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" open> <summary>Inspect and correct</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <h2 class="docs-nav-heading"> Inspect the sandbox </h2> <ul> <li> <a href="/__pyric/ui/docs/see-whats-happening/"> Traffic & rule verdicts </a> </li><li> <a href="/__pyric/ui/docs/read-a-denial/"> Read a denial and understand it </a> </li><li> <a href="/__pyric/ui/docs/shape-your-data/"> Seed, snapshot, replay </a> </li><li> <a href="/__pyric/ui/docs/watch-and-review/"> Review agent activity </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading"> Correct Security Rules </h2> <ul> <li> <a href="/__pyric/ui/docs/secure-it-with-rules/"> Security Rules </a> </li><li> <a href="/__pyric/ui/docs/simulate-and-lint/"> Simulate and lint before you deploy </a> </li><li> <a href="/__pyric/ui/docs/rules-patterns/"> Rules patterns </a> </li><li> <a href="/__pyric/ui/docs/rules-standard-library/"> The rules standard library </a> </li><li> <a href="/__pyric/ui/docs/rtdb-rules-in-typescript/"> RTDB rules in TypeScript </a> </li><li> <a href="/__pyric/ui/docs/firestore-rules-limits/"> Rules limits </a> </li><li> <a href="/__pyric/ui/docs/whats-possible/"> Case studies </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading"> Work with an agent </h2> <ul> <li> <a href="/__pyric/ui/docs/what-your-agent-can-do/"> Work through an agent </a> </li><li> <a href="/__pyric/ui/docs/skills/" aria-current="page"> Agent skills </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Verify the boundary</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/pyric-cli-how-to-verify-against-a-captured-session/"> Verify a captured session </a> </li><li> <a href="/__pyric/ui/docs/write-a-rules-test-suite/"> Write a rules test suite </a> </li><li> <a href="/__pyric/ui/docs/audit-your-rules/"> Audit rules and data </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Ship unchanged</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/ship-to-production/"> Ship to production </a> </li><li> <a href="/__pyric/ui/docs/set-up-the-project/"> Set up the Firebase project </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Conformance</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/how-we-know-it-matches-firebase/"> Conformance </a> </li><li> <a href="/__pyric/ui/docs/whats-experimental/"> What's experimental </a> </li><li> <a href="/__pyric/ui/docs/pyric-conformance-scores/"> Conformance scores </a> </li><li> <a href="/__pyric/ui/docs/pyric-app-compat/"> App </a> </li><li> <a href="/__pyric/ui/docs/pyric-firestore-compat/"> Firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-auth-compat/"> Auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-database-compat/"> Realtime Database </a> </li><li> <a href="/__pyric/ui/docs/pyric-storage-compat/"> Storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-rules-compat/"> Rules </a> </li><li> <a href="/__pyric/ui/docs/pyric-messaging-compat/"> Messaging </a> </li><li> <a href="/__pyric/ui/docs/pyric-ai-compat/"> AI Logic </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-functions-rtdb-compat/"> Functions · RTDB </a> </li> </ul> </div> </div> </details> <details class="docs-nav-group"> <summary>Reference</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/pyric-cli/"> @pyric/cli </a> </li><li> <a href="/__pyric/ui/docs/pyric-explanation-versioning-and-compatibility/"> pyric </a> </li><li> <a href="/__pyric/ui/docs/pyric-firestore/"> pyric / firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-rules/"> pyric / rules </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox/"> pyric / sandbox </a> </li><li> <a href="/__pyric/ui/docs/pyric-storage/"> pyric / storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-auth/"> pyric / auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-database/"> pyric / database </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-app/"> pyric-admin / app </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-firestore/"> pyric-admin / firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-auth/"> pyric-admin / auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-database/"> pyric-admin / database </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-storage/"> pyric-admin / storage </a> </li><li> <a href="/__pyric/ui/docs/ui/"> @pyric/ui </a> </li><li> <a href="/__pyric/ui/docs/api-reference/"> API reference </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> <a class="docs-nav-toplink" href="/__pyric/ui/docs/overview/" id="nav-group-overview"> Overview </a><details class="docs-nav-group" id="nav-group-run-locally"> <summary>Run locally</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/start-building/"> Quickstart </a> </li><li> <a href="/__pyric/ui/docs/how-the-swap-works/"> How the swap works </a> </li><li> <a href="/__pyric/ui/docs/set-up-your-agent/"> Connect an agent </a> </li><li> <a href="/__pyric/ui/docs/test-in-node/"> Test in Node </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-develop-with-firebase-apis"> <summary>Develop with Firebase APIs</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/sign-in-and-manage-users/"> Sign in and manage users </a> </li><li> <a href="/__pyric/ui/docs/store-and-query-data/"> Store and query data </a> </li><li> <a href="/__pyric/ui/docs/sync-realtime-data/"> Sync realtime data </a> </li><li> <a href="/__pyric/ui/docs/store-files/"> Store files </a> </li><li> <a href="/__pyric/ui/docs/receive-messages/"> Receive messages </a> </li><li> <a href="/__pyric/ui/docs/run-ai-logic-locally/"> Run AI Logic locally </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-how-to-run-rtdb-onvaluecreated/"> Run an RTDB function locally </a> </li><li> <a href="/__pyric/ui/docs/which-data-service/"> Which data service? </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-inspect-and-correct" open> <summary>Inspect and correct</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <h2 class="docs-nav-heading" id="nav-section-inspect-and-correct-inspect-the-sandbox"> Inspect the sandbox </h2> <ul> <li> <a href="/__pyric/ui/docs/see-whats-happening/"> Traffic & rule verdicts </a> </li><li> <a href="/__pyric/ui/docs/read-a-denial/"> Read a denial and understand it </a> </li><li> <a href="/__pyric/ui/docs/shape-your-data/"> Seed, snapshot, replay </a> </li><li> <a href="/__pyric/ui/docs/watch-and-review/"> Review agent activity </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading" id="nav-section-inspect-and-correct-correct-security-rules"> Correct Security Rules </h2> <ul> <li> <a href="/__pyric/ui/docs/secure-it-with-rules/"> Security Rules </a> </li><li> <a href="/__pyric/ui/docs/simulate-and-lint/"> Simulate and lint before you deploy </a> </li><li> <a href="/__pyric/ui/docs/rules-patterns/"> Rules patterns </a> </li><li> <a href="/__pyric/ui/docs/rules-standard-library/"> The rules standard library </a> </li><li> <a href="/__pyric/ui/docs/rtdb-rules-in-typescript/"> RTDB rules in TypeScript </a> </li><li> <a href="/__pyric/ui/docs/firestore-rules-limits/"> Rules limits </a> </li><li> <a href="/__pyric/ui/docs/whats-possible/"> Case studies </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading" id="nav-section-inspect-and-correct-work-with-an-agent"> Work with an agent </h2> <ul> <li> <a href="/__pyric/ui/docs/what-your-agent-can-do/"> Work through an agent </a> </li><li> <a href="/__pyric/ui/docs/skills/" aria-current="page"> Agent skills </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-verify-the-boundary"> <summary>Verify the boundary</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/pyric-cli-how-to-verify-against-a-captured-session/"> Verify a captured session </a> </li><li> <a href="/__pyric/ui/docs/write-a-rules-test-suite/"> Write a rules test suite </a> </li><li> <a href="/__pyric/ui/docs/audit-your-rules/"> Audit rules and data </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-ship-unchanged"> <summary>Ship unchanged</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/ship-to-production/"> Ship to production </a> </li><li> <a href="/__pyric/ui/docs/set-up-the-project/"> Set up the Firebase project </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-conformance"> <summary>Conformance</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/how-we-know-it-matches-firebase/"> Conformance </a> </li><li> <a href="/__pyric/ui/docs/whats-experimental/"> What's experimental </a> </li><li> <a href="/__pyric/ui/docs/pyric-conformance-scores/"> Conformance scores </a> </li><li> <a href="/__pyric/ui/docs/pyric-app-compat/"> App </a> </li><li> <a href="/__pyric/ui/docs/pyric-firestore-compat/"> Firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-auth-compat/"> Auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-database-compat/"> Realtime Database </a> </li><li> <a href="/__pyric/ui/docs/pyric-storage-compat/"> Storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-rules-compat/"> Rules </a> </li><li> <a href="/__pyric/ui/docs/pyric-messaging-compat/"> Messaging </a> </li><li> <a href="/__pyric/ui/docs/pyric-ai-compat/"> AI Logic </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-functions-rtdb-compat/"> Functions · RTDB </a> </li> </ul> </div> </div> </details> <details class="docs-nav-group" id="nav-group-reference"> <summary>Reference</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/pyric-cli/"> @pyric/cli </a> </li><li> <a href="/__pyric/ui/docs/pyric-explanation-versioning-and-compatibility/"> pyric </a> </li><li> <a href="/__pyric/ui/docs/pyric-firestore/"> pyric / firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-rules/"> pyric / rules </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox/"> pyric / sandbox </a> </li><li> <a href="/__pyric/ui/docs/pyric-storage/"> pyric / storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-auth/"> pyric / auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-database/"> pyric / database </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-app/"> pyric-admin / app </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-firestore/"> pyric-admin / firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-auth/"> pyric-admin / auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-database/"> pyric-admin / database </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-storage/"> pyric-admin / storage </a> </li><li> <a href="/__pyric/ui/docs/ui/"> @pyric/ui </a> </li><li> <a href="/__pyric/ui/docs/api-reference/"> API reference </a> </li> </ul> </div> </div> </details> </nav> <main class="doc-main"> <nav class="docs-breadcrumbs" aria-label="Breadcrumb"> <ol> <li> <a href="#nav-group-inspect-and-correct">Inspect and correct</a> </li><li> <span class="docs-breadcrumbs-sep" aria-hidden="true">/</span> <a href="#nav-section-inspect-and-correct-work-with-an-agent">Work with an agent</a> </li><li> <span class="docs-breadcrumbs-sep" aria-hidden="true">/</span> <span aria-current="page">Agent skills</span> </li> </ol> </nav> <article class="prose"> <h1 id="give-an-agent-methods-for-firebase-tasks">Give an agent methods for Firebase tasks</h1>
|
|
2
|
+
<p>Tools give an agent hands. Skills give it a method. A skill is a written procedure the agent follows step by step, with a completion check on every step and the specific Pyric moves each step uses named in place.</p>
|
|
3
|
+
<p>An auth-model skill does not say “think about identity.” It says map every identity, check what providers are enabled with <code>auth_get_config</code>, connect every <code>request.auth.uid</code> in the rules to a real data shape, and do not stop until every access boundary has a named identity.</p>
|
|
4
|
+
<p>Six skills ship today, one per hard problem.</p>
|
|
5
|
+
<h2 id="install-the-skills">Install the skills</h2>
|
|
6
|
+
<p>The skills live in the Pyric repository under <code>.agents/skills/</code>, one folder per skill.</p>
|
|
7
|
+
<ul>
|
|
8
|
+
<li>Agents that read the <code>.agents/skills</code> convention pick them up in place.</li>
|
|
9
|
+
<li>For Claude Code, copy the folders you want into your project’s <code>.claude/skills/</code> directory.</li>
|
|
10
|
+
<li>The Claude Code plugin ships its own operational pieces (<code>pyric-start</code> boots and wires the sandbox), so the domain skills below slot into a session that is already connected.</li>
|
|
11
|
+
</ul>
|
|
12
|
+
<h2 id="choose-a-skill-for-the-task">Choose a skill for the task</h2>
|
|
13
|
+
<p><strong>firebase-auth-model.</strong> Design or audit an identity model that actually connects to your rules. It maps every identity your app has, chooses provider flows, decides where profile data lives and which document IDs use <code>uid</code>, and draws the line between custom claims and document roles so they never contradict, ending with test users you can seed. Serves <a href="../sign-in-and-manage-users/">sign in and manage users</a>.</p>
|
|
14
|
+
<p><strong>firestore-query-indexes.</strong> Treat a query plan as an index proof. The skill inventories every read the product performs, proves each list query is constrained so rules can allow it, then extracts the composite indexes from your actual query code instead of hand-writing JSON. If the extractor returns nothing, the fix is the source, not the JSON. Serves <a href="../store-and-query-data/">store and query data</a>.</p>
|
|
15
|
+
<p><strong>firestore-rules-audit.</strong> Answer who can do what, with evidence. It lints, builds an identity-by-operation access matrix with no blank cells, checks each expression against its operation context (a <code>list</code> cannot lean on one document’s <code>resource.data</code>, a <code>create</code> has no <code>resource.data</code> at all), and flags the composition traps where a permissive wildcard quietly overrides a careful restriction. Serves <a href="../audit-your-rules/">audit your rules</a>.</p>
|
|
16
|
+
<p><strong>rtdb-security-rules.</strong> Realtime Database rules cascade downward: a permissive parent grants every descendant and a child cannot take it back. The skill starts from a locked root, opens the smallest useful paths, pairs every open path with a validation, and walks each cascade so you can state the effective access at every path a client touches. Realtime Database support in Pyric is experimental. Serves <a href="../audit-your-rules/">audit your rules</a>.</p>
|
|
17
|
+
<p><strong>rtdb-data-model.</strong> One JSON tree, where reading a path downloads everything below it, so structure is performance. The skill designs paths around the reads: flat entity collections, index tables for reverse lookups, denormalized summaries sized for list screens, and a fan-out write plan so every duplicated field updates atomically. Realtime Database support in Pyric is experimental. Serves <a href="../sync-realtime-data/">sync realtime data</a>.</p>
|
|
18
|
+
<p><strong>firebase-audit.</strong> The whole-project posture check, read-only by design. It collects rules, real data shape, and auth configuration, then cross-references them: data paths with no meaningful rule, rules guarding paths where no data exists, writable paths without validation, and rule assumptions no enabled provider can satisfy. The output is a severity-ranked report with evidence for every finding. Serves <a href="../audit-your-rules/">audit your rules</a>.</p>
|
|
19
|
+
<h2 id="where-to-go-next">Where to go next</h2>
|
|
20
|
+
<p>A skill is only as good as the tools it drives, so read <a href="../what-your-agent-can-do/">what your agent can do</a> if you have not. Then run one and watch it work in <a href="../watch-and-review/">watch and review</a>.</p> </article> </main> <aside class="doc-toc" aria-label="On this page"> <h2 class="doc-toc-heading">On this page</h2> <ul> <li data-depth="2"> <a href="#install-the-skills">Install the skills</a> </li><li data-depth="2"> <a href="#choose-a-skill-for-the-task">Choose a skill for the task</a> </li><li data-depth="2"> <a href="#where-to-go-next">Where to go next</a> </li> </ul> </aside> </div> <script type="module">const a=document.querySelector("[data-api-symbol-filter]"),d=[...document.querySelectorAll("[data-api-symbol-group]")],n=document.querySelector("[data-api-symbol-empty]");a?.addEventListener("input",()=>{const t=a.value.trim().toLowerCase();let o=0;for(const i of d){let e=0;i.querySelectorAll("[data-api-symbol]").forEach(l=>{const r=!t||(l.dataset.apiSymbol??"").includes(t);l.hidden=!r,r&&e++}),i.hidden=e===0,o+=e}n&&(n.hidden=o>0)});</script> <script type="module">const s=new Map;document.querySelectorAll('.doc-toc a[href^="#"]').forEach(t=>s.set(decodeURIComponent(t.hash.slice(1)),t));if(s.size>0){const t=new Set,n=()=>{let o=null;for(const e of s.keys())if(t.has(e)){o=e;break}s.forEach((e,c)=>e.classList.toggle("active",c===o))},r=new IntersectionObserver(o=>{for(const e of o)e.isIntersecting?t.add(e.target.id):t.delete(e.target.id);n()},{rootMargin:"-72px 0px -60% 0px"});s.forEach((o,e)=>{const c=document.getElementById(e);c&&r.observe(c)})}</script> <script type="module">document.querySelector('.studio__nav [aria-current="page"]')?.scrollIntoView({block:"nearest",inline:"center"});</script> </body> </html>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
|
|
2
|
+
# Give an agent methods for Firebase tasks
|
|
3
|
+
|
|
4
|
+
Tools give an agent hands. Skills give it a method. A skill is a written procedure the agent follows step by step, with a completion check on every step and the specific Pyric moves each step uses named in place.
|
|
5
|
+
|
|
6
|
+
An auth-model skill does not say "think about identity." It says map every identity, check what providers are enabled with `auth_get_config`, connect every `request.auth.uid` in the rules to a real data shape, and do not stop until every access boundary has a named identity.
|
|
7
|
+
|
|
8
|
+
Six skills ship today, one per hard problem.
|
|
9
|
+
|
|
10
|
+
## Install the skills
|
|
11
|
+
|
|
12
|
+
The skills live in the Pyric repository under `.agents/skills/`, one folder per skill.
|
|
13
|
+
|
|
14
|
+
- Agents that read the `.agents/skills` convention pick them up in place.
|
|
15
|
+
- For Claude Code, copy the folders you want into your project's `.claude/skills/` directory.
|
|
16
|
+
- The Claude Code plugin ships its own operational pieces (`pyric-start` boots and wires the sandbox), so the domain skills below slot into a session that is already connected.
|
|
17
|
+
|
|
18
|
+
## Choose a skill for the task
|
|
19
|
+
|
|
20
|
+
**firebase-auth-model.** Design or audit an identity model that actually connects to your rules. It maps every identity your app has, chooses provider flows, decides where profile data lives and which document IDs use `uid`, and draws the line between custom claims and document roles so they never contradict, ending with test users you can seed. Serves [sign in and manage users](../sign-in-and-manage-users/).
|
|
21
|
+
|
|
22
|
+
**firestore-query-indexes.** Treat a query plan as an index proof. The skill inventories every read the product performs, proves each list query is constrained so rules can allow it, then extracts the composite indexes from your actual query code instead of hand-writing JSON. If the extractor returns nothing, the fix is the source, not the JSON. Serves [store and query data](../store-and-query-data/).
|
|
23
|
+
|
|
24
|
+
**firestore-rules-audit.** Answer who can do what, with evidence. It lints, builds an identity-by-operation access matrix with no blank cells, checks each expression against its operation context (a `list` cannot lean on one document's `resource.data`, a `create` has no `resource.data` at all), and flags the composition traps where a permissive wildcard quietly overrides a careful restriction. Serves [audit your rules](../audit-your-rules/).
|
|
25
|
+
|
|
26
|
+
**rtdb-security-rules.** Realtime Database rules cascade downward: a permissive parent grants every descendant and a child cannot take it back. The skill starts from a locked root, opens the smallest useful paths, pairs every open path with a validation, and walks each cascade so you can state the effective access at every path a client touches. Realtime Database support in Pyric is experimental. Serves [audit your rules](../audit-your-rules/).
|
|
27
|
+
|
|
28
|
+
**rtdb-data-model.** One JSON tree, where reading a path downloads everything below it, so structure is performance. The skill designs paths around the reads: flat entity collections, index tables for reverse lookups, denormalized summaries sized for list screens, and a fan-out write plan so every duplicated field updates atomically. Realtime Database support in Pyric is experimental. Serves [sync realtime data](../sync-realtime-data/).
|
|
29
|
+
|
|
30
|
+
**firebase-audit.** The whole-project posture check, read-only by design. It collects rules, real data shape, and auth configuration, then cross-references them: data paths with no meaningful rule, rules guarding paths where no data exists, writable paths without validation, and rule assumptions no enabled provider can satisfy. The output is a severity-ranked report with evidence for every finding. Serves [audit your rules](../audit-your-rules/).
|
|
31
|
+
|
|
32
|
+
## Where to go next
|
|
33
|
+
|
|
34
|
+
A skill is only as good as the tools it drives, so read [what your agent can do](../what-your-agent-can-do/) if you have not. Then run one and watch it work in [watch and review](../watch-and-review/).
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
<!DOCTYPE html><html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Run Firebase locally · Pyric Studio</title><meta name="description" content="Start a new Firebase application or add Pyric to an existing Vite application without connecting development to production."><link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500;700&display=swap" rel="stylesheet"><link rel="stylesheet" href="/__pyric/ui/_astro/_slug_.CQYSemvw.css"></head> <body> <header class="studio__bar"> <div class="studio__bar-inner"> <a class="studio__brand" href="/__pyric/ui/" aria-label="Pyric Studio">Pyric</a> <nav class="studio__nav" aria-label="Studio tabs"> <a class="studio__nav-tab" href="/__pyric/ui/"> Home </a><a class="studio__nav-tab" href="/__pyric/ui/firestore"> Firestore </a><a class="studio__nav-tab" href="/__pyric/ui/auth"> Auth </a><a class="studio__nav-tab" href="/__pyric/ui/rtdb"> RTDB </a><a class="studio__nav-tab" href="/__pyric/ui/storage"> Storage </a><a class="studio__nav-tab" href="/__pyric/ui/traffic"> Traffic </a><a class="studio__nav-tab" href="/__pyric/ui/settings"> Settings </a><a class="studio__nav-tab" href="/__pyric/ui/docs" aria-current="page"> Docs </a> </nav> </div> </header> <div class="docs-shell"> <details class="docs-nav-drawer"> <summary>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> <a class="docs-nav-toplink" href="/__pyric/ui/docs/overview/"> Overview </a><details class="docs-nav-group" open> <summary>Run locally</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/start-building/" aria-current="page"> Quickstart </a> </li><li> <a href="/__pyric/ui/docs/how-the-swap-works/"> How the swap works </a> </li><li> <a href="/__pyric/ui/docs/set-up-your-agent/"> Connect an agent </a> </li><li> <a href="/__pyric/ui/docs/test-in-node/"> Test in Node </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Develop with Firebase APIs</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/sign-in-and-manage-users/"> Sign in and manage users </a> </li><li> <a href="/__pyric/ui/docs/store-and-query-data/"> Store and query data </a> </li><li> <a href="/__pyric/ui/docs/sync-realtime-data/"> Sync realtime data </a> </li><li> <a href="/__pyric/ui/docs/store-files/"> Store files </a> </li><li> <a href="/__pyric/ui/docs/receive-messages/"> Receive messages </a> </li><li> <a href="/__pyric/ui/docs/run-ai-logic-locally/"> Run AI Logic locally </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-how-to-run-rtdb-onvaluecreated/"> Run an RTDB function locally </a> </li><li> <a href="/__pyric/ui/docs/which-data-service/"> Which data service? </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Inspect and correct</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <h2 class="docs-nav-heading"> Inspect the sandbox </h2> <ul> <li> <a href="/__pyric/ui/docs/see-whats-happening/"> Traffic & rule verdicts </a> </li><li> <a href="/__pyric/ui/docs/read-a-denial/"> Read a denial and understand it </a> </li><li> <a href="/__pyric/ui/docs/shape-your-data/"> Seed, snapshot, replay </a> </li><li> <a href="/__pyric/ui/docs/watch-and-review/"> Review agent activity </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading"> Correct Security Rules </h2> <ul> <li> <a href="/__pyric/ui/docs/secure-it-with-rules/"> Security Rules </a> </li><li> <a href="/__pyric/ui/docs/simulate-and-lint/"> Simulate and lint before you deploy </a> </li><li> <a href="/__pyric/ui/docs/rules-patterns/"> Rules patterns </a> </li><li> <a href="/__pyric/ui/docs/rules-standard-library/"> The rules standard library </a> </li><li> <a href="/__pyric/ui/docs/rtdb-rules-in-typescript/"> RTDB rules in TypeScript </a> </li><li> <a href="/__pyric/ui/docs/firestore-rules-limits/"> Rules limits </a> </li><li> <a href="/__pyric/ui/docs/whats-possible/"> Case studies </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading"> Work with an agent </h2> <ul> <li> <a href="/__pyric/ui/docs/what-your-agent-can-do/"> Work through an agent </a> </li><li> <a href="/__pyric/ui/docs/skills/"> Agent skills </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Verify the boundary</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/pyric-cli-how-to-verify-against-a-captured-session/"> Verify a captured session </a> </li><li> <a href="/__pyric/ui/docs/write-a-rules-test-suite/"> Write a rules test suite </a> </li><li> <a href="/__pyric/ui/docs/audit-your-rules/"> Audit rules and data </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Ship unchanged</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/ship-to-production/"> Ship to production </a> </li><li> <a href="/__pyric/ui/docs/set-up-the-project/"> Set up the Firebase project </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Conformance</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/how-we-know-it-matches-firebase/"> Conformance </a> </li><li> <a href="/__pyric/ui/docs/whats-experimental/"> What's experimental </a> </li><li> <a href="/__pyric/ui/docs/pyric-conformance-scores/"> Conformance scores </a> </li><li> <a href="/__pyric/ui/docs/pyric-app-compat/"> App </a> </li><li> <a href="/__pyric/ui/docs/pyric-firestore-compat/"> Firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-auth-compat/"> Auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-database-compat/"> Realtime Database </a> </li><li> <a href="/__pyric/ui/docs/pyric-storage-compat/"> Storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-rules-compat/"> Rules </a> </li><li> <a href="/__pyric/ui/docs/pyric-messaging-compat/"> Messaging </a> </li><li> <a href="/__pyric/ui/docs/pyric-ai-compat/"> AI Logic </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-functions-rtdb-compat/"> Functions · RTDB </a> </li> </ul> </div> </div> </details> <details class="docs-nav-group"> <summary>Reference</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/pyric-cli/"> @pyric/cli </a> </li><li> <a href="/__pyric/ui/docs/pyric-explanation-versioning-and-compatibility/"> pyric </a> </li><li> <a href="/__pyric/ui/docs/pyric-firestore/"> pyric / firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-rules/"> pyric / rules </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox/"> pyric / sandbox </a> </li><li> <a href="/__pyric/ui/docs/pyric-storage/"> pyric / storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-auth/"> pyric / auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-database/"> pyric / database </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-app/"> pyric-admin / app </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-firestore/"> pyric-admin / firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-auth/"> pyric-admin / auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-database/"> pyric-admin / database </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-storage/"> pyric-admin / storage </a> </li><li> <a href="/__pyric/ui/docs/ui/"> @pyric/ui </a> </li><li> <a href="/__pyric/ui/docs/api-reference/"> API reference </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> <a class="docs-nav-toplink" href="/__pyric/ui/docs/overview/" id="nav-group-overview"> Overview </a><details class="docs-nav-group" id="nav-group-run-locally" open> <summary>Run locally</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/start-building/" aria-current="page"> Quickstart </a> </li><li> <a href="/__pyric/ui/docs/how-the-swap-works/"> How the swap works </a> </li><li> <a href="/__pyric/ui/docs/set-up-your-agent/"> Connect an agent </a> </li><li> <a href="/__pyric/ui/docs/test-in-node/"> Test in Node </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-develop-with-firebase-apis"> <summary>Develop with Firebase APIs</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/sign-in-and-manage-users/"> Sign in and manage users </a> </li><li> <a href="/__pyric/ui/docs/store-and-query-data/"> Store and query data </a> </li><li> <a href="/__pyric/ui/docs/sync-realtime-data/"> Sync realtime data </a> </li><li> <a href="/__pyric/ui/docs/store-files/"> Store files </a> </li><li> <a href="/__pyric/ui/docs/receive-messages/"> Receive messages </a> </li><li> <a href="/__pyric/ui/docs/run-ai-logic-locally/"> Run AI Logic locally </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-how-to-run-rtdb-onvaluecreated/"> Run an RTDB function locally </a> </li><li> <a href="/__pyric/ui/docs/which-data-service/"> Which data service? </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-inspect-and-correct"> <summary>Inspect and correct</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <h2 class="docs-nav-heading" id="nav-section-inspect-and-correct-inspect-the-sandbox"> Inspect the sandbox </h2> <ul> <li> <a href="/__pyric/ui/docs/see-whats-happening/"> Traffic & rule verdicts </a> </li><li> <a href="/__pyric/ui/docs/read-a-denial/"> Read a denial and understand it </a> </li><li> <a href="/__pyric/ui/docs/shape-your-data/"> Seed, snapshot, replay </a> </li><li> <a href="/__pyric/ui/docs/watch-and-review/"> Review agent activity </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading" id="nav-section-inspect-and-correct-correct-security-rules"> Correct Security Rules </h2> <ul> <li> <a href="/__pyric/ui/docs/secure-it-with-rules/"> Security Rules </a> </li><li> <a href="/__pyric/ui/docs/simulate-and-lint/"> Simulate and lint before you deploy </a> </li><li> <a href="/__pyric/ui/docs/rules-patterns/"> Rules patterns </a> </li><li> <a href="/__pyric/ui/docs/rules-standard-library/"> The rules standard library </a> </li><li> <a href="/__pyric/ui/docs/rtdb-rules-in-typescript/"> RTDB rules in TypeScript </a> </li><li> <a href="/__pyric/ui/docs/firestore-rules-limits/"> Rules limits </a> </li><li> <a href="/__pyric/ui/docs/whats-possible/"> Case studies </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading" id="nav-section-inspect-and-correct-work-with-an-agent"> Work with an agent </h2> <ul> <li> <a href="/__pyric/ui/docs/what-your-agent-can-do/"> Work through an agent </a> </li><li> <a href="/__pyric/ui/docs/skills/"> Agent skills </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-verify-the-boundary"> <summary>Verify the boundary</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/pyric-cli-how-to-verify-against-a-captured-session/"> Verify a captured session </a> </li><li> <a href="/__pyric/ui/docs/write-a-rules-test-suite/"> Write a rules test suite </a> </li><li> <a href="/__pyric/ui/docs/audit-your-rules/"> Audit rules and data </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-ship-unchanged"> <summary>Ship unchanged</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/ship-to-production/"> Ship to production </a> </li><li> <a href="/__pyric/ui/docs/set-up-the-project/"> Set up the Firebase project </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-conformance"> <summary>Conformance</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/how-we-know-it-matches-firebase/"> Conformance </a> </li><li> <a href="/__pyric/ui/docs/whats-experimental/"> What's experimental </a> </li><li> <a href="/__pyric/ui/docs/pyric-conformance-scores/"> Conformance scores </a> </li><li> <a href="/__pyric/ui/docs/pyric-app-compat/"> App </a> </li><li> <a href="/__pyric/ui/docs/pyric-firestore-compat/"> Firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-auth-compat/"> Auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-database-compat/"> Realtime Database </a> </li><li> <a href="/__pyric/ui/docs/pyric-storage-compat/"> Storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-rules-compat/"> Rules </a> </li><li> <a href="/__pyric/ui/docs/pyric-messaging-compat/"> Messaging </a> </li><li> <a href="/__pyric/ui/docs/pyric-ai-compat/"> AI Logic </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-functions-rtdb-compat/"> Functions · RTDB </a> </li> </ul> </div> </div> </details> <details class="docs-nav-group" id="nav-group-reference"> <summary>Reference</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/pyric-cli/"> @pyric/cli </a> </li><li> <a href="/__pyric/ui/docs/pyric-explanation-versioning-and-compatibility/"> pyric </a> </li><li> <a href="/__pyric/ui/docs/pyric-firestore/"> pyric / firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-rules/"> pyric / rules </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox/"> pyric / sandbox </a> </li><li> <a href="/__pyric/ui/docs/pyric-storage/"> pyric / storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-auth/"> pyric / auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-database/"> pyric / database </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-app/"> pyric-admin / app </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-firestore/"> pyric-admin / firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-auth/"> pyric-admin / auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-database/"> pyric-admin / database </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-storage/"> pyric-admin / storage </a> </li><li> <a href="/__pyric/ui/docs/ui/"> @pyric/ui </a> </li><li> <a href="/__pyric/ui/docs/api-reference/"> API reference </a> </li> </ul> </div> </div> </details> </nav> <main class="doc-main"> <nav class="docs-breadcrumbs" aria-label="Breadcrumb"> <ol> <li> <a href="/__pyric/ui/docs/start-building/">Run locally</a> </li><li> <span class="docs-breadcrumbs-sep" aria-hidden="true">/</span> <span aria-current="page">Quickstart</span> </li> </ol> </nav> <article class="prose"> <h1 id="run-firebase-locally">Run Firebase locally</h1>
|
|
2
|
+
<p>Pyric adds a development-only resolution layer to a Firebase application. During Vite development, supported <code>firebase/*</code> imports resolve to a browser-local backend. A normal production build resolves those imports to Firebase again.</p>
|
|
3
|
+
<h2 id="start-a-new-application">Start a new application</h2>
|
|
4
|
+
<p>Create a Vite application with canonical Firebase imports, Firestore rules, and the Pyric plugin already configured:</p>
|
|
5
|
+
<pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="bash"><code><span class="line"><span style="color:#61AFEF">npx</span><span style="color:#98C379"> create-pyric</span><span style="color:#98C379"> my-app</span></span>
|
|
6
|
+
<span class="line"><span style="color:#56B6C2">cd</span><span style="color:#98C379"> my-app</span></span>
|
|
7
|
+
<span class="line"><span style="color:#61AFEF">npm</span><span style="color:#98C379"> install</span></span>
|
|
8
|
+
<span class="line"><span style="color:#61AFEF">npm</span><span style="color:#98C379"> run</span><span style="color:#98C379"> dev</span></span></code></pre>
|
|
9
|
+
<p><code>npm create pyric my-app</code> runs the same scaffold.</p>
|
|
10
|
+
<p>Open the local URL printed by Vite. The application and Pyric Studio use the same local backend. Studio is mounted at <code>/__pyric/ui/</code> on that origin.</p>
|
|
11
|
+
<h2 id="add-pyric-to-an-existing-vite-application">Add Pyric to an existing Vite application</h2>
|
|
12
|
+
<p>Install the development plugin:</p>
|
|
13
|
+
<pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="bash"><code><span class="line"><span style="color:#61AFEF">npm</span><span style="color:#98C379"> install</span><span style="color:#D19A66"> --save-dev</span><span style="color:#98C379"> @pyric/cli</span></span></code></pre>
|
|
14
|
+
<p>Add it to the Vite configuration:</p>
|
|
15
|
+
<pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#7F848E;font-style:italic">// vite.config.ts</span></span>
|
|
16
|
+
<span class="line"><span style="color:#C678DD">import</span><span style="color:#ABB2BF"> { </span><span style="color:#E06C75">defineConfig</span><span style="color:#ABB2BF"> } </span><span style="color:#C678DD">from</span><span style="color:#98C379"> 'vite'</span><span style="color:#ABB2BF">;</span></span>
|
|
17
|
+
<span class="line"><span style="color:#C678DD">import</span><span style="color:#ABB2BF"> { </span><span style="color:#E06C75">pyricSandbox</span><span style="color:#ABB2BF"> } </span><span style="color:#C678DD">from</span><span style="color:#98C379"> '@pyric/cli/vite'</span><span style="color:#ABB2BF">;</span></span>
|
|
18
|
+
<span class="line"></span>
|
|
19
|
+
<span class="line"><span style="color:#C678DD">export</span><span style="color:#C678DD"> default</span><span style="color:#61AFEF"> defineConfig</span><span style="color:#ABB2BF">({</span></span>
|
|
20
|
+
<span class="line"><span style="color:#E06C75"> plugins</span><span style="color:#ABB2BF">: [</span><span style="color:#61AFEF">pyricSandbox</span><span style="color:#ABB2BF">()],</span></span>
|
|
21
|
+
<span class="line"><span style="color:#ABB2BF">});</span></span></code></pre>
|
|
22
|
+
<p>Start the normal development server:</p>
|
|
23
|
+
<pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="bash"><code><span class="line"><span style="color:#61AFEF">npm</span><span style="color:#98C379"> run</span><span style="color:#98C379"> dev</span></span></code></pre>
|
|
24
|
+
<p>No application imports change. Continue using <code>firebase/app</code>, <code>firebase/auth</code>, <code>firebase/firestore</code>, and the other supported Firebase entry points. The plugin discovers Firestore rules from <code>firebase.json</code>, or uses <code>firestore.rules</code> when no path is configured.</p>
|
|
25
|
+
<h2 id="use-a-static-application-or-node-process">Use a static application or Node process</h2>
|
|
26
|
+
<p><code>pyric dev</code> provides the same development-only package swap outside the Vite plugin:</p>
|
|
27
|
+
<pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="bash"><code><span class="line"><span style="color:#61AFEF">npm</span><span style="color:#98C379"> install</span><span style="color:#D19A66"> --save-dev</span><span style="color:#98C379"> @pyric/cli</span></span>
|
|
28
|
+
<span class="line"><span style="color:#61AFEF">npx</span><span style="color:#98C379"> pyric</span><span style="color:#98C379"> dev</span></span></code></pre>
|
|
29
|
+
<p>It can serve static files or start an existing development command. <a href="../pyric-cli/">The CLI guide</a> covers those paths. <a href="../test-in-node/">Test in Node</a> covers an in-process sandbox for tests and scripts.</p>
|
|
30
|
+
<h2 id="what-remains-local">What remains local</h2>
|
|
31
|
+
<p>The mirrored services do not connect to a production Firebase project. Local data changes stay in the sandbox. Local Security Rules changes are enforced there and are not deployed. Firebase configuration passed to <code>initializeApp(config)</code> is accepted so the application code stays unchanged, but it does not select a cloud backend during development.</p>
|
|
32
|
+
<p>Continue with <a href="../how-the-swap-works/">How the swap works</a>, then <a href="../sign-in-and-manage-users/">develop with the Firebase APIs</a>.</p> </article> </main> <aside class="doc-toc" aria-label="On this page"> <h2 class="doc-toc-heading">On this page</h2> <ul> <li data-depth="2"> <a href="#start-a-new-application">Start a new application</a> </li><li data-depth="2"> <a href="#add-pyric-to-an-existing-vite-application">Add Pyric to an existing Vite application</a> </li><li data-depth="2"> <a href="#use-a-static-application-or-node-process">Use a static application or Node process</a> </li><li data-depth="2"> <a href="#what-remains-local">What remains local</a> </li> </ul> </aside> </div> <script type="module">const a=document.querySelector("[data-api-symbol-filter]"),d=[...document.querySelectorAll("[data-api-symbol-group]")],n=document.querySelector("[data-api-symbol-empty]");a?.addEventListener("input",()=>{const t=a.value.trim().toLowerCase();let o=0;for(const i of d){let e=0;i.querySelectorAll("[data-api-symbol]").forEach(l=>{const r=!t||(l.dataset.apiSymbol??"").includes(t);l.hidden=!r,r&&e++}),i.hidden=e===0,o+=e}n&&(n.hidden=o>0)});</script> <script type="module">const s=new Map;document.querySelectorAll('.doc-toc a[href^="#"]').forEach(t=>s.set(decodeURIComponent(t.hash.slice(1)),t));if(s.size>0){const t=new Set,n=()=>{let o=null;for(const e of s.keys())if(t.has(e)){o=e;break}s.forEach((e,c)=>e.classList.toggle("active",c===o))},r=new IntersectionObserver(o=>{for(const e of o)e.isIntersecting?t.add(e.target.id):t.delete(e.target.id);n()},{rootMargin:"-72px 0px -60% 0px"});s.forEach((o,e)=>{const c=document.getElementById(e);c&&r.observe(c)})}</script> <script type="module">document.querySelector('.studio__nav [aria-current="page"]')?.scrollIntoView({block:"nearest",inline:"center"});</script> </body> </html>
|