@pyric/cli 0.1.0-alpha.19 → 0.1.0-alpha.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +64 -89
- package/dist/assurance/.generated/conformance-verdicts.d.ts +68 -1
- package/dist/assurance/.generated/conformance-verdicts.d.ts.map +1 -1
- package/dist/assurance/.generated/conformance-verdicts.js +68 -1
- package/dist/assurance/.generated/conformance-verdicts.js.map +1 -1
- package/dist/bridge/client/dispatch.d.ts +25 -19
- package/dist/bridge/client/dispatch.d.ts.map +1 -1
- package/dist/bridge/client/dispatch.js +41 -48
- package/dist/bridge/client/dispatch.js.map +1 -1
- package/dist/bridge/client/tool-family-factories.d.ts +26 -0
- package/dist/bridge/client/tool-family-factories.d.ts.map +1 -0
- package/dist/bridge/client/tool-family-factories.js +10 -0
- package/dist/bridge/client/tool-family-factories.js.map +1 -0
- package/dist/bridge/server/mcp-contract.d.ts +7 -6
- package/dist/bridge/server/mcp-contract.d.ts.map +1 -1
- package/dist/bridge/server/mcp-contract.js +9 -48
- package/dist/bridge/server/mcp-contract.js.map +1 -1
- package/dist/bridge/server/peer.d.ts +11 -1
- package/dist/bridge/server/peer.d.ts.map +1 -1
- package/dist/bridge/server/peer.js +22 -1
- package/dist/bridge/server/peer.js.map +1 -1
- package/dist/bridge/server/tool-family-factories.d.ts +30 -0
- package/dist/bridge/server/tool-family-factories.d.ts.map +1 -0
- package/dist/bridge/server/tool-family-factories.js +22 -0
- package/dist/bridge/server/tool-family-factories.js.map +1 -0
- package/dist/bridge/server/tool-metadata.d.ts +17 -18
- package/dist/bridge/server/tool-metadata.d.ts.map +1 -1
- package/dist/bridge/server/tool-metadata.js +24 -59
- package/dist/bridge/server/tool-metadata.js.map +1 -1
- package/dist/bridge/tool-families.d.ts +48 -0
- package/dist/bridge/tool-families.d.ts.map +1 -0
- package/dist/bridge/tool-families.generated.d.ts +32 -0
- package/dist/bridge/tool-families.generated.d.ts.map +1 -0
- package/dist/bridge/tool-families.generated.js +15 -0
- package/dist/bridge/tool-families.generated.js.map +1 -0
- package/dist/bridge/tool-families.js +51 -0
- package/dist/bridge/tool-families.js.map +1 -0
- package/dist/bridge/tool-family-records/conformance.d.ts +7 -0
- package/dist/bridge/tool-family-records/conformance.d.ts.map +1 -0
- package/dist/bridge/tool-family-records/conformance.js +6 -0
- package/dist/bridge/tool-family-records/conformance.js.map +1 -0
- package/dist/bridge/tool-family-records/firestore-data.d.ts +7 -0
- package/dist/bridge/tool-family-records/firestore-data.d.ts.map +1 -0
- package/dist/bridge/tool-family-records/firestore-data.js +15 -0
- package/dist/bridge/tool-family-records/firestore-data.js.map +1 -0
- package/dist/bridge/tool-family-records/firestore-inspect.d.ts +7 -0
- package/dist/bridge/tool-family-records/firestore-inspect.d.ts.map +1 -0
- package/dist/bridge/tool-family-records/firestore-inspect.js +6 -0
- package/dist/bridge/tool-family-records/firestore-inspect.js.map +1 -0
- package/dist/bridge/tool-family-records/firestore-rules.d.ts +7 -0
- package/dist/bridge/tool-family-records/firestore-rules.d.ts.map +1 -0
- package/dist/bridge/tool-family-records/firestore-rules.js +15 -0
- package/dist/bridge/tool-family-records/firestore-rules.js.map +1 -0
- package/dist/bridge/tool-family-records/firestore-simulator.d.ts +7 -0
- package/dist/bridge/tool-family-records/firestore-simulator.d.ts.map +1 -0
- package/dist/bridge/tool-family-records/firestore-simulator.js +16 -0
- package/dist/bridge/tool-family-records/firestore-simulator.js.map +1 -0
- package/dist/bridge/tool-family-records/rtdb-inspection.d.ts +7 -0
- package/dist/bridge/tool-family-records/rtdb-inspection.d.ts.map +1 -0
- package/dist/bridge/tool-family-records/rtdb-inspection.js +6 -0
- package/dist/bridge/tool-family-records/rtdb-inspection.js.map +1 -0
- package/dist/bundler/externals.d.ts +37 -0
- package/dist/bundler/externals.d.ts.map +1 -0
- package/dist/bundler/externals.js +52 -0
- package/dist/bundler/externals.js.map +1 -0
- package/dist/bundler/index.d.ts +17 -0
- package/dist/bundler/index.d.ts.map +1 -0
- package/dist/bundler/index.js +17 -0
- package/dist/bundler/index.js.map +1 -0
- package/dist/cli/index.d.ts +2 -2
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +48 -42
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/inlined-sdk-scanner.d.ts +6 -0
- package/dist/cli/inlined-sdk-scanner.d.ts.map +1 -0
- package/dist/cli/inlined-sdk-scanner.js +82 -0
- package/dist/cli/inlined-sdk-scanner.js.map +1 -0
- package/dist/cli/mcp-proxy.js +3 -3
- package/dist/cli/mcp-proxy.js.map +1 -1
- package/dist/cli/parse-args.d.ts +1 -1
- package/dist/cli/parse-args.d.ts.map +1 -1
- package/dist/cli/parse-args.js +51 -15
- package/dist/cli/parse-args.js.map +1 -1
- package/dist/cli/pyric-config.d.ts +24 -0
- package/dist/cli/pyric-config.d.ts.map +1 -0
- package/dist/cli/pyric-config.js +28 -0
- package/dist/cli/pyric-config.js.map +1 -0
- package/dist/cli/sandbox-interlock.d.ts +97 -0
- package/dist/cli/sandbox-interlock.d.ts.map +1 -0
- package/dist/cli/sandbox-interlock.js +112 -0
- package/dist/cli/sandbox-interlock.js.map +1 -0
- package/dist/cli/{dev-runner.d.ts → sandbox-runner.d.ts} +53 -48
- package/dist/cli/sandbox-runner.d.ts.map +1 -0
- package/dist/cli/{dev-runner.js → sandbox-runner.js} +105 -67
- package/dist/cli/sandbox-runner.js.map +1 -0
- package/dist/cli/serve.d.ts +12 -14
- package/dist/cli/serve.d.ts.map +1 -1
- package/dist/cli/serve.js +155 -116
- package/dist/cli/serve.js.map +1 -1
- package/dist/cli/snapshot.js +5 -5
- package/dist/cli/snapshot.js.map +1 -1
- package/dist/cli/unsupported-runtime.d.ts +27 -0
- package/dist/cli/unsupported-runtime.d.ts.map +1 -0
- package/dist/cli/unsupported-runtime.js +63 -0
- package/dist/cli/unsupported-runtime.js.map +1 -0
- package/dist/cli/verify.js +1 -1
- package/dist/cli/verify.js.map +1 -1
- package/dist/conformance/.generated/can-i-use-browser.d.ts +1 -1
- package/dist/conformance/.generated/can-i-use-browser.d.ts.map +1 -1
- package/dist/conformance/.generated/can-i-use-browser.js +1 -1
- package/dist/conformance/.generated/can-i-use-browser.js.map +1 -1
- package/dist/conformance/.generated/can-i-use.d.ts +1 -1
- package/dist/conformance/.generated/can-i-use.d.ts.map +1 -1
- package/dist/conformance/.generated/can-i-use.js +1 -1
- package/dist/conformance/.generated/can-i-use.js.map +1 -1
- package/dist/conformance/.generated/conformance-docs.d.ts.map +1 -1
- package/dist/conformance/.generated/conformance-docs.js +1 -1
- package/dist/conformance/.generated/conformance-docs.js.map +1 -1
- package/dist/functions-rtdb/child.d.ts +37 -0
- package/dist/functions-rtdb/child.d.ts.map +1 -1
- package/dist/functions-rtdb/child.js +90 -21
- package/dist/functions-rtdb/child.js.map +1 -1
- package/dist/functions-rtdb/development-runtime.d.ts +3 -0
- package/dist/functions-rtdb/development-runtime.d.ts.map +1 -1
- package/dist/functions-rtdb/development-runtime.js +2 -1
- package/dist/functions-rtdb/development-runtime.js.map +1 -1
- package/dist/functions-rtdb/project.js +8 -8
- package/dist/functions-rtdb/project.js.map +1 -1
- package/dist/google-endpoints.d.ts +67 -0
- package/dist/google-endpoints.d.ts.map +1 -0
- package/dist/google-endpoints.js +119 -0
- package/dist/google-endpoints.js.map +1 -0
- package/dist/next/guard.js +1 -1
- package/dist/next/guard.js.map +1 -1
- package/dist/next/runtime-env.d.ts.map +1 -1
- package/dist/next/runtime-env.js +5 -0
- package/dist/next/runtime-env.js.map +1 -1
- package/dist/next/with-pyric.d.ts +1 -1
- package/dist/next/with-pyric.js +1 -1
- package/dist/register/beacon.d.ts +69 -0
- package/dist/register/beacon.d.ts.map +1 -0
- package/dist/register/beacon.js +199 -0
- package/dist/register/beacon.js.map +1 -0
- package/dist/register/index.d.ts.map +1 -1
- package/dist/register/index.js +65 -6
- package/dist/register/index.js.map +1 -1
- package/dist/register/net-guard.d.ts +110 -0
- package/dist/register/net-guard.d.ts.map +1 -0
- package/dist/register/net-guard.js +462 -0
- package/dist/register/net-guard.js.map +1 -0
- package/dist/remote/index.d.ts +1 -1
- package/dist/remote/index.js +9 -9
- package/dist/remote/index.js.map +1 -1
- package/dist/serve/ai-diagnostics-relay.d.ts +63 -0
- package/dist/serve/ai-diagnostics-relay.d.ts.map +1 -0
- package/dist/serve/ai-diagnostics-relay.js +125 -0
- package/dist/serve/ai-diagnostics-relay.js.map +1 -0
- package/dist/serve/ai-proxy.d.ts +92 -0
- package/dist/serve/ai-proxy.d.ts.map +1 -0
- package/dist/serve/ai-proxy.js +269 -0
- package/dist/serve/ai-proxy.js.map +1 -0
- package/dist/serve/ai-status.d.ts +44 -0
- package/dist/serve/ai-status.d.ts.map +1 -0
- package/dist/serve/ai-status.js +77 -0
- package/dist/serve/ai-status.js.map +1 -0
- package/dist/serve/ai-terminal-blocks.d.ts +97 -0
- package/dist/serve/ai-terminal-blocks.d.ts.map +1 -0
- package/dist/serve/ai-terminal-blocks.js +128 -0
- package/dist/serve/ai-terminal-blocks.js.map +1 -0
- package/dist/serve/ai-terminal-text.d.ts +36 -0
- package/dist/serve/ai-terminal-text.d.ts.map +1 -0
- package/dist/serve/ai-terminal-text.js +48 -0
- package/dist/serve/ai-terminal-text.js.map +1 -0
- package/dist/serve/beacon-route.d.ts +53 -0
- package/dist/serve/beacon-route.d.ts.map +1 -0
- package/dist/serve/beacon-route.js +101 -0
- package/dist/serve/beacon-route.js.map +1 -0
- package/dist/serve/bundler.js +10 -10
- package/dist/serve/bundler.js.map +1 -1
- package/dist/serve/entries/active-auth-registry.d.ts +16 -0
- package/dist/serve/entries/active-auth-registry.d.ts.map +1 -0
- package/dist/serve/entries/active-auth-registry.js +48 -0
- package/dist/serve/entries/active-auth-registry.js.map +1 -0
- package/dist/serve/entries/active-auth.d.ts +18 -0
- package/dist/serve/entries/active-auth.d.ts.map +1 -0
- package/dist/serve/entries/active-auth.js +84 -0
- package/dist/serve/entries/active-auth.js.map +1 -0
- package/dist/serve/entries/ai.d.ts.map +1 -1
- package/dist/serve/entries/ai.js +27 -1
- package/dist/serve/entries/ai.js.map +1 -1
- package/dist/serve/entries/auth-helper-core.d.ts +1 -0
- package/dist/serve/entries/auth-helper-core.d.ts.map +1 -1
- package/dist/serve/entries/auth-helper-core.js +4 -0
- package/dist/serve/entries/auth-helper-core.js.map +1 -1
- package/dist/serve/entries/auth-helper-dom.d.ts.map +1 -1
- package/dist/serve/entries/auth-helper-dom.js +29 -3
- package/dist/serve/entries/auth-helper-dom.js.map +1 -1
- package/dist/serve/entries/auth-helper-runtime.js +1 -1
- package/dist/serve/entries/auth-helper-runtime.js.map +1 -1
- package/dist/serve/entries/auth.d.ts.map +1 -1
- package/dist/serve/entries/auth.js +8 -0
- package/dist/serve/entries/auth.js.map +1 -1
- package/dist/serve/entries/bridge-url.d.ts +1 -1
- package/dist/serve/entries/bridge-url.js +1 -1
- package/dist/serve/entries/firestore.js +3 -3
- package/dist/serve/entries/firestore.js.map +1 -1
- package/dist/serve/entries/init.d.ts.map +1 -1
- package/dist/serve/entries/init.js +70 -4
- package/dist/serve/entries/init.js.map +1 -1
- package/dist/serve/entries/keepalive.js +1 -1
- package/dist/serve/entries/keepalive.js.map +1 -1
- package/dist/serve/entries/runtime.d.ts.map +1 -1
- package/dist/serve/entries/runtime.js +30 -14
- package/dist/serve/entries/runtime.js.map +1 -1
- package/dist/serve/entries/storage.js +1 -1
- package/dist/serve/entries/storage.js.map +1 -1
- package/dist/serve/entries/worker-runtime.js +1 -1
- package/dist/serve/entries/worker-runtime.js.map +1 -1
- package/dist/serve/init-payload.d.ts +4 -0
- package/dist/serve/init-payload.d.ts.map +1 -1
- package/dist/serve/namespace.d.ts +20 -5
- package/dist/serve/namespace.d.ts.map +1 -1
- package/dist/serve/namespace.js +93 -129
- package/dist/serve/namespace.js.map +1 -1
- package/dist/serve/rules.d.ts.map +1 -1
- package/dist/serve/rules.js +44 -21
- package/dist/serve/rules.js.map +1 -1
- package/dist/serve/runtime/chip-config.d.ts.map +1 -1
- package/dist/serve/runtime/chip-config.js +16 -2
- package/dist/serve/runtime/chip-config.js.map +1 -1
- package/dist/serve/runtime/chip-dialog.d.ts +18 -0
- package/dist/serve/runtime/chip-dialog.d.ts.map +1 -0
- package/dist/serve/runtime/chip-dialog.js +315 -0
- package/dist/serve/runtime/chip-dialog.js.map +1 -0
- package/dist/serve/runtime/chip-install.d.ts +2 -0
- package/dist/serve/runtime/chip-install.d.ts.map +1 -1
- package/dist/serve/runtime/chip-install.js +9 -4
- package/dist/serve/runtime/chip-install.js.map +1 -1
- package/dist/serve/runtime/chip-user-search.d.ts +16 -0
- package/dist/serve/runtime/chip-user-search.d.ts.map +1 -0
- package/dist/serve/runtime/chip-user-search.js +354 -0
- package/dist/serve/runtime/chip-user-search.js.map +1 -0
- package/dist/serve/runtime/chip.d.ts +10 -0
- package/dist/serve/runtime/chip.d.ts.map +1 -1
- package/dist/serve/runtime/chip.js +149 -15
- package/dist/serve/runtime/chip.js.map +1 -1
- package/dist/serve/runtime/identity.d.ts +17 -0
- package/dist/serve/runtime/identity.d.ts.map +1 -0
- package/dist/serve/runtime/identity.js +10 -0
- package/dist/serve/runtime/identity.js.map +1 -0
- package/dist/serve/runtime/manifest.d.ts +1 -1
- package/dist/serve/runtime/manifest.d.ts.map +1 -1
- package/dist/serve/runtime/manifest.js +1 -1
- package/dist/serve/runtime/manifest.js.map +1 -1
- package/dist/serve/runtime/status.d.ts.map +1 -1
- package/dist/serve/runtime/status.js +23 -0
- package/dist/serve/runtime/status.js.map +1 -1
- package/dist/serve/sandbox-session.d.ts +8 -0
- package/dist/serve/sandbox-session.d.ts.map +1 -1
- package/dist/serve/sandbox-session.js +12 -4
- package/dist/serve/sandbox-session.js.map +1 -1
- package/dist/serve/server.d.ts +7 -0
- package/dist/serve/server.d.ts.map +1 -1
- package/dist/serve/server.js +15 -1
- package/dist/serve/server.js.map +1 -1
- package/dist/serve/site-ui/404.html +1 -1
- package/dist/serve/site-ui/_astro/{RulesCodeEditor.Bl-XMkhD.js → RulesCodeEditor.DsTAsKIa.js} +1 -1
- package/dist/serve/site-ui/_astro/_slug_.Da5VLhW1.css +1 -0
- package/dist/serve/site-ui/_astro/_studio_.BnfYCKoI.css +1 -0
- package/dist/serve/site-ui/_astro/app.BOr2kwae.js +115 -0
- package/dist/serve/site-ui/_astro/app.DhAcImFD.js +1 -0
- package/dist/serve/site-ui/_astro/app.pMSnN6Qw.css +1 -0
- package/dist/serve/site-ui/_astro/{chess-showcase.Dh5D8kqe.js → chess-showcase.Bn_pP6UJ.js} +2 -2
- package/dist/serve/site-ui/_astro/{example-runtime.CuyAjjiG.js → example-runtime.CXopTGv7.js} +1 -1
- package/dist/serve/site-ui/_astro/index.Tb-31efc.css +1 -0
- package/dist/serve/site-ui/_astro/index.UkCBr-_0.css +1 -0
- package/dist/serve/site-ui/_astro/sandbox-controls.rOuZTOUG.js +510 -0
- package/dist/serve/site-ui/_astro/{seed.CSUkloMi.js → seed.03a08f9t.js} +2 -2
- package/dist/serve/site-ui/_astro/writes.BsPBG3dp.js +653 -0
- package/dist/serve/site-ui/auth/index.html +5 -3
- package/dist/serve/site-ui/david-east.jpg +0 -0
- package/dist/serve/site-ui/docs/_rhythm/index.html +6 -3
- package/dist/serve/site-ui/docs/_rhythm.md +1 -1
- package/dist/serve/site-ui/docs/agent/set-up-your-agent/index.html +18 -15
- package/dist/serve/site-ui/docs/agent/set-up-your-agent.md +16 -16
- package/dist/serve/site-ui/docs/agent/watch-and-review/index.html +6 -5
- package/dist/serve/site-ui/docs/agent/watch-and-review.md +1 -5
- package/dist/serve/site-ui/docs/agent/work-with-an-agent/index.html +8 -5
- package/dist/serve/site-ui/docs/agent/work-with-an-agent.md +4 -4
- package/dist/serve/site-ui/docs/ai-compat/index.html +5 -2
- package/dist/serve/site-ui/docs/api-reference/index.html +13 -2
- package/dist/serve/site-ui/docs/api-reference.md +8 -0
- package/dist/serve/site-ui/docs/app-compat/index.html +5 -2
- package/dist/serve/site-ui/docs/auth-compat/index.html +7 -4
- package/dist/serve/site-ui/docs/auth-compat.md +2 -2
- package/dist/serve/site-ui/docs/build/ai-logic/index.html +10 -2
- package/dist/serve/site-ui/docs/build/ai-logic.md +6 -0
- package/dist/serve/site-ui/docs/build/authentication/index.html +7 -4
- package/dist/serve/site-ui/docs/build/authentication.md +2 -2
- package/dist/serve/site-ui/docs/build/cloud-firestore/index.html +5 -2
- package/dist/serve/site-ui/docs/build/cloud-messaging/index.html +5 -2
- package/dist/serve/site-ui/docs/build/cloud-storage/index.html +6 -3
- package/dist/serve/site-ui/docs/build/cloud-storage.md +1 -1
- package/dist/serve/site-ui/docs/build/realtime-database/index.html +9 -6
- package/dist/serve/site-ui/docs/build/realtime-database.md +4 -4
- package/dist/serve/site-ui/docs/conformance-scores/index.html +10 -3
- package/dist/serve/site-ui/docs/conformance-scores.md +5 -1
- package/dist/serve/site-ui/docs/create-pyric-reference-api/index.html +6 -3
- package/dist/serve/site-ui/docs/create-pyric-reference-api.md +1 -1
- package/dist/serve/site-ui/docs/database-compat/index.html +48 -45
- package/dist/serve/site-ui/docs/database-compat.md +43 -43
- package/dist/serve/site-ui/docs/examples/chess/index.html +5 -2
- package/dist/serve/site-ui/docs/examples/index.html +5 -2
- package/dist/serve/site-ui/docs/firestore-compat/index.html +8 -5
- package/dist/serve/site-ui/docs/firestore-compat.md +3 -3
- package/dist/serve/site-ui/docs/firestore-flutter-compat/index.html +319 -0
- package/dist/serve/site-ui/docs/firestore-flutter-compat.md +344 -0
- package/dist/serve/site-ui/docs/functions-rtdb-compat/index.html +5 -2
- package/dist/serve/site-ui/docs/get-started/backend-bundlers/index.html +105 -0
- package/dist/serve/site-ui/docs/get-started/backend-bundlers.md +165 -0
- package/dist/serve/site-ui/docs/get-started/how-the-swap-works/index.html +9 -6
- package/dist/serve/site-ui/docs/get-started/how-the-swap-works.md +5 -5
- package/dist/serve/site-ui/docs/get-started/nextjs/index.html +9 -6
- package/dist/serve/site-ui/docs/get-started/nextjs.md +4 -4
- package/dist/serve/site-ui/docs/get-started/start-building/index.html +14 -9
- package/dist/serve/site-ui/docs/get-started/start-building.md +16 -10
- package/dist/serve/site-ui/docs/get-started/vite/index.html +6 -3
- package/dist/serve/site-ui/docs/get-started/vite.md +1 -1
- package/dist/serve/site-ui/docs/index.json +3128 -1613
- package/dist/serve/site-ui/docs/messaging-compat/index.html +5 -2
- package/dist/serve/site-ui/docs/observe/resolve-runtime-status/index.html +5 -2
- package/dist/serve/site-ui/docs/observe/see-whats-happening/index.html +6 -4
- package/dist/serve/site-ui/docs/observe/see-whats-happening.md +2 -4
- package/dist/serve/site-ui/docs/observe/shape-your-data/index.html +9 -6
- package/dist/serve/site-ui/docs/observe/shape-your-data.md +4 -4
- package/dist/serve/site-ui/docs/overview/index.html +16 -10
- package/dist/serve/site-ui/docs/overview.md +19 -11
- package/dist/serve/site-ui/docs/pyric-admin-app-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-admin-auth-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-admin-database-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-admin-firestore-reference-api/index.html +8 -5
- package/dist/serve/site-ui/docs/pyric-admin-firestore-reference-api.md +3 -3
- package/dist/serve/site-ui/docs/pyric-admin-messaging-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-admin-reference-api/index.html +501 -0
- package/dist/serve/site-ui/docs/pyric-admin-reference-api.md +587 -0
- package/dist/serve/site-ui/docs/pyric-admin-storage-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-ai-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-ai-scripting-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-analytics-reference-api/index.html +124 -0
- package/dist/serve/site-ui/docs/pyric-analytics-reference-api.md +287 -0
- package/dist/serve/site-ui/docs/pyric-app-check-reference-api/index.html +87 -0
- package/dist/serve/site-ui/docs/pyric-app-check-reference-api.md +199 -0
- package/dist/serve/site-ui/docs/pyric-app-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-auth-reference-api/index.html +10 -3
- package/dist/serve/site-ui/docs/pyric-auth-reference-api.md +2 -1
- package/dist/serve/site-ui/docs/pyric-cli-assurance-browser-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-cli-assurance-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-cli-bridge-client-reference-api/index.html +6 -3
- package/dist/serve/site-ui/docs/pyric-cli-bridge-client-reference-api.md +1 -1
- package/dist/serve/site-ui/docs/pyric-cli-bridge-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-cli-bundler-reference-api/index.html +56 -0
- package/dist/serve/site-ui/docs/pyric-cli-bundler-reference-api.md +72 -0
- package/dist/serve/site-ui/docs/pyric-cli-conformance-browser-reference-api/index.html +6 -2
- package/dist/serve/site-ui/docs/pyric-cli-conformance-browser-reference-api.md +1 -0
- package/dist/serve/site-ui/docs/pyric-cli-conformance-docs-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-cli-conformance-reference-api/index.html +6 -2
- package/dist/serve/site-ui/docs/pyric-cli-conformance-reference-api.md +1 -0
- package/dist/serve/site-ui/docs/pyric-cli-credentials-node-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-cli-discover-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-cli-next-reference-api/index.html +6 -3
- package/dist/serve/site-ui/docs/pyric-cli-next-reference-api.md +1 -1
- package/dist/serve/site-ui/docs/pyric-cli-register-app-bridge-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-cli-register-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-cli-remote-reference-api/index.html +39 -11
- package/dist/serve/site-ui/docs/pyric-cli-remote-reference-api.md +17 -9
- package/dist/serve/site-ui/docs/pyric-cli-serve-worker-reference-api/index.html +137 -94
- package/dist/serve/site-ui/docs/pyric-cli-serve-worker-reference-api.md +61 -1
- package/dist/serve/site-ui/docs/pyric-cli-verify-reference-api/index.html +6 -3
- package/dist/serve/site-ui/docs/pyric-cli-verify-reference-api.md +1 -1
- package/dist/serve/site-ui/docs/pyric-cli-vite-reference-api/index.html +6 -3
- package/dist/serve/site-ui/docs/pyric-cli-vite-reference-api.md +2 -2
- package/dist/serve/site-ui/docs/pyric-database-reference-api/index.html +167 -96
- package/dist/serve/site-ui/docs/pyric-database-reference-api.md +108 -2
- package/dist/serve/site-ui/docs/pyric-firestore-lite-reference-api/index.html +559 -0
- package/dist/serve/site-ui/docs/pyric-firestore-lite-reference-api.md +1240 -0
- package/dist/serve/site-ui/docs/pyric-firestore-reference-api/index.html +44 -12
- package/dist/serve/site-ui/docs/pyric-firestore-reference-api.md +18 -8
- package/dist/serve/site-ui/docs/pyric-functions-reference-api/index.html +67 -0
- package/dist/serve/site-ui/docs/pyric-functions-reference-api.md +149 -0
- package/dist/serve/site-ui/docs/pyric-messaging-reference-api/index.html +10 -4
- package/dist/serve/site-ui/docs/pyric-messaging-reference-api.md +5 -2
- package/dist/serve/site-ui/docs/pyric-messaging-sw-reference-api/index.html +10 -4
- package/dist/serve/site-ui/docs/pyric-messaging-sw-reference-api.md +5 -2
- package/dist/serve/site-ui/docs/pyric-performance-reference-api/index.html +35 -0
- package/dist/serve/site-ui/docs/pyric-performance-reference-api.md +69 -0
- package/dist/serve/site-ui/docs/pyric-remote-config-reference-api/index.html +132 -0
- package/dist/serve/site-ui/docs/pyric-remote-config-reference-api.md +307 -0
- package/dist/serve/site-ui/docs/pyric-rules-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-sandbox-database-reference-api/index.html +56 -18
- package/dist/serve/site-ui/docs/pyric-sandbox-database-reference-api.md +48 -9
- package/dist/serve/site-ui/docs/pyric-sandbox-firestore-reference-api/index.html +6 -3
- package/dist/serve/site-ui/docs/pyric-sandbox-firestore-reference-api.md +2 -2
- package/dist/serve/site-ui/docs/pyric-sandbox-reference-api/index.html +243 -50
- package/dist/serve/site-ui/docs/pyric-sandbox-reference-api.md +148 -31
- package/dist/serve/site-ui/docs/pyric-storage-reference-api/index.html +26 -5
- package/dist/serve/site-ui/docs/pyric-storage-reference-api.md +24 -2
- package/dist/serve/site-ui/docs/pyric-ui-agents-reference-api/index.html +30 -97
- package/dist/serve/site-ui/docs/pyric-ui-agents-reference-api.md +20 -51
- package/dist/serve/site-ui/docs/pyric-ui-auth-hooks-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-ui-auth-reference-api/index.html +6 -3
- package/dist/serve/site-ui/docs/pyric-ui-auth-reference-api.md +1 -1
- package/dist/serve/site-ui/docs/pyric-ui-events-hooks-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-ui-events-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-ui-firestore-hooks-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-ui-firestore-reference-api/index.html +6 -3
- package/dist/serve/site-ui/docs/pyric-ui-firestore-reference-api.md +1 -1
- package/dist/serve/site-ui/docs/pyric-ui-primitives-reference-api/index.html +128 -27
- package/dist/serve/site-ui/docs/pyric-ui-primitives-reference-api.md +58 -5
- package/dist/serve/site-ui/docs/pyric-ui-rtdb-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-ui-rules-hooks-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-ui-rules-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-ui-storage-hooks-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-ui-storage-reference-api/index.html +8 -6
- package/dist/serve/site-ui/docs/pyric-ui-storage-reference-api.md +3 -4
- package/dist/serve/site-ui/docs/pyric-ui-traffic-hooks-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-ui-traffic-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/reference/cli/index.html +156 -0
- package/dist/serve/site-ui/docs/reference/cli.md +120 -0
- package/dist/serve/site-ui/docs/rules-compat/index.html +14 -3
- package/dist/serve/site-ui/docs/rules-compat.md +9 -1
- package/dist/serve/site-ui/docs/secure/audit-your-rules/index.html +5 -2
- package/dist/serve/site-ui/docs/secure/firestore-rules-limits/index.html +5 -2
- package/dist/serve/site-ui/docs/secure/read-a-denial/index.html +6 -3
- package/dist/serve/site-ui/docs/secure/read-a-denial.md +1 -1
- package/dist/serve/site-ui/docs/secure/rtdb-rules-in-typescript/index.html +5 -2
- package/dist/serve/site-ui/docs/secure/rules-standard-library/index.html +5 -2
- package/dist/serve/site-ui/docs/secure/secure-it-with-rules/index.html +5 -2
- package/dist/serve/site-ui/docs/secure/simulate-and-lint/index.html +5 -2
- package/dist/serve/site-ui/docs/secure/write-a-rules-test-suite/index.html +5 -2
- package/dist/serve/site-ui/docs/ship/ship-to-production/index.html +7 -4
- package/dist/serve/site-ui/docs/ship/ship-to-production.md +2 -2
- package/dist/serve/site-ui/docs/ship/test-in-node/index.html +9 -6
- package/dist/serve/site-ui/docs/ship/test-in-node.md +4 -4
- package/dist/serve/site-ui/docs/storage-compat/index.html +17 -14
- package/dist/serve/site-ui/docs/storage-compat.md +12 -12
- package/dist/serve/site-ui/docs/trust/how-we-know-it-matches-firebase/index.html +5 -2
- package/dist/serve/site-ui/docs/trust/rules-standard-library/index.html +5 -2
- package/dist/serve/site-ui/docs/trust/versioning-and-compatibility/index.html +5 -2
- package/dist/serve/site-ui/docs/tutorial/index.html +10 -7
- package/dist/serve/site-ui/docs/tutorial.md +4 -4
- package/dist/serve/site-ui/examples/chess/index.html +4 -2
- package/dist/serve/site-ui/firestore/index.html +5 -3
- package/dist/serve/site-ui/hero-charcoal.jpg +0 -0
- package/dist/serve/site-ui/index.html +9 -7
- package/dist/serve/site-ui/llms.txt +13 -3
- package/dist/serve/site-ui/pyric-campfire-full.png +0 -0
- package/dist/serve/site-ui/pyric-campfire.png +0 -0
- package/dist/serve/site-ui/rtdb/index.html +5 -3
- package/dist/serve/site-ui/settings/index.html +5 -3
- package/dist/serve/site-ui/storage/index.html +5 -3
- package/dist/serve/site-ui/studio/index.html +13 -0
- package/dist/serve/site-ui/studio-routes.json +1 -1
- package/dist/serve/site-ui/traffic/index.html +5 -3
- package/dist/serve/studio/disk-workspace.d.ts.map +1 -1
- package/dist/serve/studio/disk-workspace.js +64 -2
- package/dist/serve/studio/disk-workspace.js.map +1 -1
- package/dist/serve/studio/routes.d.ts +9 -0
- package/dist/serve/studio/routes.d.ts.map +1 -1
- package/dist/serve/studio/routes.js +47 -7
- package/dist/serve/studio/routes.js.map +1 -1
- package/dist/serve/vite-ai-config.d.ts.map +1 -1
- package/dist/serve/vite-ai-config.js +38 -8
- package/dist/serve/vite-ai-config.js.map +1 -1
- package/dist/serve/vite-module-swap.d.ts.map +1 -1
- package/dist/serve/vite-module-swap.js +0 -28
- package/dist/serve/vite-module-swap.js.map +1 -1
- package/dist/serve/vite-plugin.d.ts +7 -7
- package/dist/serve/vite-plugin.js +1 -1
- package/dist/serve/vite-plugin.js.map +1 -1
- package/dist/serve/vite-sandbox-generation.d.ts +1 -1
- package/dist/serve/vite-sandbox-generation.d.ts.map +1 -1
- package/dist/serve/vite-sandbox-generation.js +13 -1
- package/dist/serve/vite-sandbox-generation.js.map +1 -1
- package/dist/serve/worker/client/auth.js +1 -2
- package/dist/serve/worker/client/auth.js.map +1 -1
- package/dist/serve/worker/client/core.d.ts +21 -1
- package/dist/serve/worker/client/core.d.ts.map +1 -1
- package/dist/serve/worker/client/core.js +79 -3
- package/dist/serve/worker/client/core.js.map +1 -1
- package/dist/serve/worker/client/disconnect.js +1 -1
- package/dist/serve/worker/client/disconnect.js.map +1 -1
- package/dist/serve/worker/client/presence.d.ts.map +1 -1
- package/dist/serve/worker/client/presence.js +18 -5
- package/dist/serve/worker/client/presence.js.map +1 -1
- package/dist/serve/worker/client.d.ts +1 -1
- package/dist/serve/worker/client.d.ts.map +1 -1
- package/dist/serve/worker/client.js +1 -1
- package/dist/serve/worker/client.js.map +1 -1
- package/dist/serve/worker/context-resolver.d.ts +30 -0
- package/dist/serve/worker/context-resolver.d.ts.map +1 -0
- package/dist/serve/worker/context-resolver.js +44 -0
- package/dist/serve/worker/context-resolver.js.map +1 -0
- package/dist/serve/worker/entry.js +23 -19
- package/dist/serve/worker/entry.js.map +1 -1
- package/dist/serve/worker/host/core.d.ts +1 -0
- package/dist/serve/worker/host/core.d.ts.map +1 -1
- package/dist/serve/worker/host/core.js +12 -6
- package/dist/serve/worker/host/core.js.map +1 -1
- package/dist/serve/worker/host/storage.js +2 -2
- package/dist/serve/worker/host-ai.d.ts.map +1 -1
- package/dist/serve/worker/host-ai.js +15 -0
- package/dist/serve/worker/host-ai.js.map +1 -1
- package/dist/serve/worker/host-auth.js +1 -2
- package/dist/serve/worker/host-auth.js.map +1 -1
- package/dist/serve/worker/index.d.ts +1 -1
- package/dist/serve/worker/index.d.ts.map +1 -1
- package/dist/serve/worker/index.js +2 -2
- package/dist/serve/worker/index.js.map +1 -1
- package/dist/serve/worker/port-lifecycle.d.ts +18 -0
- package/dist/serve/worker/port-lifecycle.d.ts.map +1 -0
- package/dist/serve/worker/port-lifecycle.js +28 -0
- package/dist/serve/worker/port-lifecycle.js.map +1 -0
- package/dist/serve/worker/protocol.d.ts +4 -0
- package/dist/serve/worker/protocol.d.ts.map +1 -1
- package/dist/serve/worker/protocol.js.map +1 -1
- package/dist/serve/worker/serve-init.d.ts.map +1 -1
- package/dist/serve/worker/serve-init.js +15 -3
- package/dist/serve/worker/serve-init.js.map +1 -1
- package/dist/verify/fixture.d.ts +1 -1
- package/package.json +17 -6
- package/src/assurance/.generated/conformance-verdicts.ts +68 -1
- package/src/bridge/client/dispatch.ts +52 -56
- package/src/bridge/client/tool-family-factories.ts +34 -0
- package/src/bridge/server/mcp-contract.ts +15 -59
- package/src/bridge/server/peer.ts +24 -1
- package/src/bridge/server/tool-family-factories.ts +40 -0
- package/src/bridge/server/tool-metadata.ts +29 -61
- package/src/bridge/tool-families.generated.ts +17 -0
- package/src/bridge/tool-families.ts +87 -0
- package/src/bridge/tool-family-records/conformance.ts +6 -0
- package/src/bridge/tool-family-records/firestore-data.ts +15 -0
- package/src/bridge/tool-family-records/firestore-inspect.ts +6 -0
- package/src/bridge/tool-family-records/firestore-rules.ts +15 -0
- package/src/bridge/tool-family-records/firestore-simulator.ts +16 -0
- package/src/bridge/tool-family-records/rtdb-inspection.ts +6 -0
- package/src/bundler/externals.ts +55 -0
- package/src/bundler/index.ts +21 -0
- package/src/cli/cli.test.ts +2 -46
- package/src/cli/index.ts +48 -42
- package/src/cli/inlined-sdk-scanner.ts +77 -0
- package/src/cli/mcp-proxy.ts +4 -4
- package/src/cli/parse-args.ts +61 -15
- package/src/cli/pyric-config.ts +45 -0
- package/src/cli/sandbox-interlock.ts +167 -0
- package/src/cli/{dev-runner.ts → sandbox-runner.ts} +142 -86
- package/src/cli/serve.ts +182 -115
- package/src/cli/snapshot.ts +5 -5
- package/src/cli/unsupported-runtime.ts +68 -0
- package/src/cli/verify.ts +1 -1
- package/src/conformance/.generated/can-i-use-browser.ts +2 -2
- package/src/conformance/.generated/can-i-use.ts +2 -2
- package/src/conformance/.generated/conformance-docs.ts +1 -1
- package/src/functions-rtdb/child.ts +115 -21
- package/src/functions-rtdb/development-runtime.ts +5 -1
- package/src/functions-rtdb/project.ts +8 -8
- package/src/google-endpoints.ts +155 -0
- package/src/next/guard.ts +1 -1
- package/src/next/runtime-env.ts +5 -0
- package/src/next/with-pyric.ts +1 -1
- package/src/register/beacon.ts +232 -0
- package/src/register/index.ts +68 -6
- package/src/register/net-guard.ts +567 -0
- package/src/remote/index.ts +9 -9
- package/src/serve/ai-diagnostics-relay.ts +243 -0
- package/src/serve/ai-proxy.ts +327 -0
- package/src/serve/ai-status.ts +109 -0
- package/src/serve/ai-terminal-blocks.ts +210 -0
- package/src/serve/ai-terminal-text.ts +52 -0
- package/src/serve/beacon-route.ts +141 -0
- package/src/serve/bundler.ts +10 -10
- package/src/serve/entries/active-auth-registry.ts +56 -0
- package/src/serve/entries/active-auth.ts +100 -0
- package/src/serve/entries/ai.ts +27 -1
- package/src/serve/entries/auth-helper-core.ts +5 -0
- package/src/serve/entries/auth-helper-dom.ts +27 -3
- package/src/serve/entries/auth-helper-runtime.ts +1 -1
- package/src/serve/entries/auth.ts +8 -0
- package/src/serve/entries/bridge-url.ts +1 -1
- package/src/serve/entries/firestore.ts +3 -3
- package/src/serve/entries/init.ts +78 -3
- package/src/serve/entries/keepalive.ts +1 -1
- package/src/serve/entries/runtime.ts +29 -14
- package/src/serve/entries/storage.ts +1 -1
- package/src/serve/entries/worker-runtime.ts +1 -1
- package/src/serve/init-payload.ts +4 -0
- package/src/serve/namespace.ts +117 -145
- package/src/serve/rules.ts +47 -22
- package/src/serve/runtime/chip-config.ts +16 -2
- package/src/serve/runtime/chip-dialog.ts +366 -0
- package/src/serve/runtime/chip-install.ts +10 -4
- package/src/serve/runtime/chip-user-search.ts +391 -0
- package/src/serve/runtime/chip.ts +177 -15
- package/src/serve/runtime/identity.ts +26 -0
- package/src/serve/runtime/manifest.ts +1 -1
- package/src/serve/runtime/status.ts +24 -0
- package/src/serve/sandbox-session.ts +19 -4
- package/src/serve/server.ts +18 -1
- package/src/serve/studio/disk-workspace.ts +76 -2
- package/src/serve/studio/routes.ts +63 -7
- package/src/serve/vite-ai-config.ts +37 -7
- package/src/serve/vite-module-swap.ts +0 -28
- package/src/serve/vite-plugin.ts +8 -8
- package/src/serve/vite-sandbox-generation.ts +16 -1
- package/src/serve/worker/client/auth.ts +1 -1
- package/src/serve/worker/client/core.ts +80 -3
- package/src/serve/worker/client/disconnect.ts +1 -1
- package/src/serve/worker/client/presence.ts +25 -5
- package/src/serve/worker/client.ts +1 -1
- package/src/serve/worker/context-resolver.ts +60 -0
- package/src/serve/worker/entry.ts +22 -18
- package/src/serve/worker/host/core.ts +9 -7
- package/src/serve/worker/host/storage.ts +2 -2
- package/src/serve/worker/host-ai.ts +15 -0
- package/src/serve/worker/host-auth.ts +1 -1
- package/src/serve/worker/index.ts +4 -1
- package/src/serve/worker/port-lifecycle.ts +45 -0
- package/src/serve/worker/protocol.ts +2 -1
- package/src/serve/worker/serve-init.ts +14 -3
- package/src/verify/fixture.ts +1 -1
- package/README.md.orig +0 -145
- package/dist/cli/dev-runner.d.ts.map +0 -1
- package/dist/cli/dev-runner.js.map +0 -1
- package/dist/serve/site-ui/_astro/_slug_.CXh9yTP1.css +0 -1
- package/dist/serve/site-ui/_astro/_slug_.CupVK4TM.css +0 -1
- package/dist/serve/site-ui/_astro/_studio_.CfxiQWkk.css +0 -1
- package/dist/serve/site-ui/_astro/app.BsFsMjn0.css +0 -1
- package/dist/serve/site-ui/_astro/app.Ce3MTLQm.js +0 -1
- package/dist/serve/site-ui/_astro/app.taqzyjD0.js +0 -11
- package/dist/serve/site-ui/_astro/sandbox-controls.BP4M5f1M.js +0 -1169
- package/dist/serve/site-ui/_astro/writes.C57paAj2.js +0 -99
- package/dist/serve/site-ui/docs/trust/storage-rules-stdlib-research/index.html +0 -582
- package/dist/serve/site-ui/docs/trust/storage-rules-stdlib-research.md +0 -448
package/src/serve/namespace.ts
CHANGED
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
* the injected init script + shared chunks)
|
|
7
7
|
* /__pyric/init.json the page init payload (rules, bridge URL) —
|
|
8
8
|
* fetched by the runtime chunk at module init
|
|
9
|
+
* /__pyric/beacon the handshake beacon a pyric-launched child
|
|
10
|
+
* POSTs once its interception is installed
|
|
9
11
|
*
|
|
10
12
|
* Bridge routes (`/__pyric/mcp`, `/__pyric/sandbox`) mount here in P2.
|
|
11
13
|
*/
|
|
@@ -18,10 +20,14 @@ import { collectBody } from '../bridge/server/peer.js';
|
|
|
18
20
|
import { StateFileError, type StateSection, type StateStore } from './state-store.js';
|
|
19
21
|
import { createWriterLock, type WriterLock } from './writer-lock.js';
|
|
20
22
|
import { createStudioRoutes, type StudioRouteOptions } from './studio/index.js';
|
|
21
|
-
import { pipeFileToResponse, type ServeLogger } from './server.js';
|
|
23
|
+
import { pipeFileToResponse, getHeader, isAllowedHost, isAllowedOrigin, type ServeLogger } from './server.js';
|
|
22
24
|
import type { InitPayload } from './init-payload.js';
|
|
23
25
|
import { handleActivity } from './activity-route.js';
|
|
26
|
+
import { handleAiProxy, AI_PROXY_ROUTE } from './ai-proxy.js';
|
|
27
|
+
import { aiTerminalBlockFor, type AiDiagnosticPayload } from './ai-terminal-blocks.js';
|
|
24
28
|
import { createSiteTreeHandler } from './site-tree.js';
|
|
29
|
+
import { BEACON_PATH, type BeaconReport } from '../register/beacon.js';
|
|
30
|
+
import { handleBeacon } from './beacon-route.js';
|
|
25
31
|
export type { InitPayload } from './init-payload.js';
|
|
26
32
|
|
|
27
33
|
/**
|
|
@@ -107,144 +113,34 @@ export interface NamespaceOptions {
|
|
|
107
113
|
* (disk-backed `WorkspaceStore`/`ProjectStore`, plus the SSE watch stream)
|
|
108
114
|
* that `@pyric/studio`'s `local` mode talks to. */
|
|
109
115
|
studio?: StudioRouteOptions;
|
|
116
|
+
/** Per-boot session capability token required on workspace and project endpoints. */
|
|
117
|
+
sessionToken?: string;
|
|
118
|
+
/** Bound host for DNS rebinding guard. */
|
|
119
|
+
boundHost?: string;
|
|
120
|
+
/** Extra allowed hostnames. */
|
|
121
|
+
allowedHosts?: string[];
|
|
110
122
|
/** The OpenAI-compatible upstream `/__pyric/ai-proxy` forwards to
|
|
111
123
|
* (pyric/ai — cdd-deltas #98.2). Falls back to the
|
|
112
124
|
* `PYRIC_AI_PROXY_UPSTREAM` env var, then `http://localhost:11434/v1`
|
|
113
125
|
* (local Ollama). Always mounted — the route only touches the network
|
|
114
126
|
* when a request arrives. */
|
|
115
127
|
aiProxyUpstream?: string;
|
|
116
|
-
/**
|
|
117
|
-
*
|
|
118
|
-
*
|
|
128
|
+
/** Receives one handshake beacon per pyric-launched child (`POST
|
|
129
|
+
* /__pyric/beacon`, sent by `@pyric/cli/register` once its hooks and
|
|
130
|
+
* net-guard are installed). Absent means the route still 204s; the child
|
|
131
|
+
* must never be able to fail on its own proof-of-life. */
|
|
132
|
+
beacon?: (report: BeaconReport) => void;
|
|
133
|
+
/** The per-launch secret a beacon must present in `x-pyric-beacon-token`,
|
|
134
|
+
* which the launcher puts in the child's `PYRIC_BEACON_TOKEN`. Absent means
|
|
135
|
+
* one is generated that nobody holds, so the route accepts nothing. */
|
|
136
|
+
beaconToken?: string;
|
|
137
|
+
/** Where hot-reload/diagnostic lines print (rules reload, denial relay,
|
|
138
|
+
* AI broker diagnostics, ai-proxy upstream failures). Absent ⇒ diagnostics
|
|
139
|
+
* are dropped (a caller that wires no logger opts out silently rather than
|
|
140
|
+
* falling back to raw `console`). */
|
|
119
141
|
logger?: ServeLogger;
|
|
120
142
|
}
|
|
121
143
|
|
|
122
|
-
// ─── AI proxy (`/__pyric/ai-proxy` — pyric/ai, cdd-deltas #98.2) ───────────
|
|
123
|
-
|
|
124
|
-
/** Default upstream: local Ollama's OpenAI-compatible endpoint. */
|
|
125
|
-
export const AI_PROXY_DEFAULT_UPSTREAM = 'http://localhost:11434/v1';
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* Request headers that must NOT be forwarded upstream: origin-sensitive
|
|
129
|
-
* browser context (`origin`/`referer`/`cookie` — the upstream is a different
|
|
130
|
-
* origin and must never see the page's), hop-by-hop headers, and the two the
|
|
131
|
-
* proxy re-derives (`host`, `content-length`). `accept-encoding` is dropped
|
|
132
|
-
* so fetch negotiates its own compression and the streamed body needs no
|
|
133
|
-
* length fixups.
|
|
134
|
-
*/
|
|
135
|
-
const AI_PROXY_STRIPPED_HEADERS = new Set([
|
|
136
|
-
'host',
|
|
137
|
-
'origin',
|
|
138
|
-
'referer',
|
|
139
|
-
'cookie',
|
|
140
|
-
'connection',
|
|
141
|
-
'content-length',
|
|
142
|
-
'accept-encoding',
|
|
143
|
-
'keep-alive',
|
|
144
|
-
'proxy-authorization',
|
|
145
|
-
'te',
|
|
146
|
-
'trailer',
|
|
147
|
-
'transfer-encoding',
|
|
148
|
-
'upgrade',
|
|
149
|
-
]);
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* Handle `POST /__pyric/ai-proxy/<suffix>` — a same-origin passthrough to the
|
|
153
|
-
* configured OpenAI-compatible upstream, so the browser openai engine
|
|
154
|
-
* (running in the served page or the SharedWorker host) reaches a localhost
|
|
155
|
-
* upstream like Ollama with ZERO CORS setup (no `OLLAMA_ORIGINS`, ever).
|
|
156
|
-
*
|
|
157
|
-
* Behavior:
|
|
158
|
-
* - POST only (the OpenAI chat-completions surface is POST); 405 otherwise.
|
|
159
|
-
* - the path suffix + query ride through verbatim
|
|
160
|
-
* (`/__pyric/ai-proxy/chat/completions` → `<upstream>/chat/completions`).
|
|
161
|
-
* - the request body is forwarded verbatim; headers minus the
|
|
162
|
-
* origin-sensitive/hop-by-hop set above (`authorization` DOES forward —
|
|
163
|
-
* upstreams may require a key).
|
|
164
|
-
* - the response body is STREAMED through chunk-by-chunk — SSE passthrough
|
|
165
|
-
* must never buffer, or `stream: true` completions would arrive all at
|
|
166
|
-
* once at the end.
|
|
167
|
-
* - an unreachable upstream answers 502 with a plain-text explanation.
|
|
168
|
-
*/
|
|
169
|
-
async function handleAiProxy(
|
|
170
|
-
configuredUpstream: string | undefined,
|
|
171
|
-
req: IncomingMessage,
|
|
172
|
-
res: ServerResponse,
|
|
173
|
-
url: URL,
|
|
174
|
-
): Promise<void> {
|
|
175
|
-
if (req.method !== 'POST') {
|
|
176
|
-
res.writeHead(405, { allow: 'POST' }).end('method not allowed');
|
|
177
|
-
return;
|
|
178
|
-
}
|
|
179
|
-
const upstreamBase = (
|
|
180
|
-
configuredUpstream ??
|
|
181
|
-
process.env.PYRIC_AI_PROXY_UPSTREAM ??
|
|
182
|
-
AI_PROXY_DEFAULT_UPSTREAM
|
|
183
|
-
).replace(/\/$/, '');
|
|
184
|
-
const suffix = url.pathname.slice('/__pyric/ai-proxy'.length);
|
|
185
|
-
const target = `${upstreamBase}${suffix}${url.search}`;
|
|
186
|
-
|
|
187
|
-
// Buffer the REQUEST body (small JSON payloads); the RESPONSE streams.
|
|
188
|
-
const raw = await new Promise<Buffer>((resolve, reject) => {
|
|
189
|
-
const chunks: Buffer[] = [];
|
|
190
|
-
req.on('data', (c: Buffer) => chunks.push(c));
|
|
191
|
-
req.on('end', () => resolve(Buffer.concat(chunks)));
|
|
192
|
-
req.on('error', reject);
|
|
193
|
-
});
|
|
194
|
-
// Copy into a plain-ArrayBuffer view — fetch's BodyInit typing rejects
|
|
195
|
-
// Buffer's ArrayBufferLike backing.
|
|
196
|
-
const body = new Uint8Array(raw.byteLength);
|
|
197
|
-
body.set(raw);
|
|
198
|
-
|
|
199
|
-
const headers: Record<string, string> = {};
|
|
200
|
-
for (const [key, value] of Object.entries(req.headers)) {
|
|
201
|
-
if (value === undefined) continue;
|
|
202
|
-
if (AI_PROXY_STRIPPED_HEADERS.has(key.toLowerCase())) continue;
|
|
203
|
-
headers[key] = Array.isArray(value) ? value.join(', ') : value;
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
let upstream: Response;
|
|
207
|
-
try {
|
|
208
|
-
upstream = await fetch(target, { method: 'POST', headers, body });
|
|
209
|
-
} catch (e) {
|
|
210
|
-
res.writeHead(502, { 'content-type': 'text/plain' });
|
|
211
|
-
res.end(
|
|
212
|
-
`pyric dev ai-proxy: upstream ${target} unreachable: ` +
|
|
213
|
-
`${e instanceof Error ? e.message : String(e)}\n` +
|
|
214
|
-
'Set PYRIC_AI_PROXY_UPSTREAM to an OpenAI-compatible base URL ' +
|
|
215
|
-
`(default ${AI_PROXY_DEFAULT_UPSTREAM}).`,
|
|
216
|
-
);
|
|
217
|
-
return;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
const responseHeaders: Record<string, string> = { 'cache-control': 'no-store' };
|
|
221
|
-
const contentType = upstream.headers.get('content-type');
|
|
222
|
-
if (contentType) responseHeaders['content-type'] = contentType;
|
|
223
|
-
res.writeHead(upstream.status, responseHeaders);
|
|
224
|
-
if (!upstream.body) {
|
|
225
|
-
res.end();
|
|
226
|
-
return;
|
|
227
|
-
}
|
|
228
|
-
(res as ServerResponse & { flushHeaders?: () => void }).flushHeaders?.();
|
|
229
|
-
|
|
230
|
-
// Chunk-by-chunk passthrough. A dropped client cancels the upstream read
|
|
231
|
-
// so an abandoned SSE stream doesn't keep the upstream generating.
|
|
232
|
-
const reader = upstream.body.getReader();
|
|
233
|
-
res.on('close', () => {
|
|
234
|
-
void reader.cancel().catch(() => {});
|
|
235
|
-
});
|
|
236
|
-
try {
|
|
237
|
-
for (;;) {
|
|
238
|
-
const { done, value } = await reader.read();
|
|
239
|
-
if (done) break;
|
|
240
|
-
res.write(value);
|
|
241
|
-
}
|
|
242
|
-
} catch {
|
|
243
|
-
// Upstream or client dropped mid-stream — nothing to salvage.
|
|
244
|
-
}
|
|
245
|
-
res.end();
|
|
246
|
-
}
|
|
247
|
-
|
|
248
144
|
/** The page's persistence backend speaks this route:
|
|
249
145
|
* GET /__pyric/state → whole envelope (404 when absent)
|
|
250
146
|
* GET /__pyric/state?section=firestore → that section (404 when null)
|
|
@@ -384,6 +280,18 @@ async function handleCapture(
|
|
|
384
280
|
// An agent driving `pyric dev` headlessly has no browser console to watch;
|
|
385
281
|
// this is that visibility, printed to the terminal instead.
|
|
386
282
|
//
|
|
283
|
+
// The route carries the AI broker's diagnostics on the same channel, relayed
|
|
284
|
+
// by `serve/ai-diagnostics-relay.ts` off the sandbox event stream:
|
|
285
|
+
// `request_rejected` (a malformed request) and `response_blocked` (a safety
|
|
286
|
+
// or recitation filter withheld the answer). Same category ("the sandbox
|
|
287
|
+
// refused your operation"), same terminal treatment, same throttle, so they
|
|
288
|
+
// ride here rather than opening parallel diagnostics channels.
|
|
289
|
+
// `model_substituted` (an engine answered as a model the code never named)
|
|
290
|
+
// rides along too: not a refusal, but the same "the sandbox quietly did
|
|
291
|
+
// something else" category. The payload's `kind` discriminates the four, and
|
|
292
|
+
// `ai-terminal-blocks.ts` holds one record per AI kind so this route
|
|
293
|
+
// dispatches through a table instead of a cascade.
|
|
294
|
+
//
|
|
387
295
|
// A denied listener re-fires on every auth/rules change, so printing is
|
|
388
296
|
// throttled per (path, message) pair — at most one line per window, and
|
|
389
297
|
// silent (no output at all) on suppression rather than a "suppressed N more"
|
|
@@ -443,9 +351,21 @@ export function formatDenialBlock(payload: DenialRelayPayload): string {
|
|
|
443
351
|
return lines.join('\n');
|
|
444
352
|
}
|
|
445
353
|
|
|
446
|
-
/**
|
|
447
|
-
*
|
|
448
|
-
*
|
|
354
|
+
/**
|
|
355
|
+
* The throttle key separator: a NUL byte, written as an escape so the file
|
|
356
|
+
* stays greppable. It cannot occur in a Firestore path, a model id, or a
|
|
357
|
+
* rejection reason, so no (target, reason) pair can be spelled two ways.
|
|
358
|
+
*/
|
|
359
|
+
const THROTTLE_KEY_SEPARATOR = '\x00';
|
|
360
|
+
|
|
361
|
+
/** Handle `POST /__pyric/denials`: a rules denial, or (discriminated by
|
|
362
|
+
* `kind`) an AI broker rejection, blocked response, or model substitution
|
|
363
|
+
* relayed off the sandbox event stream. All four share the throttle map: an
|
|
364
|
+
* agent retry loop re-sends the SAME malformed (or filter-tripping) AI
|
|
365
|
+
* request exactly the way a denied listener re-fires, so one line per
|
|
366
|
+
* (target, reason) per window is the right volume for every one of them.
|
|
367
|
+
* Always 204s (best-effort diagnostics: a malformed body or a caller with no
|
|
368
|
+
* logger wired must never fail the page that reported the refusal). */
|
|
449
369
|
async function handleDenials(
|
|
450
370
|
throttle: DenialThrottle,
|
|
451
371
|
logger: ServeLogger | undefined,
|
|
@@ -457,22 +377,48 @@ async function handleDenials(
|
|
|
457
377
|
return;
|
|
458
378
|
}
|
|
459
379
|
try {
|
|
460
|
-
const payload = (await collectBody(req)) as DenialRelayPayload;
|
|
461
|
-
const
|
|
462
|
-
|
|
463
|
-
|
|
380
|
+
const payload = (await collectBody(req)) as DenialRelayPayload & AiDiagnosticPayload;
|
|
381
|
+
const aiBlock = aiTerminalBlockFor(payload.kind);
|
|
382
|
+
let target: string;
|
|
383
|
+
let reason: string;
|
|
384
|
+
let render: () => string;
|
|
385
|
+
if (aiBlock === null) {
|
|
386
|
+
target = payload.denialContext?.request?.path ?? '';
|
|
387
|
+
reason = typeof payload.message === 'string' ? payload.message : 'permission denied';
|
|
388
|
+
render = () => formatDenialBlock(payload);
|
|
389
|
+
} else {
|
|
390
|
+
target = aiBlock.throttleTarget(payload);
|
|
391
|
+
reason = aiBlock.throttleReason(payload);
|
|
392
|
+
render = () => aiBlock.format(payload);
|
|
393
|
+
}
|
|
394
|
+
const key = `${target}${THROTTLE_KEY_SEPARATOR}${reason}`;
|
|
464
395
|
if (logger && throttle.shouldPrint(key, Date.now())) {
|
|
465
|
-
logger.note(
|
|
396
|
+
logger.note(render());
|
|
466
397
|
}
|
|
467
398
|
} catch {
|
|
468
|
-
/* malformed body
|
|
399
|
+
/* malformed body: drop it; this is a diagnostics side channel */
|
|
469
400
|
}
|
|
470
401
|
res.writeHead(204).end();
|
|
471
402
|
}
|
|
472
403
|
|
|
473
404
|
export function createPyricNamespace(opts: NamespaceOptions) {
|
|
474
|
-
const
|
|
475
|
-
const
|
|
405
|
+
const stateWriterLock = createWriterLock();
|
|
406
|
+
const studioWriterLock = opts.studio?.writerLock ?? createWriterLock();
|
|
407
|
+
const sessionToken = opts.sessionToken ?? randomBytes(24).toString('base64url');
|
|
408
|
+
// Fail closed: with no launcher-supplied secret the generated one is held by
|
|
409
|
+
// nobody, so `/__pyric/beacon` accepts nothing rather than everything.
|
|
410
|
+
const beaconToken = opts.beaconToken ?? randomBytes(24).toString('base64url');
|
|
411
|
+
let studioRoutes: ((req: IncomingMessage, res: ServerResponse, url: URL) => Promise<boolean>) | null = null;
|
|
412
|
+
if (opts.studio) {
|
|
413
|
+
const studioOptions: StudioRouteOptions = {
|
|
414
|
+
...opts.studio,
|
|
415
|
+
sessionToken,
|
|
416
|
+
writerLock: studioWriterLock,
|
|
417
|
+
boundHost: opts.boundHost,
|
|
418
|
+
allowedHosts: opts.allowedHosts,
|
|
419
|
+
};
|
|
420
|
+
studioRoutes = createStudioRoutes(studioOptions);
|
|
421
|
+
}
|
|
476
422
|
const siteTree = opts.siteUiDir
|
|
477
423
|
? createSiteTreeHandler(opts.siteUiDir, opts.workerVersion)
|
|
478
424
|
: null;
|
|
@@ -489,7 +435,7 @@ export function createPyricNamespace(opts: NamespaceOptions) {
|
|
|
489
435
|
return studioRoutes(req, res, url);
|
|
490
436
|
}
|
|
491
437
|
if (opts.state && url.pathname === '/__pyric/state') {
|
|
492
|
-
return handleState(opts.state!,
|
|
438
|
+
return handleState(opts.state!, stateWriterLock, req, res, url).then(() => true);
|
|
493
439
|
}
|
|
494
440
|
if (opts.capture && url.pathname === '/__pyric/capture') {
|
|
495
441
|
return handleCapture(opts.capture, req, res).then(() => true);
|
|
@@ -498,18 +444,44 @@ export function createPyricNamespace(opts: NamespaceOptions) {
|
|
|
498
444
|
return handleActivity(opts.activity, req, res, activityToken!).then(() => true);
|
|
499
445
|
}
|
|
500
446
|
if (opts.events && url.pathname === '/__pyric/events') {
|
|
447
|
+
const hostHeader = getHeader(req, 'host');
|
|
448
|
+
const originHeader = getHeader(req, 'origin');
|
|
449
|
+
if (!isAllowedHost(hostHeader, opts.boundHost ?? 'localhost', opts.allowedHosts)) {
|
|
450
|
+
res.writeHead(403, { 'content-type': 'text/plain' }).end('Forbidden: host not allowed');
|
|
451
|
+
return true;
|
|
452
|
+
}
|
|
453
|
+
if (originHeader && !isAllowedOrigin(originHeader, opts.boundHost ?? 'localhost', opts.allowedHosts)) {
|
|
454
|
+
res.writeHead(403, { 'content-type': 'text/plain' }).end('Forbidden: origin mismatch');
|
|
455
|
+
return true;
|
|
456
|
+
}
|
|
457
|
+
const reqToken = getHeader(req, 'x-pyric-session-token') ?? url.searchParams.get('token');
|
|
458
|
+
if (sessionToken && reqToken && reqToken !== sessionToken) {
|
|
459
|
+
res.writeHead(401, { 'content-type': 'text/plain' }).end('Unauthorized: invalid session capability token');
|
|
460
|
+
return true;
|
|
461
|
+
}
|
|
501
462
|
opts.events.handle(req, res);
|
|
502
463
|
return true;
|
|
503
464
|
}
|
|
504
|
-
if (url.pathname ===
|
|
505
|
-
return handleAiProxy(opts.aiProxyUpstream, req, res, url).then(
|
|
465
|
+
if (url.pathname === AI_PROXY_ROUTE || url.pathname.startsWith(`${AI_PROXY_ROUTE}/`)) {
|
|
466
|
+
return handleAiProxy(opts.aiProxyUpstream, denialThrottle, req, res, url, opts.logger).then(
|
|
467
|
+
() => true,
|
|
468
|
+
);
|
|
469
|
+
}
|
|
470
|
+
if (url.pathname === BEACON_PATH) {
|
|
471
|
+
return handleBeacon({ token: beaconToken, onBeacon: opts.beacon }, req, res).then(() => true);
|
|
506
472
|
}
|
|
507
473
|
if (url.pathname === '/__pyric/denials') {
|
|
508
474
|
return handleDenials(denialThrottle, opts.logger, req, res).then(() => true);
|
|
509
475
|
}
|
|
510
476
|
if (url.pathname === '/__pyric/init.json') {
|
|
511
477
|
res.writeHead(200, { 'content-type': 'application/json; charset=utf-8', 'cache-control': 'no-store' });
|
|
512
|
-
res.end(
|
|
478
|
+
res.end(
|
|
479
|
+
JSON.stringify({
|
|
480
|
+
...opts.initPayload(),
|
|
481
|
+
sessionToken,
|
|
482
|
+
...(activityToken ? { activityToken } : {}),
|
|
483
|
+
}),
|
|
484
|
+
);
|
|
513
485
|
return true;
|
|
514
486
|
}
|
|
515
487
|
if (url.pathname.startsWith('/__pyric/sdk/')) {
|
package/src/serve/rules.ts
CHANGED
|
@@ -56,7 +56,7 @@ export function prepareRulesSource(raw: string, sourcePath: string): string {
|
|
|
56
56
|
const resolved = resolveModulesBrowser(raw);
|
|
57
57
|
if (!resolved.success) {
|
|
58
58
|
throw new Error(
|
|
59
|
-
`pyric
|
|
59
|
+
`pyric sandbox: ${sourcePath} uses 2+modules but module resolution failed: ${resolved.error.message}`,
|
|
60
60
|
);
|
|
61
61
|
}
|
|
62
62
|
source = resolved.data.resolved;
|
|
@@ -65,13 +65,13 @@ export function prepareRulesSource(raw: string, sourcePath: string): string {
|
|
|
65
65
|
if (lint.parseError) {
|
|
66
66
|
const { line, column } = lint.parseError;
|
|
67
67
|
throw new Error(
|
|
68
|
-
`pyric
|
|
68
|
+
`pyric sandbox: ${sourcePath} failed to parse (line ${line}, col ${column}). Fix the rules before serving.`,
|
|
69
69
|
);
|
|
70
70
|
}
|
|
71
71
|
const errors = lint.warnings.filter((w) => w.severity === 'error');
|
|
72
72
|
if (errors.length > 0) {
|
|
73
73
|
throw new Error(
|
|
74
|
-
`pyric
|
|
74
|
+
`pyric sandbox: ${sourcePath} has ${errors.length} rules error(s):\n` +
|
|
75
75
|
errors.map((e) => ` - ${e.message}`).join('\n'),
|
|
76
76
|
);
|
|
77
77
|
}
|
|
@@ -98,7 +98,7 @@ export async function loadProjectRules(
|
|
|
98
98
|
} catch (e) {
|
|
99
99
|
if ((e as NodeJS.ErrnoException).code === 'ENOENT') {
|
|
100
100
|
if (configured) {
|
|
101
|
-
throw new Error(`pyric
|
|
101
|
+
throw new Error(`pyric sandbox: firebase.json points firestore.rules at ${path}, but it does not exist.`);
|
|
102
102
|
}
|
|
103
103
|
return { rules: null, rulesHash: null, sourcePath: null };
|
|
104
104
|
}
|
|
@@ -119,7 +119,7 @@ export function prepareStorageRulesSource(raw: string, sourcePath: string): stri
|
|
|
119
119
|
const resolved = resolveModulesBrowser(raw, { sourceFile: sourcePath });
|
|
120
120
|
if (!resolved.success) {
|
|
121
121
|
throw new Error(
|
|
122
|
-
`pyric
|
|
122
|
+
`pyric sandbox: ${sourcePath} uses 2+modules but module resolution failed: ${resolved.error.message}`,
|
|
123
123
|
);
|
|
124
124
|
}
|
|
125
125
|
source = resolved.data.resolved;
|
|
@@ -128,7 +128,7 @@ export function prepareStorageRulesSource(raw: string, sourcePath: string): stri
|
|
|
128
128
|
parseStorageRules(source);
|
|
129
129
|
} catch (e) {
|
|
130
130
|
throw new Error(
|
|
131
|
-
`pyric
|
|
131
|
+
`pyric sandbox: ${sourcePath} failed to parse: ${e instanceof Error ? e.message : String(e)}. Fix the rules before serving.`,
|
|
132
132
|
);
|
|
133
133
|
}
|
|
134
134
|
return source;
|
|
@@ -159,7 +159,7 @@ export async function loadProjectStorageRules(
|
|
|
159
159
|
} catch (e) {
|
|
160
160
|
if ((e as NodeJS.ErrnoException).code === 'ENOENT') {
|
|
161
161
|
if (configured) {
|
|
162
|
-
throw new Error(`pyric
|
|
162
|
+
throw new Error(`pyric sandbox: firebase.json points storage.rules at ${path}, but it does not exist.`);
|
|
163
163
|
}
|
|
164
164
|
return { rules: null, rulesHash: null, sourcePath: null };
|
|
165
165
|
}
|
|
@@ -169,27 +169,52 @@ export async function loadProjectStorageRules(
|
|
|
169
169
|
return { rules, rulesHash: rulesHashOf(rules), sourcePath: path };
|
|
170
170
|
}
|
|
171
171
|
|
|
172
|
+
function normalizeDatabaseEntries(block: unknown): Array<Record<string, unknown>> {
|
|
173
|
+
if (!block) {
|
|
174
|
+
return [];
|
|
175
|
+
}
|
|
176
|
+
if (Array.isArray(block)) {
|
|
177
|
+
return block.filter((item): item is Record<string, unknown> => typeof item === 'object' && item !== null);
|
|
178
|
+
}
|
|
179
|
+
if (typeof block === 'object' && block !== null) {
|
|
180
|
+
return [block as Record<string, unknown>];
|
|
181
|
+
}
|
|
182
|
+
return [];
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function hasConfiguredRules(entry: Record<string, unknown>): entry is Record<string, unknown> & { rules: string } {
|
|
186
|
+
return typeof entry.rules === 'string';
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
function hasConfiguredUrl(entry: Record<string, unknown>): entry is Record<string, unknown> & { url: string } {
|
|
190
|
+
return typeof entry.url === 'string';
|
|
191
|
+
}
|
|
192
|
+
|
|
172
193
|
export async function loadProjectDatabaseRules(
|
|
173
194
|
cwd: string,
|
|
174
195
|
config: FirebaseJson | null,
|
|
175
196
|
): Promise<LoadedDatabaseRules> {
|
|
176
|
-
const
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
};
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
const path = isAbsolute(configured) ? configured : join(cwd, configured);
|
|
197
|
+
const entries = normalizeDatabaseEntries(config?.database);
|
|
198
|
+
const configuredEntry = entries.find(hasConfiguredRules);
|
|
199
|
+
const configured = configuredEntry?.rules;
|
|
200
|
+
const rel = configured ?? 'database.rules.json';
|
|
201
|
+
const path = isAbsolute(rel) ? rel : join(cwd, rel);
|
|
202
|
+
const urlEntry = entries.find(hasConfiguredUrl);
|
|
203
|
+
const databaseUrl = urlEntry?.url ?? null;
|
|
187
204
|
let raw: string;
|
|
188
205
|
try {
|
|
189
206
|
raw = await readFile(path, 'utf8');
|
|
190
207
|
} catch (e) {
|
|
191
208
|
if ((e as NodeJS.ErrnoException).code === 'ENOENT') {
|
|
192
|
-
|
|
209
|
+
if (configured) {
|
|
210
|
+
throw new Error(`pyric sandbox: firebase.json points database.rules at ${path}, but it does not exist.`);
|
|
211
|
+
}
|
|
212
|
+
return {
|
|
213
|
+
rules: null,
|
|
214
|
+
rulesHash: null,
|
|
215
|
+
sourcePath: null,
|
|
216
|
+
databaseUrl,
|
|
217
|
+
};
|
|
193
218
|
}
|
|
194
219
|
throw e;
|
|
195
220
|
}
|
|
@@ -198,18 +223,18 @@ export async function loadProjectDatabaseRules(
|
|
|
198
223
|
try {
|
|
199
224
|
parsed = JSON.parse(stripJsonComments(raw));
|
|
200
225
|
} catch (e) {
|
|
201
|
-
throw new Error(`pyric
|
|
226
|
+
throw new Error(`pyric sandbox: ${path} failed to parse as RTDB rules JSON: ${e instanceof Error ? e.message : String(e)}`);
|
|
202
227
|
}
|
|
203
228
|
const rules = parseRtdbRulesJson(
|
|
204
229
|
parsed,
|
|
205
|
-
() => new Error(`pyric
|
|
230
|
+
() => new Error(`pyric sandbox: ${path} must contain a top-level "rules" object.`),
|
|
206
231
|
);
|
|
207
232
|
|
|
208
233
|
return {
|
|
209
234
|
rules,
|
|
210
235
|
rulesHash: rulesHashOf(raw),
|
|
211
236
|
sourcePath: path,
|
|
212
|
-
databaseUrl
|
|
237
|
+
databaseUrl,
|
|
213
238
|
};
|
|
214
239
|
}
|
|
215
240
|
|
|
@@ -17,8 +17,22 @@ interface RuntimeChipDocument {
|
|
|
17
17
|
querySelector(selector: string): { getAttribute(name: string): string | null } | null;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
/** Read the browser-inlined chip value, preferring the `NEXT_PUBLIC_`-prefixed
|
|
21
|
+
* name (the only one Next.js is guaranteed to expose to client bundles) and
|
|
22
|
+
* falling back to the unprefixed name for other bundlers/back-compat. */
|
|
23
|
+
function bundlerRuntimeChipValue(): string | undefined {
|
|
24
|
+
if (typeof process === 'undefined' || typeof process.env === 'undefined') return undefined;
|
|
25
|
+
if (typeof process.env.NEXT_PUBLIC_PYRIC_RUNTIME_CHIP === 'string') {
|
|
26
|
+
return process.env.NEXT_PUBLIC_PYRIC_RUNTIME_CHIP;
|
|
27
|
+
}
|
|
28
|
+
if (typeof process.env.PYRIC_RUNTIME_CHIP === 'string') {
|
|
29
|
+
return process.env.PYRIC_RUNTIME_CHIP;
|
|
30
|
+
}
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
|
|
20
34
|
function hasBundlerRuntimeChipConfig(): boolean {
|
|
21
|
-
return
|
|
35
|
+
return bundlerRuntimeChipValue() !== undefined;
|
|
22
36
|
}
|
|
23
37
|
|
|
24
38
|
/** Read plugin-authored values from DOM metadata or bundler environment variables, defaulting to collapsed UI when omitted. */
|
|
@@ -31,7 +45,7 @@ export function readPyricRuntimeChipConfig(
|
|
|
31
45
|
|
|
32
46
|
const shouldFallbackToEnv = !hasMetaTag && hasBundlerRuntimeChipConfig();
|
|
33
47
|
if (shouldFallbackToEnv) {
|
|
34
|
-
value =
|
|
48
|
+
value = bundlerRuntimeChipValue() as string;
|
|
35
49
|
}
|
|
36
50
|
if (value === 'off') {
|
|
37
51
|
return null;
|