@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
|
@@ -1,8 +1,20 @@
|
|
|
1
|
+
import type { AuthLens } from 'pyric/sandbox';
|
|
1
2
|
import type {
|
|
2
3
|
PyricRuntimeError,
|
|
3
4
|
PyricRuntimeSnapshot,
|
|
4
5
|
PyricRuntimeStatus,
|
|
5
6
|
} from './status.js';
|
|
7
|
+
import {
|
|
8
|
+
createChipDialogController,
|
|
9
|
+
DIALOG_STYLES,
|
|
10
|
+
type ChipDialogController,
|
|
11
|
+
} from './chip-dialog.js';
|
|
12
|
+
import type { RuntimeIdentity, RuntimeIdentityBindings } from './identity.js';
|
|
13
|
+
import {
|
|
14
|
+
getLens as defaultGetLens,
|
|
15
|
+
setLens as defaultSetLens,
|
|
16
|
+
subscribeLens as defaultSubscribeLens,
|
|
17
|
+
} from '../worker/client/core.js';
|
|
6
18
|
|
|
7
19
|
export interface PyricRuntimeChipOptions {
|
|
8
20
|
runtime: PyricRuntimeStatus;
|
|
@@ -11,6 +23,14 @@ export interface PyricRuntimeChipOptions {
|
|
|
11
23
|
initiallyOpen?: boolean;
|
|
12
24
|
/** Override Studio availability. Omitted uses the runtime manifest URL. */
|
|
13
25
|
studioUrl?: string | null;
|
|
26
|
+
/** Optional identity integration. Missing operations use lens/no-op fallbacks. */
|
|
27
|
+
identity?: Partial<RuntimeIdentityBindings>;
|
|
28
|
+
/** Injectable lens getter (defaults to worker client getLens). */
|
|
29
|
+
getLens?: () => AuthLens | undefined;
|
|
30
|
+
/** Injectable lens setter (defaults to worker client setLens). */
|
|
31
|
+
setLens?: (lens: AuthLens | undefined) => void;
|
|
32
|
+
/** Injectable lens subscription (defaults to worker client subscribeLens). */
|
|
33
|
+
subscribeLens?: (listener: (lens: AuthLens | undefined) => void) => () => void;
|
|
14
34
|
}
|
|
15
35
|
|
|
16
36
|
export interface PyricRuntimeChip {
|
|
@@ -18,6 +38,32 @@ export interface PyricRuntimeChip {
|
|
|
18
38
|
dispose(): void;
|
|
19
39
|
}
|
|
20
40
|
|
|
41
|
+
interface AiEngineDisplay {
|
|
42
|
+
primary: string;
|
|
43
|
+
subline: string | null;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function aiEngineState(): AiEngineDisplay {
|
|
47
|
+
const engine = (globalThis as { __PYRIC_AI_ENGINE__?: { kind?: string; model?: string } }).__PYRIC_AI_ENGINE__;
|
|
48
|
+
if (engine?.kind === 'gemini') {
|
|
49
|
+
return {
|
|
50
|
+
primary: 'gemini (production)',
|
|
51
|
+
subline: 'gemini-3.5-flash-lite → gemini-flash-lite-latest',
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
if (engine?.kind === 'openai') {
|
|
55
|
+
const modelLabel = engine.model ? ` (${engine.model})` : '';
|
|
56
|
+
return {
|
|
57
|
+
primary: `openai (proxy${modelLabel})`,
|
|
58
|
+
subline: null,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
primary: 'sandbox (scripted)',
|
|
63
|
+
subline: null,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
21
67
|
const styles = `
|
|
22
68
|
:host {
|
|
23
69
|
--pyric-bg: #1e1e24;
|
|
@@ -63,9 +109,14 @@ const styles = `
|
|
|
63
109
|
.brand-label { font-size: 11px; }
|
|
64
110
|
.signals { color: var(--pyric-muted); font-size: 10px; gap: 8px; }
|
|
65
111
|
.signal { gap: 4px; white-space: nowrap; }
|
|
112
|
+
.signal[data-identity-badge] {
|
|
113
|
+
max-width: 140px;
|
|
114
|
+
overflow: hidden;
|
|
115
|
+
text-overflow: ellipsis;
|
|
116
|
+
}
|
|
66
117
|
.dot { background: var(--pyric-accent); border-radius: 50%; height: 8px; width: 8px; }
|
|
67
|
-
.dot.error { background: var(--pyric-error); box-shadow: 0 0 0 3px rgba(240,160,160,.12); }
|
|
68
118
|
.signal.update { color: var(--pyric-warning); }
|
|
119
|
+
.signal.bypass { color: #8f7fe8; font-weight: 500; }
|
|
69
120
|
.chevron { color: var(--pyric-muted); height: 14px; width: 14px; }
|
|
70
121
|
.panel {
|
|
71
122
|
background: var(--pyric-bg);
|
|
@@ -86,8 +137,11 @@ const styles = `
|
|
|
86
137
|
.icon-button[data-copy-failed] { color: var(--pyric-error); }
|
|
87
138
|
.icon { height: 15px; width: 15px; }
|
|
88
139
|
.worker-state { border-top: 1px solid var(--pyric-border-soft); color: var(--pyric-muted); font-size: 10px; justify-content: space-between; min-height: 34px; padding: 7px 12px; }
|
|
140
|
+
.worker-state-col { border-top: 1px solid var(--pyric-border-soft); color: var(--pyric-muted); font-size: 10px; display: flex; flex-direction: column; min-height: 34px; padding: 7px 12px; }
|
|
141
|
+
.worker-state-row { align-items: center; display: flex; justify-content: space-between; width: 100%; }
|
|
142
|
+
.worker-state-subline { color: #89899f; font: 9px/1.4 ui-monospace, monospace; margin-top: 4px; overflow-wrap: anywhere; text-align: right; width: 100%; }
|
|
89
143
|
.worker-state .available { color: var(--pyric-warning); }
|
|
90
|
-
.worker-state .state-label { align-items: center; display: flex; gap: 7px; }
|
|
144
|
+
.worker-state .state-label, .worker-state-col .state-label { align-items: center; display: flex; gap: 7px; white-space: nowrap; }
|
|
91
145
|
.mini-dot { background: var(--pyric-accent); border-radius: 50%; height: 6px; width: 6px; }
|
|
92
146
|
.available .mini-dot { background: var(--pyric-warning); }
|
|
93
147
|
.epochs { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
@@ -104,7 +158,7 @@ const styles = `
|
|
|
104
158
|
.error-body code { color: #d7d7df; display: block; font-size: 11px; line-height: 1.55; overflow-wrap: anywhere; white-space: pre-wrap; }
|
|
105
159
|
.error-meta { color: var(--pyric-muted); font: 9px/1.4 ui-monospace, monospace; margin-top: 4px; overflow-wrap: anywhere; }
|
|
106
160
|
.empty { align-items: center; color: var(--pyric-muted); display: flex; font: 11px/1.5 ui-monospace, monospace; min-height: 57px; padding: 12px; }
|
|
107
|
-
.actions { display: grid; gap: 8px; grid-template-columns:
|
|
161
|
+
.actions { display: grid; gap: 8px; grid-template-columns: repeat(3, 1fr); min-height: 56px; padding: 10px 12px; }
|
|
108
162
|
.button { align-items: center; background: transparent; border: 1px solid var(--pyric-border-soft); border-radius: 4px; color: var(--pyric-muted); display: inline-flex; font-size: 10px; justify-content: center; letter-spacing: .06em; min-height: 34px; padding: 6px 8px; text-decoration: none; text-transform: uppercase; }
|
|
109
163
|
button.button { cursor: pointer; }
|
|
110
164
|
.button:hover:not(:disabled):not([aria-disabled="true"]), a.button:hover { border-color: #3a3a48; color: var(--pyric-text); }
|
|
@@ -121,6 +175,8 @@ const styles = `
|
|
|
121
175
|
.chip, .panel { animation: pyric-enter 120ms ease-out; transform-origin: bottom right; }
|
|
122
176
|
@keyframes pyric-enter { from { opacity: 0; transform: translateY(4px) scale(.98); } }
|
|
123
177
|
}
|
|
178
|
+
|
|
179
|
+
${DIALOG_STYLES}
|
|
124
180
|
`;
|
|
125
181
|
|
|
126
182
|
const icons = {
|
|
@@ -132,7 +188,7 @@ const icons = {
|
|
|
132
188
|
};
|
|
133
189
|
|
|
134
190
|
function escapeAttribute(value: string): string {
|
|
135
|
-
return value.replaceAll('&', '&').replaceAll('"', '"').replaceAll('<', '<');
|
|
191
|
+
return value.replaceAll('&', '&').replaceAll('"', '"').replaceAll('<', '<').replaceAll('>', '>');
|
|
136
192
|
}
|
|
137
193
|
|
|
138
194
|
export function formatPyricRuntimeError(error: PyricRuntimeError): string {
|
|
@@ -160,7 +216,19 @@ function renderErrors(snapshot: PyricRuntimeSnapshot, canCopy: boolean): string
|
|
|
160
216
|
/** Mount the framework-independent runtime chip in an isolated shadow root. */
|
|
161
217
|
export function mountPyricRuntimeChip(options: PyricRuntimeChipOptions): PyricRuntimeChip {
|
|
162
218
|
const documentLike = options.document ?? document;
|
|
163
|
-
const
|
|
219
|
+
const existingHost = documentLike.querySelector<HTMLElement>(
|
|
220
|
+
'[data-pyric-runtime-chip-host], pyric-runtime-chip',
|
|
221
|
+
);
|
|
222
|
+
if (existingHost) {
|
|
223
|
+
existingHost.remove();
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
let host: HTMLElement;
|
|
227
|
+
try {
|
|
228
|
+
host = documentLike.createElement('pyric-runtime-chip');
|
|
229
|
+
} catch {
|
|
230
|
+
host = documentLike.createElement('div');
|
|
231
|
+
}
|
|
164
232
|
host.setAttribute('data-pyric-runtime-chip-host', '');
|
|
165
233
|
const root = host.attachShadow({ mode: 'open' });
|
|
166
234
|
root.innerHTML = `<style>${styles}</style><div class="announcer" role="status" aria-live="polite" aria-atomic="true"></div><div data-view></div>`;
|
|
@@ -174,6 +242,50 @@ export function mountPyricRuntimeChip(options: PyricRuntimeChipOptions): PyricRu
|
|
|
174
242
|
let open = options.initiallyOpen ?? false;
|
|
175
243
|
let snapshot = options.runtime.getSnapshot();
|
|
176
244
|
|
|
245
|
+
const getLensFn = options.getLens ?? defaultGetLens;
|
|
246
|
+
const setLensFn = options.setLens ?? defaultSetLens;
|
|
247
|
+
const subscribeLensFn = options.subscribeLens ?? defaultSubscribeLens;
|
|
248
|
+
const providedIdentity = options.identity;
|
|
249
|
+
let clientUser: RuntimeIdentity | null = null;
|
|
250
|
+
const readCurrentUser = (): RuntimeIdentity | null => {
|
|
251
|
+
if (providedIdentity?.getCurrentUser) return providedIdentity.getCurrentUser();
|
|
252
|
+
return clientUser;
|
|
253
|
+
};
|
|
254
|
+
clientUser = readCurrentUser();
|
|
255
|
+
|
|
256
|
+
const identity: RuntimeIdentityBindings = {
|
|
257
|
+
listUsers: providedIdentity?.listUsers ?? (() => []),
|
|
258
|
+
switchUser: async (uid) => {
|
|
259
|
+
if (providedIdentity?.switchUser) await providedIdentity.switchUser(uid);
|
|
260
|
+
else setLensFn({ mode: 'as', uid });
|
|
261
|
+
clientUser = readCurrentUser();
|
|
262
|
+
render();
|
|
263
|
+
},
|
|
264
|
+
signOut: async () => {
|
|
265
|
+
if (providedIdentity?.signOut) await providedIdentity.signOut();
|
|
266
|
+
else setLensFn(undefined);
|
|
267
|
+
clientUser = null;
|
|
268
|
+
render();
|
|
269
|
+
},
|
|
270
|
+
openCreateUser: providedIdentity?.openCreateUser ?? (() => {}),
|
|
271
|
+
getCurrentUser: readCurrentUser,
|
|
272
|
+
subscribeAuth: providedIdentity?.subscribeAuth ?? (() => () => {}),
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
const dialogController: ChipDialogController = createChipDialogController({
|
|
276
|
+
shadowRoot: root,
|
|
277
|
+
identity,
|
|
278
|
+
onToggleAdminBypass: (enable) => {
|
|
279
|
+
if (enable) {
|
|
280
|
+
setLensFn({ mode: 'admin' });
|
|
281
|
+
} else {
|
|
282
|
+
setLensFn(undefined);
|
|
283
|
+
}
|
|
284
|
+
render();
|
|
285
|
+
},
|
|
286
|
+
getLens: () => getLensFn(),
|
|
287
|
+
});
|
|
288
|
+
|
|
177
289
|
const render = (next = snapshot): void => {
|
|
178
290
|
const active = root.activeElement;
|
|
179
291
|
const oldViewport = view.querySelector<HTMLElement>('[data-error-viewport]');
|
|
@@ -184,7 +296,7 @@ export function mountPyricRuntimeChip(options: PyricRuntimeChipOptions): PyricRu
|
|
|
184
296
|
}
|
|
185
297
|
: null;
|
|
186
298
|
const activeCopyId = active?.getAttribute('data-copy-error');
|
|
187
|
-
const activeControl = ['data-expand', 'data-collapse', 'data-update-worker', 'data-open-studio']
|
|
299
|
+
const activeControl = ['data-expand', 'data-collapse', 'data-update-worker', 'data-open-studio', 'data-open-impersonate']
|
|
188
300
|
.find((attribute) => active?.hasAttribute(attribute));
|
|
189
301
|
const focusToken = activeCopyId !== null && activeCopyId !== undefined
|
|
190
302
|
? { attribute: 'data-copy-error', value: activeCopyId }
|
|
@@ -199,33 +311,60 @@ export function mountPyricRuntimeChip(options: PyricRuntimeChipOptions): PyricRu
|
|
|
199
311
|
? 'Sandbox starting'
|
|
200
312
|
: snapshot.mode === 'in-page'
|
|
201
313
|
? 'In-page sandbox'
|
|
202
|
-
: 'Worker
|
|
314
|
+
: 'Worker version';
|
|
203
315
|
const epochs = snapshot.updateAvailable
|
|
204
316
|
? `${snapshot.runningEpoch?.slice(0, 8) ?? 'unknown'} → ${snapshot.servedEpoch?.slice(0, 8) ?? 'unknown'}`
|
|
205
317
|
: snapshot.runningEpoch?.slice(0, 8) ?? '';
|
|
318
|
+
const aiState = aiEngineState();
|
|
319
|
+
|
|
320
|
+
const lens = getLensFn();
|
|
321
|
+
const user = readCurrentUser();
|
|
322
|
+
const isAdmin = lens?.mode === 'admin';
|
|
323
|
+
const activeUid = lens?.mode === 'as' ? lens.uid : user?.uid;
|
|
324
|
+
|
|
325
|
+
const identitySignals: string[] = [];
|
|
326
|
+
let identityStateHtml = '<span class="epochs" data-identity-state>App session</span>';
|
|
327
|
+
if (activeUid) {
|
|
328
|
+
identitySignals.push(`<span class="signal" data-identity-badge title="as: ${escapeAttribute(activeUid)}">as: ${escapeAttribute(activeUid)}</span>`);
|
|
329
|
+
identityStateHtml = `<span class="epochs" data-identity-state data-identity-badge title="as: ${escapeAttribute(activeUid)}">as: ${escapeAttribute(activeUid)}</span>`;
|
|
330
|
+
}
|
|
331
|
+
if (isAdmin) {
|
|
332
|
+
identitySignals.push('<span class="signal bypass" data-identity-badge>bypass rules</span>');
|
|
333
|
+
}
|
|
334
|
+
const identitySignalHtml = identitySignals.join('');
|
|
206
335
|
|
|
207
336
|
view.innerHTML = `${open ? `
|
|
208
|
-
<section class="panel" role="dialog" aria-label="
|
|
337
|
+
<section class="panel" role="dialog" aria-label="pyric">
|
|
209
338
|
<header class="panel-header">
|
|
210
|
-
<div class="panel-title"><span class="brand-mark">>_</span><strong>
|
|
339
|
+
<div class="panel-title"><span class="brand-mark">>_</span><strong>pyric</strong>${errorCount > 0 ? `<span class="count">${errorCount} ${errorCount === 1 ? 'error' : 'errors'}</span><button class="clear-button" type="button" data-clear-errors aria-label="Clear all errors">Clear</button>` : ''}</div>
|
|
211
340
|
<div class="panel-controls">
|
|
212
|
-
<button class="icon-button" type="button" data-collapse aria-label="Minimize
|
|
213
|
-
<button class="icon-button" type="button" data-dismiss-chip aria-label="Dismiss
|
|
341
|
+
<button class="icon-button" type="button" data-collapse aria-label="Minimize pyric">${icons.minimize}</button>
|
|
342
|
+
<button class="icon-button" type="button" data-dismiss-chip aria-label="Dismiss pyric from page">${icons.close}</button>
|
|
214
343
|
</div>
|
|
215
344
|
</header>
|
|
216
|
-
<div class="worker-state"><span class="state-label${snapshot.updateAvailable ? ' available' : ''}"
|
|
345
|
+
<div class="worker-state"><span class="state-label${snapshot.updateAvailable ? ' available' : ''}">${workerLabel}</span><span class="epochs">${epochs}</span></div>
|
|
346
|
+
<div class="worker-state-col" data-ai-status>
|
|
347
|
+
<div class="worker-state-row">
|
|
348
|
+
<span class="state-label">AI engine</span>
|
|
349
|
+
<span class="epochs">${aiState.primary}</span>
|
|
350
|
+
</div>
|
|
351
|
+
${aiState.subline ? `<div class="worker-state-subline">${aiState.subline}</div>` : ''}
|
|
352
|
+
</div>
|
|
353
|
+
<div class="worker-state"><span class="state-label">Rules</span><span class="epochs" style="${isAdmin ? 'color: #8f7fe8; font-weight: 500;' : ''}">${isAdmin ? 'bypassed' : 'enforced'}</span></div>
|
|
354
|
+
<div class="worker-state"><span class="state-label">Identity</span>${identityStateHtml}</div>
|
|
217
355
|
<div class="errors" data-error-viewport>${renderErrors(snapshot, Boolean(clipboard))}</div>
|
|
218
356
|
<div class="actions">
|
|
219
357
|
<button class="button update" type="button" data-update-worker ${snapshot.updateAvailable ? '' : 'disabled'} aria-disabled="${snapshot.updateAvailable && !snapshot.updatingWorker ? 'false' : 'true'}">${snapshot.updatingWorker ? 'Updating…' : 'Update worker'}</button>
|
|
358
|
+
<button class="button" type="button" data-open-impersonate>Identity</button>
|
|
220
359
|
${studioUrl
|
|
221
360
|
? `<a class="button" data-open-studio href="${escapeAttribute(studioUrl)}" target="_blank" rel="noopener noreferrer">Studio${icons.external}</a>`
|
|
222
361
|
: `<span class="button" data-open-studio aria-disabled="true" title="Pyric Studio is disabled">Studio${icons.external}</span>`}
|
|
223
362
|
</div>
|
|
224
363
|
</section>
|
|
225
364
|
` : `
|
|
226
|
-
<button class="chip" type="button" data-expand aria-label="Open
|
|
227
|
-
<span class="brand"><span class="dot${errorCount > 0 ? ' error' : ''}"></span><span class="brand-label">
|
|
228
|
-
<span class="signals">${snapshot.updateAvailable ? '<span class="signal update">update</span>' : ''}${errorCount > 0 ? `<span class="signal">${errorCount} ${errorCount === 1 ? 'error' : 'errors'}</span>` : '
|
|
365
|
+
<button class="chip" type="button" data-expand aria-label="Open pyric" aria-expanded="false">
|
|
366
|
+
<span class="brand"><span class="dot${errorCount > 0 ? ' error' : ''}"></span><span class="brand-label">pyric</span></span>
|
|
367
|
+
<span class="signals">${identitySignalHtml}${snapshot.updateAvailable ? '<span class="signal update">update</span>' : ''}${errorCount > 0 ? `<span class="signal">${errorCount} ${errorCount === 1 ? 'error' : 'errors'}</span>` : ''}${icons.chevron}</span>
|
|
229
368
|
</button>
|
|
230
369
|
`}`;
|
|
231
370
|
|
|
@@ -265,6 +404,9 @@ export function mountPyricRuntimeChip(options: PyricRuntimeChipOptions): PyricRu
|
|
|
265
404
|
if (!snapshot.updateAvailable || snapshot.updatingWorker) return;
|
|
266
405
|
void options.runtime.updateWorker().catch(() => { /* status records and renders the failure */ });
|
|
267
406
|
});
|
|
407
|
+
root.querySelector('[data-open-impersonate]')?.addEventListener('click', (e) => {
|
|
408
|
+
void dialogController.open(e.currentTarget as HTMLElement);
|
|
409
|
+
});
|
|
268
410
|
for (const button of root.querySelectorAll<HTMLButtonElement>('[data-copy-error]')) {
|
|
269
411
|
button.addEventListener('click', () => {
|
|
270
412
|
const error = snapshot.errors.find((item) => item.id === button.dataset.copyError);
|
|
@@ -292,11 +434,31 @@ export function mountPyricRuntimeChip(options: PyricRuntimeChipOptions): PyricRu
|
|
|
292
434
|
};
|
|
293
435
|
|
|
294
436
|
documentLike.body.append(host);
|
|
437
|
+
const reattachAfterAstroSwap = (): void => {
|
|
438
|
+
if (!host.isConnected) documentLike.body.append(host);
|
|
439
|
+
};
|
|
440
|
+
documentLike.addEventListener('astro:after-swap', reattachAfterAstroSwap);
|
|
295
441
|
const unsubscribe = options.runtime.subscribe(render);
|
|
442
|
+
|
|
443
|
+
const unsubLens = subscribeLensFn(() => {
|
|
444
|
+
render();
|
|
445
|
+
});
|
|
446
|
+
|
|
447
|
+
const unsubAuth = identity.subscribeAuth((user) => {
|
|
448
|
+
clientUser = user;
|
|
449
|
+
render();
|
|
450
|
+
});
|
|
451
|
+
|
|
452
|
+
render();
|
|
453
|
+
|
|
296
454
|
return {
|
|
297
455
|
element: host,
|
|
298
456
|
dispose() {
|
|
299
457
|
unsubscribe();
|
|
458
|
+
unsubLens();
|
|
459
|
+
unsubAuth();
|
|
460
|
+
documentLike.removeEventListener('astro:after-swap', reattachAfterAstroSwap);
|
|
461
|
+
dialogController.dispose();
|
|
300
462
|
host.remove();
|
|
301
463
|
},
|
|
302
464
|
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { AuthUserRecord } from 'pyric/auth';
|
|
2
|
+
|
|
3
|
+
export interface RuntimeIdentity {
|
|
4
|
+
uid: string;
|
|
5
|
+
email?: string | null;
|
|
6
|
+
displayName?: string | null;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/** The chip's complete identity integration seam, passed intact through mounting. */
|
|
10
|
+
export interface RuntimeIdentityBindings {
|
|
11
|
+
listUsers(): Promise<AuthUserRecord[]> | AuthUserRecord[];
|
|
12
|
+
switchUser(uid: string): Promise<void> | void;
|
|
13
|
+
signOut(): Promise<void> | void;
|
|
14
|
+
openCreateUser(): void;
|
|
15
|
+
getCurrentUser(): RuntimeIdentity | null;
|
|
16
|
+
subscribeAuth(listener: (user: RuntimeIdentity | null) => void): () => void;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function projectRuntimeIdentity(user: RuntimeIdentity | null | undefined): RuntimeIdentity | null {
|
|
20
|
+
if (!user) return null;
|
|
21
|
+
return {
|
|
22
|
+
uid: user.uid,
|
|
23
|
+
email: user.email,
|
|
24
|
+
displayName: user.displayName,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/** Stable routes and identity used by the served runtime and its UI. */
|
|
2
2
|
export const PYRIC_WORKER_URL = '/__pyric/sdk/worker.js';
|
|
3
3
|
export const PYRIC_WORKER_NAME = 'pyric-shared-worker';
|
|
4
|
-
export const PYRIC_STUDIO_URL = '/__pyric/ui/';
|
|
4
|
+
export const PYRIC_STUDIO_URL = '/__pyric/ui/studio';
|
|
5
5
|
|
|
6
6
|
export interface PyricRuntimeManifest {
|
|
7
7
|
studioUrl: string;
|
|
@@ -108,6 +108,13 @@ function isListenerPhaseErroredEvent(event: SandboxEvent): boolean {
|
|
|
108
108
|
return isListenerKind && isErroredPhase && hasErrorPayload;
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
+
function isAiRejectedEvent(event: SandboxEvent): boolean {
|
|
112
|
+
const isServiceMutationKind = event.kind === 'service_mutation';
|
|
113
|
+
const isAiService = event.service === 'ai';
|
|
114
|
+
const isRejectedOp = 'op' in event && event.op === 'request_rejected';
|
|
115
|
+
return isServiceMutationKind && isAiService && isRejectedOp;
|
|
116
|
+
}
|
|
117
|
+
|
|
111
118
|
function sandboxError(event: SandboxEvent): PyricRuntimeError | null {
|
|
112
119
|
if (isRuntimeErrorEvent(event)) {
|
|
113
120
|
const hasPathProperty = 'path' in event && typeof event.path === 'string';
|
|
@@ -127,6 +134,23 @@ function sandboxError(event: SandboxEvent): PyricRuntimeError | null {
|
|
|
127
134
|
message: errorPayload?.message ? errorPayload.message : 'Sandbox runtime error',
|
|
128
135
|
};
|
|
129
136
|
}
|
|
137
|
+
if (isAiRejectedEvent(event)) {
|
|
138
|
+
const detail = 'detail' in event ? (event.detail as Record<string, unknown> | undefined) : undefined;
|
|
139
|
+
const code = typeof detail?.code === 'string' ? detail.code : 'AI_ERROR';
|
|
140
|
+
const message = typeof detail?.message === 'string' ? detail.message : 'AI request rejected';
|
|
141
|
+
const hasPathProperty = 'path' in event && typeof event.path === 'string';
|
|
142
|
+
const targetPath = hasPathProperty ? event.path : '(ai)';
|
|
143
|
+
return {
|
|
144
|
+
id: event.id,
|
|
145
|
+
source: 'sandbox',
|
|
146
|
+
at: event.at,
|
|
147
|
+
service: 'ai',
|
|
148
|
+
method: 'generateContent',
|
|
149
|
+
path: targetPath,
|
|
150
|
+
code,
|
|
151
|
+
message: `AI_ERROR: ${message}`,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
130
154
|
if (isListenerErroredEvent(event)) {
|
|
131
155
|
const errorPayload = (event as { error: { code?: string; message: string } }).error;
|
|
132
156
|
return {
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
rulesHashOf,
|
|
15
15
|
} from './rules.js';
|
|
16
16
|
import { createEventHub, createPyricNamespace } from './namespace.js';
|
|
17
|
+
import type { BeaconReport } from '../register/beacon.js';
|
|
17
18
|
import { diskProjectStore, diskWorkspace } from './studio/index.js';
|
|
18
19
|
import type { ServeLogger } from './server.js';
|
|
19
20
|
import {
|
|
@@ -35,8 +36,15 @@ export interface SandboxSessionOptions {
|
|
|
35
36
|
bridgeUrl?: () => string | null;
|
|
36
37
|
ai?: InitPayload['ai'];
|
|
37
38
|
aiProxyUpstream?: string;
|
|
39
|
+
permissive?: boolean;
|
|
38
40
|
logger?: ServeLogger;
|
|
39
41
|
activity?: (incident: ActivityIncident) => void;
|
|
42
|
+
/** Receives one handshake beacon per pyric-launched child, the dev
|
|
43
|
+
* server's only positive proof that the register module reached it. */
|
|
44
|
+
beacon?: (report: BeaconReport) => void;
|
|
45
|
+
/** The per-launch secret a beacon must present, also placed in the child's
|
|
46
|
+
* `PYRIC_BEACON_TOKEN`. */
|
|
47
|
+
beaconToken?: string;
|
|
40
48
|
}
|
|
41
49
|
|
|
42
50
|
export interface SandboxSessionSummary {
|
|
@@ -97,6 +105,13 @@ export async function createSandboxSession(
|
|
|
97
105
|
databaseRules: database.rules,
|
|
98
106
|
databaseRulesHash: database.rulesHash,
|
|
99
107
|
};
|
|
108
|
+
if (!database.sourcePath) {
|
|
109
|
+
if (options.permissive) {
|
|
110
|
+
options.logger?.note(' ⓘ RTDB permissive mode active — client reads/writes are open by default.');
|
|
111
|
+
} else {
|
|
112
|
+
options.logger?.note(' ⚠ no database.rules.json found — client RTDB reads/writes default to DENY (matching production Firebase). Use --permissive for open prototyping.');
|
|
113
|
+
}
|
|
114
|
+
}
|
|
100
115
|
const events = createEventHub();
|
|
101
116
|
const capture: CaptureStore | undefined = (options.capture ?? true)
|
|
102
117
|
? createCaptureStore(options.projectDir)
|
|
@@ -164,6 +179,7 @@ export async function createSandboxSession(
|
|
|
164
179
|
: seedUsers,
|
|
165
180
|
messaging: true,
|
|
166
181
|
ai: options.ai ?? null,
|
|
182
|
+
permissive: Boolean(options.permissive),
|
|
167
183
|
});
|
|
168
184
|
|
|
169
185
|
const summary: SandboxSessionSummary = {
|
|
@@ -203,6 +219,8 @@ export async function createSandboxSession(
|
|
|
203
219
|
workerVersion: options.sdk.workerVersion,
|
|
204
220
|
aiProxyUpstream: options.aiProxyUpstream,
|
|
205
221
|
activity: options.activity,
|
|
222
|
+
beacon: options.beacon,
|
|
223
|
+
beaconToken: options.beaconToken,
|
|
206
224
|
logger: options.logger,
|
|
207
225
|
});
|
|
208
226
|
|
|
@@ -221,16 +239,13 @@ export async function createSandboxSession(
|
|
|
221
239
|
}
|
|
222
240
|
};
|
|
223
241
|
const reloadDatabaseRules = async (): Promise<RulesReloadResult> => {
|
|
224
|
-
const isMissingDatabaseRules = database.sourcePath === null;
|
|
225
|
-
if (isMissingDatabaseRules) {
|
|
226
|
-
return { kind: 'not-configured' };
|
|
227
|
-
}
|
|
228
242
|
try {
|
|
229
243
|
const updated = await loadProjectDatabaseRules(options.projectDir, options.firebaseConfig);
|
|
230
244
|
const isMissingUpdatedRules = updated.rules === null || updated.rulesHash === null;
|
|
231
245
|
if (isMissingUpdatedRules) {
|
|
232
246
|
return { kind: 'not-configured' };
|
|
233
247
|
}
|
|
248
|
+
database.sourcePath = updated.sourcePath;
|
|
234
249
|
live.databaseRules = updated.rules;
|
|
235
250
|
live.databaseRulesHash = updated.rulesHash;
|
|
236
251
|
events.broadcast('rtdb-rules-update', { rules: updated.rules, rulesHash: updated.rulesHash });
|
package/src/serve/server.ts
CHANGED
|
@@ -134,6 +134,23 @@ export function isAllowedUpgrade(
|
|
|
134
134
|
);
|
|
135
135
|
}
|
|
136
136
|
|
|
137
|
+
/**
|
|
138
|
+
* Extract a header value case-insensitively from either Node's IncomingMessage headers
|
|
139
|
+
* or Fetch API Headers object.
|
|
140
|
+
*/
|
|
141
|
+
export function getHeader(
|
|
142
|
+
req: { headers?: Record<string, string | string[] | undefined> | Headers },
|
|
143
|
+
name: string,
|
|
144
|
+
): string | undefined {
|
|
145
|
+
const headers = req?.headers;
|
|
146
|
+
if (!headers) return undefined;
|
|
147
|
+
if (typeof (headers as Headers).get === 'function') {
|
|
148
|
+
return (headers as Headers).get(name) ?? undefined;
|
|
149
|
+
}
|
|
150
|
+
const val = (headers as Record<string, string | string[] | undefined>)[name.toLowerCase()];
|
|
151
|
+
return Array.isArray(val) ? val.join(', ') : val;
|
|
152
|
+
}
|
|
153
|
+
|
|
137
154
|
export interface ServeHandle {
|
|
138
155
|
port: number;
|
|
139
156
|
host: string;
|
|
@@ -249,7 +266,7 @@ async function handleRequest(
|
|
|
249
266
|
if (!isAllowedHost(req.headers.host, opts.host ?? 'localhost', opts.allowedHosts)) {
|
|
250
267
|
logger.note(` ✖ 403 blocked Host '${req.headers.host}' (DNS-rebinding guard)`);
|
|
251
268
|
res.writeHead(403, { 'content-type': 'text/plain' }).end(
|
|
252
|
-
`pyric
|
|
269
|
+
`pyric sandbox: refused request for Host '${req.headers.host ?? ''}'. ` +
|
|
253
270
|
'Only localhost is allowed; use --allowed-host to add one.',
|
|
254
271
|
);
|
|
255
272
|
return;
|
|
@@ -17,8 +17,16 @@ import {
|
|
|
17
17
|
stat,
|
|
18
18
|
writeFile,
|
|
19
19
|
} from 'node:fs/promises';
|
|
20
|
-
import {
|
|
21
|
-
|
|
20
|
+
import {
|
|
21
|
+
existsSync,
|
|
22
|
+
lstatSync,
|
|
23
|
+
mkdirSync,
|
|
24
|
+
readlinkSync,
|
|
25
|
+
realpathSync,
|
|
26
|
+
watch as fsWatch,
|
|
27
|
+
type FSWatcher,
|
|
28
|
+
} from 'node:fs';
|
|
29
|
+
import { basename, dirname, join, posix, relative, resolve, sep } from 'node:path';
|
|
22
30
|
|
|
23
31
|
import type {
|
|
24
32
|
WorkspaceChange,
|
|
@@ -34,6 +42,54 @@ export class WorkspacePathError extends Error {
|
|
|
34
42
|
}
|
|
35
43
|
}
|
|
36
44
|
|
|
45
|
+
/**
|
|
46
|
+
* Resolves the canonical realpath of a path, handling symlinks and non-existent
|
|
47
|
+
* terminal segments by resolving the nearest existing ancestor.
|
|
48
|
+
*/
|
|
49
|
+
function getCanonicalPath(targetPath: string, seen = new Set<string>()): string {
|
|
50
|
+
const abs = resolve(targetPath);
|
|
51
|
+
if (seen.has(abs)) {
|
|
52
|
+
throw new WorkspacePathError(targetPath);
|
|
53
|
+
}
|
|
54
|
+
seen.add(abs);
|
|
55
|
+
|
|
56
|
+
try {
|
|
57
|
+
return realpathSync(abs);
|
|
58
|
+
} catch (err: any) {
|
|
59
|
+
if (err?.code === 'ELOOP') {
|
|
60
|
+
throw new WorkspacePathError(targetPath);
|
|
61
|
+
}
|
|
62
|
+
if (err?.code !== 'ENOENT' && err?.code !== 'ENOTDIR') {
|
|
63
|
+
throw err;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
try {
|
|
68
|
+
const st = lstatSync(abs);
|
|
69
|
+
if (st.isSymbolicLink()) {
|
|
70
|
+
const linkTarget = readlinkSync(abs);
|
|
71
|
+
const nextTarget = resolve(dirname(abs), linkTarget);
|
|
72
|
+
return getCanonicalPath(nextTarget, seen);
|
|
73
|
+
}
|
|
74
|
+
} catch {
|
|
75
|
+
// abs does not exist as a directory entry
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const parent = dirname(abs);
|
|
79
|
+
if (parent === abs) {
|
|
80
|
+
return abs;
|
|
81
|
+
}
|
|
82
|
+
const canonicalParent = getCanonicalPath(parent, seen);
|
|
83
|
+
return join(canonicalParent, basename(abs));
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/** Check whether canonical target is contained within canonical root. */
|
|
87
|
+
function isContained(root: string, target: string): boolean {
|
|
88
|
+
if (target === root) return true;
|
|
89
|
+
const prefix = root.endsWith(sep) ? root : root + sep;
|
|
90
|
+
return target.startsWith(prefix);
|
|
91
|
+
}
|
|
92
|
+
|
|
37
93
|
/**
|
|
38
94
|
* Resolve a project-relative POSIX path to an absolute OS path inside `root`,
|
|
39
95
|
* or throw {@link WorkspacePathError} if it would escape. Leading slashes are
|
|
@@ -52,6 +108,24 @@ export function resolveWorkspacePath(root: string, rel: string): string {
|
|
|
52
108
|
if (abs !== root && !abs.startsWith(root + sep)) {
|
|
53
109
|
throw new WorkspacePathError(rel);
|
|
54
110
|
}
|
|
111
|
+
|
|
112
|
+
// Canonical realpath containment check:
|
|
113
|
+
// Reject symlinks that escape the workspace root.
|
|
114
|
+
const canonicalRoot = getCanonicalPath(root);
|
|
115
|
+
let canonicalTarget: string;
|
|
116
|
+
try {
|
|
117
|
+
canonicalTarget = getCanonicalPath(abs);
|
|
118
|
+
} catch (err) {
|
|
119
|
+
if (err instanceof WorkspacePathError) {
|
|
120
|
+
throw new WorkspacePathError(rel);
|
|
121
|
+
}
|
|
122
|
+
throw err;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (!isContained(canonicalRoot, canonicalTarget)) {
|
|
126
|
+
throw new WorkspacePathError(rel);
|
|
127
|
+
}
|
|
128
|
+
|
|
55
129
|
return abs;
|
|
56
130
|
}
|
|
57
131
|
|