@pyric/cli 0.1.0-alpha.20 → 0.1.0-alpha.22
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 +238 -1
- package/dist/assurance/.generated/conformance-verdicts.d.ts.map +1 -1
- package/dist/assurance/.generated/conformance-verdicts.js +238 -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/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/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/sandbox-runner.d.ts +20 -12
- package/dist/cli/sandbox-runner.d.ts.map +1 -1
- package/dist/cli/sandbox-runner.js +24 -21
- package/dist/cli/sandbox-runner.js.map +1 -1
- package/dist/cli/serve.d.ts +6 -10
- package/dist/cli/serve.d.ts.map +1 -1
- package/dist/cli/serve.js +57 -77
- package/dist/cli/serve.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/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 +1 -0
- package/dist/functions-rtdb/development-runtime.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/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/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/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/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 +28 -2
- package/dist/serve/entries/auth-helper-dom.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/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/runtime.d.ts.map +1 -1
- package/dist/serve/entries/runtime.js +9 -0
- package/dist/serve/entries/runtime.js.map +1 -1
- package/dist/serve/namespace.d.ts +14 -5
- package/dist/serve/namespace.d.ts.map +1 -1
- package/dist/serve/namespace.js +57 -124
- package/dist/serve/namespace.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 +118 -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/sandbox-session.d.ts +7 -0
- package/dist/serve/sandbox-session.d.ts.map +1 -1
- package/dist/serve/sandbox-session.js +2 -0
- package/dist/serve/sandbox-session.js.map +1 -1
- package/dist/serve/site-ui/_astro/{RulesCodeEditor.XtDmHOlN.js → RulesCodeEditor.DsTAsKIa.js} +1 -1
- package/dist/serve/site-ui/_astro/app.CMmTxyhL.js +1 -0
- package/dist/serve/site-ui/_astro/app.DhALsVii.js +115 -0
- package/dist/serve/site-ui/_astro/{chess-showcase.B72XYeoh.js → chess-showcase.Bn_pP6UJ.js} +2 -2
- package/dist/serve/site-ui/_astro/{example-runtime.C25_lx6Z.js → example-runtime.CXopTGv7.js} +1 -1
- package/dist/serve/site-ui/_astro/sandbox-controls.rOuZTOUG.js +510 -0
- package/dist/serve/site-ui/_astro/{seed.Co0yUJY5.js → seed.lywYbXZ0.js} +2 -2
- package/dist/serve/site-ui/_astro/writes.BsPBG3dp.js +653 -0
- package/dist/serve/site-ui/auth/index.html +1 -1
- package/dist/serve/site-ui/docs/_rhythm/index.html +1 -1
- package/dist/serve/site-ui/docs/agent/set-up-your-agent/index.html +1 -1
- package/dist/serve/site-ui/docs/agent/watch-and-review/index.html +1 -1
- package/dist/serve/site-ui/docs/agent/work-with-an-agent/index.html +1 -1
- package/dist/serve/site-ui/docs/ai-compat/index.html +1 -1
- package/dist/serve/site-ui/docs/api-reference/index.html +8 -1
- package/dist/serve/site-ui/docs/api-reference.md +7 -0
- package/dist/serve/site-ui/docs/app-compat/index.html +1 -1
- package/dist/serve/site-ui/docs/auth-compat/index.html +3 -3
- package/dist/serve/site-ui/docs/auth-compat.md +2 -2
- package/dist/serve/site-ui/docs/build/ai-logic/index.html +6 -1
- package/dist/serve/site-ui/docs/build/ai-logic.md +6 -0
- package/dist/serve/site-ui/docs/build/authentication/index.html +2 -2
- package/dist/serve/site-ui/docs/build/authentication.md +1 -1
- package/dist/serve/site-ui/docs/build/cloud-firestore/index.html +4 -2
- package/dist/serve/site-ui/docs/build/cloud-firestore.md +4 -0
- package/dist/serve/site-ui/docs/build/cloud-messaging/index.html +1 -1
- package/dist/serve/site-ui/docs/build/cloud-storage/index.html +1 -1
- package/dist/serve/site-ui/docs/build/realtime-database/index.html +1 -1
- package/dist/serve/site-ui/docs/conformance-scores/index.html +14 -2
- package/dist/serve/site-ui/docs/conformance-scores.md +13 -1
- package/dist/serve/site-ui/docs/create-pyric-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/database-compat/index.html +44 -44
- package/dist/serve/site-ui/docs/database-compat.md +43 -43
- package/dist/serve/site-ui/docs/examples/chess/index.html +1 -1
- package/dist/serve/site-ui/docs/examples/index.html +1 -1
- package/dist/serve/site-ui/docs/firestore-compat/index.html +4 -4
- 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/firestore-kotlin-compat/index.html +319 -0
- package/dist/serve/site-ui/docs/firestore-kotlin-compat.md +344 -0
- package/dist/serve/site-ui/docs/firestore-swift-compat/index.html +490 -0
- package/dist/serve/site-ui/docs/firestore-swift-compat.md +517 -0
- package/dist/serve/site-ui/docs/functions-rtdb-compat/index.html +1 -1
- 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/flutter/index.html +98 -0
- package/dist/serve/site-ui/docs/get-started/flutter.md +105 -0
- package/dist/serve/site-ui/docs/get-started/how-the-swap-works/index.html +1 -1
- package/dist/serve/site-ui/docs/get-started/nextjs/index.html +1 -1
- package/dist/serve/site-ui/docs/get-started/start-building/index.html +1 -1
- package/dist/serve/site-ui/docs/get-started/vite/index.html +1 -1
- package/dist/serve/site-ui/docs/index.json +3211 -1471
- package/dist/serve/site-ui/docs/messaging-compat/index.html +1 -1
- package/dist/serve/site-ui/docs/observe/resolve-runtime-status/index.html +4 -3
- package/dist/serve/site-ui/docs/observe/resolve-runtime-status.md +3 -1
- package/dist/serve/site-ui/docs/observe/see-whats-happening/index.html +1 -1
- package/dist/serve/site-ui/docs/observe/shape-your-data/index.html +1 -1
- package/dist/serve/site-ui/docs/observe/switch-and-impersonate-identities/index.html +110 -0
- package/dist/serve/site-ui/docs/observe/switch-and-impersonate-identities.md +134 -0
- package/dist/serve/site-ui/docs/overview/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-admin-app-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-admin-auth-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-admin-database-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-admin-firestore-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-admin-messaging-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-admin-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-admin-storage-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-ai-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-ai-scripting-reference-api/index.html +1 -1
- 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 +1 -1
- package/dist/serve/site-ui/docs/pyric-auth-reference-api/index.html +6 -2
- 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 +1 -1
- package/dist/serve/site-ui/docs/pyric-cli-assurance-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-cli-bridge-client-reference-api/index.html +2 -2
- 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 +1 -1
- 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 +4 -1
- package/dist/serve/site-ui/docs/pyric-cli-conformance-browser-reference-api.md +3 -0
- package/dist/serve/site-ui/docs/pyric-cli-conformance-docs-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-cli-conformance-reference-api/index.html +4 -1
- package/dist/serve/site-ui/docs/pyric-cli-conformance-reference-api.md +3 -0
- package/dist/serve/site-ui/docs/pyric-cli-credentials-node-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-cli-discover-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-cli-next-reference-api/index.html +2 -2
- 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 +1 -1
- package/dist/serve/site-ui/docs/pyric-cli-register-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-cli-remote-reference-api/index.html +34 -9
- package/dist/serve/site-ui/docs/pyric-cli-remote-reference-api.md +16 -8
- package/dist/serve/site-ui/docs/pyric-cli-serve-worker-reference-api/index.html +133 -93
- 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 +2 -2
- 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 +2 -2
- 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 +2 -2
- package/dist/serve/site-ui/docs/pyric-database-reference-api.md +1 -1
- 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 +40 -11
- 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 +1 -1
- package/dist/serve/site-ui/docs/pyric-messaging-sw-reference-api/index.html +1 -1
- 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 +1 -1
- package/dist/serve/site-ui/docs/pyric-sandbox-database-reference-api/index.html +52 -17
- 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 +1 -1
- package/dist/serve/site-ui/docs/pyric-sandbox-reference-api/index.html +239 -49
- 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 +22 -4
- package/dist/serve/site-ui/docs/pyric-storage-reference-api.md +25 -3
- package/dist/serve/site-ui/docs/pyric-ui-agents-reference-api/index.html +26 -96
- 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 +1 -1
- package/dist/serve/site-ui/docs/pyric-ui-auth-reference-api/index.html +2 -2
- 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 +1 -1
- package/dist/serve/site-ui/docs/pyric-ui-events-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-ui-firestore-hooks-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-ui-firestore-reference-api/index.html +2 -2
- 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 +124 -26
- 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 +1 -1
- package/dist/serve/site-ui/docs/pyric-ui-rules-hooks-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-ui-rules-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-ui-storage-hooks-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/pyric-ui-storage-reference-api/index.html +4 -5
- 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 +1 -1
- package/dist/serve/site-ui/docs/pyric-ui-traffic-reference-api/index.html +1 -1
- package/dist/serve/site-ui/docs/reference/cli/index.html +6 -3
- package/dist/serve/site-ui/docs/reference/cli.md +8 -2
- package/dist/serve/site-ui/docs/rules-compat/index.html +10 -2
- package/dist/serve/site-ui/docs/rules-compat.md +9 -1
- package/dist/serve/site-ui/docs/secure/audit-your-rules/index.html +1 -1
- package/dist/serve/site-ui/docs/secure/firestore-rules-limits/index.html +1 -1
- package/dist/serve/site-ui/docs/secure/read-a-denial/index.html +1 -1
- package/dist/serve/site-ui/docs/secure/rtdb-rules-in-typescript/index.html +1 -1
- package/dist/serve/site-ui/docs/secure/rules-standard-library/index.html +1 -1
- package/dist/serve/site-ui/docs/secure/secure-it-with-rules/index.html +1 -1
- package/dist/serve/site-ui/docs/secure/simulate-and-lint/index.html +1 -1
- package/dist/serve/site-ui/docs/secure/write-a-rules-test-suite/index.html +1 -1
- package/dist/serve/site-ui/docs/ship/ship-to-production/index.html +1 -1
- package/dist/serve/site-ui/docs/ship/test-in-node/index.html +1 -1
- package/dist/serve/site-ui/docs/storage-compat/index.html +13 -13
- 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 +1 -1
- package/dist/serve/site-ui/docs/trust/rules-standard-library/index.html +1 -1
- package/dist/serve/site-ui/docs/trust/versioning-and-compatibility/index.html +1 -1
- package/dist/serve/site-ui/docs/tutorial/index.html +1 -1
- package/dist/serve/site-ui/examples/chess/index.html +1 -1
- package/dist/serve/site-ui/firestore/index.html +1 -1
- package/dist/serve/site-ui/llms.txt +13 -0
- package/dist/serve/site-ui/rtdb/index.html +1 -1
- package/dist/serve/site-ui/settings/index.html +1 -1
- package/dist/serve/site-ui/storage/index.html +1 -1
- package/dist/serve/site-ui/studio/index.html +1 -1
- package/dist/serve/site-ui/traffic/index.html +1 -1
- 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/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.map +1 -1
- package/dist/serve/vite-sandbox-generation.js +12 -0
- 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.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-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/serve-init.d.ts.map +1 -1
- package/dist/serve/worker/serve-init.js +8 -2
- package/dist/serve/worker/serve-init.js.map +1 -1
- package/dist/verify/fixture.d.ts +1 -1
- package/package.json +16 -5
- package/src/assurance/.generated/conformance-verdicts.ts +238 -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 +0 -44
- package/src/cli/inlined-sdk-scanner.ts +77 -0
- package/src/cli/sandbox-interlock.ts +167 -0
- package/src/cli/sandbox-runner.ts +37 -26
- package/src/cli/serve.ts +68 -69
- package/src/cli/unsupported-runtime.ts +68 -0
- 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 +4 -0
- package/src/google-endpoints.ts +155 -0
- 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/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/entries/active-auth-registry.ts +56 -0
- package/src/serve/entries/active-auth.ts +100 -0
- package/src/serve/entries/auth-helper-core.ts +5 -0
- package/src/serve/entries/auth-helper-dom.ts +26 -2
- package/src/serve/entries/auth.ts +8 -0
- package/src/serve/entries/bridge-url.ts +1 -1
- package/src/serve/entries/init.ts +78 -3
- package/src/serve/entries/runtime.ts +10 -0
- package/src/serve/namespace.ts +73 -140
- 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 +140 -15
- package/src/serve/runtime/identity.ts +26 -0
- package/src/serve/sandbox-session.ts +9 -0
- package/src/serve/studio/disk-workspace.ts +76 -2
- package/src/serve/vite-plugin.ts +8 -8
- package/src/serve/vite-sandbox-generation.ts +15 -0
- package/src/serve/worker/client/auth.ts +1 -1
- package/src/serve/worker/client/core.ts +80 -3
- 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-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/serve-init.ts +9 -2
- package/src/verify/fixture.ts +1 -1
- package/dist/serve/site-ui/_astro/app.B52xr-DK.js +0 -1
- package/dist/serve/site-ui/_astro/app.DWBraPUw.js +0 -12
- package/dist/serve/site-ui/_astro/sandbox-controls.DEpnKg-O.js +0 -1169
- package/dist/serve/site-ui/_astro/writes.rpjrFzmu.js +0 -102
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The interlock: the launcher's statement about interception in the child it
|
|
3
|
+
* is about to start, plus the warn-only watchdog for the child's answer.
|
|
4
|
+
*
|
|
5
|
+
* The status line is knowable synchronously from the env `pyric sandbox` just
|
|
6
|
+
* assembled: guard mode, whether NODE_OPTIONS really carries the register
|
|
7
|
+
* import, and where the child's handshake beacon will land. The watchdog is
|
|
8
|
+
* the other half: a child still alive well after launch that never posted a
|
|
9
|
+
* beacon is probably not intercepted.
|
|
10
|
+
*/
|
|
11
|
+
import { beaconEndpoint } from '../register/beacon.js';
|
|
12
|
+
import { parseGuardMode, type GuardMode } from '../register/net-guard.js';
|
|
13
|
+
import { detectUnsupportedRuntime, formatUnsupportedRuntimeWarning } from './unsupported-runtime.js';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* What `pyric sandbox` can say about the interception it is about to hand the
|
|
17
|
+
* child, entirely from the env it just assembled: no waiting, no round trip.
|
|
18
|
+
*/
|
|
19
|
+
export interface InterlockStatus {
|
|
20
|
+
/** Net-guard mode the child will run under (`PYRIC_GUARD`, default warn). */
|
|
21
|
+
readonly guard: GuardMode;
|
|
22
|
+
/** Whether `NODE_OPTIONS` actually carries the register `--import`. */
|
|
23
|
+
readonly registerImported: boolean;
|
|
24
|
+
/** Where the child's handshake beacon will land, or null when the
|
|
25
|
+
* activator carries no bridge URL. */
|
|
26
|
+
readonly beacon: string | null;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Read the interlock off the child env. Everything here is synchronous by
|
|
31
|
+
* construction: it is a statement about the launch, printed before anything at
|
|
32
|
+
* runtime has had a chance to go wrong.
|
|
33
|
+
*/
|
|
34
|
+
export function describeInterlock(
|
|
35
|
+
childEnv: NodeJS.ProcessEnv,
|
|
36
|
+
registerUrl: string,
|
|
37
|
+
): InterlockStatus {
|
|
38
|
+
return {
|
|
39
|
+
guard: parseGuardMode(childEnv.PYRIC_GUARD),
|
|
40
|
+
registerImported: (childEnv.NODE_OPTIONS ?? '').includes(`--import ${registerUrl}`),
|
|
41
|
+
beacon: beaconEndpoint(childEnv.PYRIC_SANDBOX),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* The startup status line, alongside the other `✔ <service>` checks.
|
|
47
|
+
*
|
|
48
|
+
* The healthy line is deliberately short: one fact per field and nothing the
|
|
49
|
+
* reader has to skim past. The degraded line is long because it reports a
|
|
50
|
+
* broken launch, which is worth every word.
|
|
51
|
+
*/
|
|
52
|
+
export function formatInterlockLine(status: InterlockStatus): string {
|
|
53
|
+
if (!status.registerImported) {
|
|
54
|
+
return (
|
|
55
|
+
`⚠ interlock guard=${status.guard}, register is NOT in the child's NODE_OPTIONS. ` +
|
|
56
|
+
`Its firebase-admin/firebase imports will NOT be rewritten and would reach LIVE Firebase.\n`
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
return `✔ interlock guard=${status.guard}, register loaded via NODE_OPTIONS\n`;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export interface LaunchCheckOptions {
|
|
63
|
+
/** The environment the child is about to receive. */
|
|
64
|
+
readonly childEnv: NodeJS.ProcessEnv;
|
|
65
|
+
/** Absolute `file:` URL of the register module, to look for in NODE_OPTIONS. */
|
|
66
|
+
readonly registerUrl: string;
|
|
67
|
+
/** The child's argv, for the unsupported-runtime check. */
|
|
68
|
+
readonly argv: readonly string[];
|
|
69
|
+
readonly write: (line: string) => void;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Every statement the launcher makes about the child, printed in one block
|
|
74
|
+
* before the spawn, and the interlock status it derived on the way.
|
|
75
|
+
*
|
|
76
|
+
* Two checks: the interlock status line, from the env alone, and the
|
|
77
|
+
* unsupported-runtime warning for the other way interception can be absent, a
|
|
78
|
+
* child runtime that never evaluates Node loader hooks at all.
|
|
79
|
+
*/
|
|
80
|
+
export function reportLaunchChecks(opts: LaunchCheckOptions): InterlockStatus {
|
|
81
|
+
const interlock = describeInterlock(opts.childEnv, opts.registerUrl);
|
|
82
|
+
opts.write(formatInterlockLine(interlock));
|
|
83
|
+
const unsupportedRuntime = detectUnsupportedRuntime(opts.argv);
|
|
84
|
+
if (unsupportedRuntime !== null) opts.write(formatUnsupportedRuntimeWarning(unsupportedRuntime));
|
|
85
|
+
return interlock;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** How long a child may live without its beacon before we say something. */
|
|
89
|
+
const BEACON_GRACE_MS = 15_000;
|
|
90
|
+
|
|
91
|
+
export interface BeaconWatchdogOptions {
|
|
92
|
+
/** The child command, for attribution in the warning. */
|
|
93
|
+
readonly label: string;
|
|
94
|
+
/** The endpoint the child would post to. Null means nothing to watch. */
|
|
95
|
+
readonly beacon: string | null;
|
|
96
|
+
/** Whether a beacon from this child has been recorded. */
|
|
97
|
+
readonly sawBeacon: () => boolean;
|
|
98
|
+
/** Whether the child is still running. */
|
|
99
|
+
readonly isAlive: () => boolean;
|
|
100
|
+
readonly warn: (line: string) => void;
|
|
101
|
+
readonly graceMs?: number;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export interface BeaconWatchdog {
|
|
105
|
+
/** Cancel a pending check. Idempotent. */
|
|
106
|
+
stop(): void;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/** The warning itself: one paragraph naming what the silence means and what
|
|
110
|
+
* to check. Kept separate so its exact wording is testable. */
|
|
111
|
+
export function formatMissingBeaconWarning(opts: {
|
|
112
|
+
label: string;
|
|
113
|
+
graceMs: number;
|
|
114
|
+
beacon: string;
|
|
115
|
+
}): string {
|
|
116
|
+
const seconds = Math.round(opts.graceMs / 1000);
|
|
117
|
+
return (
|
|
118
|
+
` ⚠ interlock: \`${opts.label}\` has been running ${seconds}s without posting a register ` +
|
|
119
|
+
`beacon to ${opts.beacon}. Its firebase-admin/firebase imports are probably NOT routed to ` +
|
|
120
|
+
`the pyric sandbox, which means they would reach LIVE Firebase. Check that the command starts ` +
|
|
121
|
+
`a Node process (bun and deno do not evaluate Node loader hooks), that it does not overwrite ` +
|
|
122
|
+
`NODE_OPTIONS, and that NODE_ENV is not production. Warning only: nothing was blocked, and ` +
|
|
123
|
+
`this is reported once per child.`
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* The warn-only interlock watchdog.
|
|
129
|
+
*
|
|
130
|
+
* It never kills the child and never blocks a request. The reason is the
|
|
131
|
+
* signal's own honesty: beacon delivery is best-effort (see
|
|
132
|
+
* `register/beacon.ts`), and a plausible silent child is not the same thing as
|
|
133
|
+
* a broken one. A short-lived script that exits before its POST lands, a child
|
|
134
|
+
* that reaches the sandbox only through a grandchild, a dev server slow to
|
|
135
|
+
* boot: each would be killed by a fail-closed version of this check, and each
|
|
136
|
+
* is fine.
|
|
137
|
+
*
|
|
138
|
+
* So the heuristic is the simple, attributable one: the child is still alive
|
|
139
|
+
* `graceMs` after launch and no beacon has arrived. Both halves matter. An
|
|
140
|
+
* exited child was never expected to say anything, and a child whose beacon
|
|
141
|
+
* landed has already proved the point. One warning per child, guaranteed by
|
|
142
|
+
* the one-shot timer; the timer is unref'd so a watchdog can never be the
|
|
143
|
+
* reason a process stays up.
|
|
144
|
+
*
|
|
145
|
+
* `sawBeacon` is a count delta rather than a pid match, deliberately. The
|
|
146
|
+
* process that loads register is often a grandchild (`npm run dev` starts
|
|
147
|
+
* node, `next dev` starts its worker), so the spawned child's own pid is
|
|
148
|
+
* frequently not the pid in the beacon, and matching on it would warn about
|
|
149
|
+
* perfectly healthy launches. The delta's known imprecision runs the other
|
|
150
|
+
* way: a sibling runtime's beacon that lands inside the grace window can mask
|
|
151
|
+
* a real miss. Erring toward silence is the right bias for a warn-only check.
|
|
152
|
+
*/
|
|
153
|
+
export function startBeaconWatchdog(opts: BeaconWatchdogOptions): BeaconWatchdog {
|
|
154
|
+
const beacon = opts.beacon;
|
|
155
|
+
if (beacon === null) return { stop: () => {} };
|
|
156
|
+
const graceMs = opts.graceMs ?? BEACON_GRACE_MS;
|
|
157
|
+
const timer = setTimeout(() => {
|
|
158
|
+
if (opts.sawBeacon() || !opts.isAlive()) return;
|
|
159
|
+
opts.warn(formatMissingBeaconWarning({ label: opts.label, graceMs, beacon }));
|
|
160
|
+
}, graceMs);
|
|
161
|
+
timer.unref?.();
|
|
162
|
+
return {
|
|
163
|
+
stop(): void {
|
|
164
|
+
clearTimeout(timer);
|
|
165
|
+
},
|
|
166
|
+
};
|
|
167
|
+
}
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
* only `spawnDevChild` touches the process table.
|
|
17
17
|
*/
|
|
18
18
|
import { spawn, type ChildProcess } from 'node:child_process';
|
|
19
|
+
import { SHELL_OPERATORS } from './unsupported-runtime.js';
|
|
19
20
|
|
|
20
21
|
// ─── First-run race guard ───────────────────────────────────────────────────
|
|
21
22
|
|
|
@@ -152,41 +153,60 @@ export function registerModuleUrl(): string {
|
|
|
152
153
|
return new URL('../register/index.js', import.meta.url).href;
|
|
153
154
|
}
|
|
154
155
|
|
|
156
|
+
/** What the launcher has to put in a child's environment for interception. */
|
|
157
|
+
export interface ChildActivation {
|
|
158
|
+
/** The serve host the child's sandbox calls reach. */
|
|
159
|
+
readonly serveUrl: string;
|
|
160
|
+
/** Absolute `file:` URL of the register module. */
|
|
161
|
+
readonly registerUrl: string;
|
|
162
|
+
/** The per-launch secret the child's handshake beacon must present.
|
|
163
|
+
* Absent when the launcher runs no beacon receiver, as the Vite plugin's
|
|
164
|
+
* Functions runtime does; the child then reports on stderr only. */
|
|
165
|
+
readonly beaconToken?: string | undefined;
|
|
166
|
+
}
|
|
167
|
+
|
|
155
168
|
/**
|
|
156
|
-
* Child env: sets the activator and APPENDS the loader
|
|
157
|
-
*
|
|
158
|
-
* must survive). `file:` URLs are
|
|
159
|
-
* even for paths with spaces.
|
|
169
|
+
* Child env: sets the activator and the beacon secret, and APPENDS the loader
|
|
170
|
+
* to NODE_OPTIONS rather than replacing it (the user's own --inspect /
|
|
171
|
+
* --max-old-space-size and so on must survive). `file:` URLs are
|
|
172
|
+
* percent-encoded, so no quoting is needed even for paths with spaces.
|
|
160
173
|
*/
|
|
161
174
|
export function buildChildEnv(
|
|
162
175
|
base: NodeJS.ProcessEnv,
|
|
163
|
-
opts:
|
|
176
|
+
opts: ChildActivation,
|
|
164
177
|
): NodeJS.ProcessEnv {
|
|
165
178
|
const importFlag = `--import ${opts.registerUrl}`;
|
|
166
|
-
|
|
179
|
+
const env: NodeJS.ProcessEnv = {
|
|
167
180
|
...base,
|
|
168
181
|
PYRIC_SANDBOX: `remote:${opts.serveUrl}`,
|
|
169
182
|
NODE_OPTIONS: base.NODE_OPTIONS ? `${base.NODE_OPTIONS} ${importFlag}` : importFlag,
|
|
170
183
|
};
|
|
184
|
+
if (opts.beaconToken !== undefined) env.PYRIC_BEACON_TOKEN = opts.beaconToken;
|
|
185
|
+
return env;
|
|
171
186
|
}
|
|
172
187
|
|
|
173
188
|
/**
|
|
174
189
|
* Format copy-pasteable POSIX export statements for host-only startup.
|
|
175
190
|
* Grouped in a cleanly formatted console block for easy selection and copying
|
|
176
191
|
* into a separate terminal (for example, when running Next.js independently).
|
|
192
|
+
*
|
|
193
|
+
* The beacon secret is part of the block: without it a process started this
|
|
194
|
+
* way still intercepts, but the dev server cannot confirm that it did.
|
|
177
195
|
*/
|
|
178
|
-
export function formatStartupEnvExport(opts:
|
|
179
|
-
const
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
196
|
+
export function formatStartupEnvExport(opts: ChildActivation): string {
|
|
197
|
+
const lines = [`export PYRIC_SANDBOX="remote:${opts.serveUrl}"`];
|
|
198
|
+
if (opts.beaconToken !== undefined) {
|
|
199
|
+
lines.push(`export PYRIC_BEACON_TOKEN="${opts.beaconToken}"`);
|
|
200
|
+
}
|
|
201
|
+
lines.push(`export NODE_OPTIONS="--import ${opts.registerUrl}"`);
|
|
202
|
+
const width = Math.max(...lines.map((line) => line.length));
|
|
203
|
+
const divider = '─'.repeat(width + 4);
|
|
204
|
+
const body = lines.map((line) => ` ${line}\n`).join('');
|
|
184
205
|
return (
|
|
185
206
|
'\n' +
|
|
186
207
|
' To run external commands against this sandbox, paste in another terminal:\n' +
|
|
187
208
|
` ${divider}\n` +
|
|
188
|
-
|
|
189
|
-
` ${line2}\n` +
|
|
209
|
+
body +
|
|
190
210
|
` ${divider}\n`
|
|
191
211
|
);
|
|
192
212
|
}
|
|
@@ -225,8 +245,6 @@ export function createLinePrefixer(
|
|
|
225
245
|
/** How long a signalled child may linger before SIGKILL. */
|
|
226
246
|
const FORCE_KILL_AFTER_MS = 2_000;
|
|
227
247
|
|
|
228
|
-
const SHELL_OPERATORS = new Set(['&&', '||', '|', ';', '&']);
|
|
229
|
-
|
|
230
248
|
export interface SandboxChildHandle {
|
|
231
249
|
exited: Promise<number>;
|
|
232
250
|
signal(sig: NodeJS.Signals): void;
|
|
@@ -259,16 +277,9 @@ export function spawnSandboxChild(
|
|
|
259
277
|
// 2. Check for discrete shell operators (&&, ||, |, ;) among top-level tokens
|
|
260
278
|
const hasShellOperators = parts.some((token) => SHELL_OPERATORS.has(token));
|
|
261
279
|
|
|
262
|
-
//
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
const target = opts.json ? process.stderr : process.stdout;
|
|
266
|
-
target.write(
|
|
267
|
-
` ⚠ ${runner} detected: pyric intercepts Firebase imports via Node.js module loader hooks (NODE_OPTIONS="--import ..."). ` +
|
|
268
|
-
`${runner} does not evaluate Node loader hooks — SDK calls in this process will not reach the pyric sandbox. ` +
|
|
269
|
-
`Use \`node\` (or \`npx tsx\`) to run with the sandbox swap.\n`,
|
|
270
|
-
);
|
|
271
|
-
}
|
|
280
|
+
// The bun/deno warning is emitted by the launch seam in serve.ts, alongside
|
|
281
|
+
// the interlock line, so every pre-spawn statement about the child prints in
|
|
282
|
+
// one block and in order.
|
|
272
283
|
|
|
273
284
|
const [command, ...args] = parts;
|
|
274
285
|
let child: ChildProcess;
|
package/src/cli/serve.ts
CHANGED
|
@@ -10,8 +10,9 @@
|
|
|
10
10
|
* rules load (fail fast on broken rules) → SDK bundle (cached per pyric
|
|
11
11
|
* version) → static server with the `/__pyric/` namespace + HTML injection.
|
|
12
12
|
*/
|
|
13
|
+
import { randomBytes } from 'node:crypto';
|
|
13
14
|
import { join, relative, resolve } from 'node:path';
|
|
14
|
-
import { existsSync,
|
|
15
|
+
import { existsSync, watch as watchFile } from 'node:fs';
|
|
15
16
|
import type { ParsedArgs } from './parse-args.js';
|
|
16
17
|
import { readFirebaseJson, readFirebaseRc, type FirebaseJson } from './firebase-json.js';
|
|
17
18
|
import { bundleSdk, bundleWorker, defaultSdkEntries, resolveSiteUiDir } from '../serve/bundler.js';
|
|
@@ -22,7 +23,9 @@ import {
|
|
|
22
23
|
embeddedWorkerVersion,
|
|
23
24
|
} from '../serve/standalone-assets.js';
|
|
24
25
|
import { hasSandboxBuildMarker } from '../serve/sandbox-marker.js';
|
|
26
|
+
import { formatBeaconReceipt } from '../serve/beacon-route.js';
|
|
25
27
|
import type { InitPayload } from '../serve/namespace.js';
|
|
28
|
+
import { formatAiStatusLine } from '../serve/ai-status.js';
|
|
26
29
|
import { injectServeTags } from '../serve/html-injection.js';
|
|
27
30
|
import { formatActivityWarning } from '../serve/activity-warning.js';
|
|
28
31
|
import { consoleServeLogger, startStaticServer, stderrServeLogger, type ServeHandle } from '../serve/server.js';
|
|
@@ -38,6 +41,12 @@ import {
|
|
|
38
41
|
waitForSandboxPeer,
|
|
39
42
|
type SandboxChildHandle,
|
|
40
43
|
} from './sandbox-runner.js';
|
|
44
|
+
import {
|
|
45
|
+
reportLaunchChecks,
|
|
46
|
+
startBeaconWatchdog,
|
|
47
|
+
type BeaconWatchdog,
|
|
48
|
+
} from './sandbox-interlock.js';
|
|
49
|
+
import { scanForInlinedFirebase } from './inlined-sdk-scanner.js';
|
|
41
50
|
import {
|
|
42
51
|
createFunctionsDevelopmentRuntime,
|
|
43
52
|
createHttpFunctionsPeerReadiness,
|
|
@@ -88,6 +97,12 @@ export interface ServeRuntime {
|
|
|
88
97
|
uiUrl: string | null;
|
|
89
98
|
/** Persistence summary (null when `--persist` is off). */
|
|
90
99
|
persist: { restoredDocs: number; restoredUsers: number } | null;
|
|
100
|
+
/** Handshake beacons posted to `/__pyric/beacon` so far, the interlock
|
|
101
|
+
* watchdog's only input. */
|
|
102
|
+
beaconCount: () => number;
|
|
103
|
+
/** The per-launch secret a beacon must present, placed in every child's
|
|
104
|
+
* `PYRIC_BEACON_TOKEN`. */
|
|
105
|
+
beaconToken: string;
|
|
91
106
|
}
|
|
92
107
|
|
|
93
108
|
/** The `--json` stdout contract — one line, keep stable; agents parse this.
|
|
@@ -152,6 +167,12 @@ export async function startServe(opts: {
|
|
|
152
167
|
}): Promise<ServeRuntime> {
|
|
153
168
|
const logger = opts.logger ?? consoleServeLogger();
|
|
154
169
|
|
|
170
|
+
// Handshake beacons from pyric-launched children, plus the per-launch secret
|
|
171
|
+
// that authorizes one. Both live here because the route does.
|
|
172
|
+
let beaconsSeen = 0;
|
|
173
|
+
const beaconCount = (): number => beaconsSeen;
|
|
174
|
+
const beaconToken = randomBytes(24).toString('base64url');
|
|
175
|
+
|
|
155
176
|
// --fresh only means anything against the state.json file `--persist`
|
|
156
177
|
// maintains — without `--persist` there is no file to discard, so
|
|
157
178
|
// `--fresh` alone was a silent no-op (nothing happened, nothing said so).
|
|
@@ -212,12 +233,12 @@ export async function startServe(opts: {
|
|
|
212
233
|
|
|
213
234
|
// The import map can only remap BARE `firebase/*` specifiers. A plain bundler
|
|
214
235
|
// build (`vite build`) inlines the real SDK into the app chunk, leaving
|
|
215
|
-
// nothing to intercept
|
|
236
|
+
// nothing to intercept: the page would then talk to REAL Firebase endpoints
|
|
216
237
|
// with the sandbox's fake credentials while the injected banner claims
|
|
217
238
|
// otherwise. That hole is structural, so `pyric sandbox` refuses such a dist
|
|
218
239
|
// rather than serving it. A pyric SANDBOX build (`vite build --mode
|
|
219
240
|
// development`) carries the marker and bundles pyric's in-page adapters, so it
|
|
220
|
-
// is trusted and the scan is skipped (marker present
|
|
241
|
+
// is trusted and the scan is skipped (marker present, no real SDK to find).
|
|
221
242
|
if (!hasSandboxBuildMarker(publicDir)) {
|
|
222
243
|
const inlined = scanForInlinedFirebase(publicDir);
|
|
223
244
|
if (inlined.length > 0) {
|
|
@@ -306,6 +327,11 @@ export async function startServe(opts: {
|
|
|
306
327
|
studio: opts.ui ? { siteUiDir } : false,
|
|
307
328
|
bridgeUrl: () => mount && origin.port > 0 ? mount.wsUrl(origin) : null,
|
|
308
329
|
activity: (incident) => logger.note(formatActivityWarning(incident)),
|
|
330
|
+
beaconToken,
|
|
331
|
+
beacon: (report) => {
|
|
332
|
+
beaconsSeen += 1;
|
|
333
|
+
logger.note(formatBeaconReceipt(report));
|
|
334
|
+
},
|
|
309
335
|
permissive: opts.permissive,
|
|
310
336
|
logger,
|
|
311
337
|
});
|
|
@@ -494,7 +520,7 @@ export async function startServe(opts: {
|
|
|
494
520
|
session.payload().storageRules
|
|
495
521
|
? `✔ rules ${session.summary.rules.storage.sourcePath} → deployed to the storage sandbox (hash ${session.summary.rules.storage.hash}; ` +
|
|
496
522
|
`edits require a restart — storage rules do not hot-reload)`
|
|
497
|
-
: `• rules no storage.rules — storage sandbox
|
|
523
|
+
: `• rules no storage.rules — storage sandbox denies client operations by default`,
|
|
498
524
|
);
|
|
499
525
|
if (uiUrl) {
|
|
500
526
|
logger.info(`✔ studio Pyric Studio: ${uiUrl}`);
|
|
@@ -505,6 +531,13 @@ export async function startServe(opts: {
|
|
|
505
531
|
if (mount) {
|
|
506
532
|
logger.info(`✔ bridge MCP endpoint: ${mount.mcpUrl(origin)} (sandbox peers over ws at /__pyric/sandbox)`);
|
|
507
533
|
}
|
|
534
|
+
// AI is a mounted service like the bridge: `/__pyric/ai-proxy` answers from
|
|
535
|
+
// the first request on, whether or not anything is configured. `pyric
|
|
536
|
+
// sandbox` has no AI flag, so the ENGINE is always the page's own `getAI()`
|
|
537
|
+
// choice (resolved lazily in the browser, since nothing here instantiates a
|
|
538
|
+
// broker to find out); what this server does decide is where the proxy
|
|
539
|
+
// forwards, and that is what the line reports.
|
|
540
|
+
logger.info(formatAiStatusLine({}));
|
|
508
541
|
let persistSummary: ServeRuntime['persist'] = null;
|
|
509
542
|
const persistence = session.summary.persistence;
|
|
510
543
|
if (persistence) {
|
|
@@ -553,7 +586,8 @@ export async function startServe(opts: {
|
|
|
553
586
|
logger.note('');
|
|
554
587
|
logger.note(' ⚠ the pyric sandbox runs IN the served page — keep the browser tab open.');
|
|
555
588
|
logger.note(' Firestore/auth data and persistence stop when no page is open.');
|
|
556
|
-
|
|
589
|
+
const mcpUrl = mount ? mount.mcpUrl(origin) : null;
|
|
590
|
+
return { handle, publicDir, payload, uiUrl, mcpUrl, persist: persistSummary, beaconCount, beaconToken };
|
|
557
591
|
}
|
|
558
592
|
|
|
559
593
|
/**
|
|
@@ -779,6 +813,7 @@ export async function runServe(parsed: ParsedArgs): Promise<number> {
|
|
|
779
813
|
}
|
|
780
814
|
|
|
781
815
|
let devChild: SandboxChildHandle | null = null;
|
|
816
|
+
let beaconWatchdog: BeaconWatchdog | null = null;
|
|
782
817
|
let functionsRuntime: FunctionsDevelopmentRuntime | null = null;
|
|
783
818
|
let resolveFunctionsExit!: (code: number) => void;
|
|
784
819
|
const functionsExited = new Promise<number>((resolve) => { resolveFunctionsExit = resolve; });
|
|
@@ -801,6 +836,7 @@ export async function runServe(parsed: ParsedArgs): Promise<number> {
|
|
|
801
836
|
]);
|
|
802
837
|
const stopAfterSignal = async (): Promise<number> => {
|
|
803
838
|
(json ? process.stderr : process.stdout).write('\nShutting down...\n');
|
|
839
|
+
beaconWatchdog?.stop();
|
|
804
840
|
if (devChild && devChild.child.exitCode === null) devChild.signal(await signal);
|
|
805
841
|
await functionsRuntime?.close().catch(() => undefined);
|
|
806
842
|
await runtime.handle.stop().catch(() => undefined);
|
|
@@ -845,6 +881,7 @@ export async function runServe(parsed: ParsedArgs): Promise<number> {
|
|
|
845
881
|
baseEnv: process.env,
|
|
846
882
|
serveUrl: runtime.handle.url,
|
|
847
883
|
registerUrl: registerModuleUrl(),
|
|
884
|
+
beaconToken: runtime.beaconToken,
|
|
848
885
|
instance: `${functionsProjectId}-default-rtdb`,
|
|
849
886
|
location: process.env.PYRIC_FUNCTIONS_RTDB_REGION ?? 'us-central1',
|
|
850
887
|
projectId: functionsProjectId ?? 'demo-project',
|
|
@@ -910,19 +947,37 @@ export async function runServe(parsed: ParsedArgs): Promise<number> {
|
|
|
910
947
|
info.write(
|
|
911
948
|
`✔ run \`${plan.label}\` — firebase-admin/firebase imports are routed to the sandbox at ${runtime.handle.url}\n`,
|
|
912
949
|
);
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
950
|
+
const childEnv = buildChildEnv(process.env, {
|
|
951
|
+
serveUrl: runtime.handle.url,
|
|
952
|
+
registerUrl: registerModuleUrl(),
|
|
953
|
+
beaconToken: runtime.beaconToken,
|
|
954
|
+
});
|
|
955
|
+
// What we are handing the child, stated before it starts: the interlock
|
|
956
|
+
// line and the unsupported-runtime check.
|
|
957
|
+
const interlock = reportLaunchChecks({
|
|
958
|
+
childEnv,
|
|
959
|
+
registerUrl: registerModuleUrl(),
|
|
960
|
+
argv: plan.argv,
|
|
961
|
+
write: (line) => info.write(line),
|
|
962
|
+
});
|
|
963
|
+
|
|
964
|
+
devChild = spawnSandboxChild(plan, { cwd, json, env: childEnv });
|
|
965
|
+
// A child still alive well after launch that never posted a beacon is very
|
|
966
|
+
// likely not intercepted. `startBeaconWatchdog` says why this only warns.
|
|
967
|
+
const beaconsAtSpawn = runtime.beaconCount();
|
|
968
|
+
beaconWatchdog = startBeaconWatchdog({
|
|
969
|
+
label: plan.label,
|
|
970
|
+
beacon: interlock.beacon,
|
|
971
|
+
sawBeacon: () => runtime.beaconCount() > beaconsAtSpawn,
|
|
972
|
+
isAlive: () => devChild !== null && devChild.child.exitCode === null,
|
|
973
|
+
warn: (line) => void process.stderr.write(`${line}\n`),
|
|
920
974
|
});
|
|
921
975
|
} else if (!json) {
|
|
922
976
|
process.stdout.write(
|
|
923
977
|
formatStartupEnvExport({
|
|
924
978
|
serveUrl: runtime.handle.url,
|
|
925
979
|
registerUrl: registerModuleUrl(),
|
|
980
|
+
beaconToken: runtime.beaconToken,
|
|
926
981
|
}),
|
|
927
982
|
);
|
|
928
983
|
}
|
|
@@ -934,6 +989,7 @@ export async function runServe(parsed: ParsedArgs): Promise<number> {
|
|
|
934
989
|
if (settled) return;
|
|
935
990
|
settled = true;
|
|
936
991
|
void (async () => {
|
|
992
|
+
beaconWatchdog?.stop();
|
|
937
993
|
await functionsRuntime?.close().catch(() => undefined);
|
|
938
994
|
if (devChild && devChild.child.exitCode === null) {
|
|
939
995
|
devChild.signal('SIGTERM');
|
|
@@ -971,60 +1027,3 @@ export async function runServe(parsed: ParsedArgs): Promise<number> {
|
|
|
971
1027
|
void signal.then(shutdown);
|
|
972
1028
|
});
|
|
973
1029
|
}
|
|
974
|
-
|
|
975
|
-
/**
|
|
976
|
-
* Detect a bundler build that INLINED the real firebase SDK into its served
|
|
977
|
-
* assets (`vite build` output). The served import map remaps only bare
|
|
978
|
-
* `firebase/*` specifiers, so such a build cannot be sandboxed — its calls
|
|
979
|
-
* reach real Google endpoints. Fingerprints are real-SDK-only endpoint hosts
|
|
980
|
-
* that never appear in a sandbox-clean app (whose calls all route to
|
|
981
|
-
* `/__pyric/*`). Bounded: depth ≤ 4, ≤ 200 script files, first hit per file.
|
|
982
|
-
* Returns publicDir-relative paths of offending assets.
|
|
983
|
-
*/
|
|
984
|
-
export function scanForInlinedFirebase(dir: string): string[] {
|
|
985
|
-
const FINGERPRINTS = [
|
|
986
|
-
'identitytoolkit.googleapis.com',
|
|
987
|
-
'firestore.googleapis.com',
|
|
988
|
-
'securetoken.googleapis.com',
|
|
989
|
-
'firebasedatabase.app',
|
|
990
|
-
];
|
|
991
|
-
const hits: string[] = [];
|
|
992
|
-
let scanned = 0;
|
|
993
|
-
const walk = (d: string, rel: string, depth: number): void => {
|
|
994
|
-
if (depth > 4 || scanned >= 200) return;
|
|
995
|
-
let names: string[];
|
|
996
|
-
try {
|
|
997
|
-
names = readdirSync(d);
|
|
998
|
-
} catch {
|
|
999
|
-
return;
|
|
1000
|
-
}
|
|
1001
|
-
for (const name of names) {
|
|
1002
|
-
if (scanned >= 200) return;
|
|
1003
|
-
const p = join(d, name);
|
|
1004
|
-
const r = rel ? `${rel}/${name}` : name;
|
|
1005
|
-
let st;
|
|
1006
|
-
try {
|
|
1007
|
-
st = statSync(p);
|
|
1008
|
-
} catch {
|
|
1009
|
-
continue;
|
|
1010
|
-
}
|
|
1011
|
-
if (st.isDirectory()) {
|
|
1012
|
-
// The pyric namespace itself never lands in hosting.public, but a
|
|
1013
|
-
// node_modules inside a served dir would be a scan-cost trap.
|
|
1014
|
-
// Dot-directories (.next, .git, .pyric) are internal caches and must be ignored.
|
|
1015
|
-
if (name === 'node_modules' || name.startsWith('.')) continue;
|
|
1016
|
-
walk(p, r, depth + 1);
|
|
1017
|
-
} else if (/\.(js|mjs)$/.test(name)) {
|
|
1018
|
-
scanned++;
|
|
1019
|
-
try {
|
|
1020
|
-
const text = readFileSync(p, 'utf8');
|
|
1021
|
-
if (FINGERPRINTS.some((f) => text.includes(f))) hits.push(r);
|
|
1022
|
-
} catch {
|
|
1023
|
-
// unreadable asset: skip
|
|
1024
|
-
}
|
|
1025
|
-
}
|
|
1026
|
-
}
|
|
1027
|
-
};
|
|
1028
|
-
walk(dir, '', 0);
|
|
1029
|
-
return hits;
|
|
1030
|
-
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Child runtimes that cannot evaluate Node loader hooks, and the one warning
|
|
3
|
+
* that says what is lost when a command starts one.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/** Tokens that end one command and begin the next inside a shell string. */
|
|
7
|
+
export const SHELL_OPERATORS = new Set(['&&', '||', '|', ';', '&']);
|
|
8
|
+
|
|
9
|
+
/** Command basenames that cannot evaluate Node loader hooks, to the runtime. */
|
|
10
|
+
const UNSUPPORTED_RUNTIME_BINARIES = new Map<string, string>([
|
|
11
|
+
['bun', 'bun'],
|
|
12
|
+
['bunx', 'bun'],
|
|
13
|
+
['deno', 'deno'],
|
|
14
|
+
]);
|
|
15
|
+
|
|
16
|
+
/** Leading `KEY=VAL` environment assignments in a shell command. */
|
|
17
|
+
const ENV_ASSIGNMENT = /^[A-Za-z_][A-Za-z0-9_]*=/;
|
|
18
|
+
|
|
19
|
+
/** Strip directory and a Windows `.exe` suffix from a command token. */
|
|
20
|
+
function commandBasename(token: string): string {
|
|
21
|
+
const base = token.split(/[\\/]/).pop() ?? token;
|
|
22
|
+
return base.toLowerCase().replace(/\.exe$/, '');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Decide whether the child command starts a runtime that cannot intercept.
|
|
27
|
+
*
|
|
28
|
+
* Detection is by command name: argv[0], and any token that begins a new
|
|
29
|
+
* command after a shell operator, with leading `KEY=VAL` assignments skipped
|
|
30
|
+
* and the path and `.exe` decoration stripped. That is the honest 90%.
|
|
31
|
+
* `npm run dev` whose package script shells out to bun is undetectable from
|
|
32
|
+
* here, and guessing would cost false positives on names that merely start
|
|
33
|
+
* with the same letters (`bundle exec`).
|
|
34
|
+
*
|
|
35
|
+
* Returns the canonical runtime name (`bun` for `bunx` too) or null.
|
|
36
|
+
*/
|
|
37
|
+
export function detectUnsupportedRuntime(argv: readonly string[]): string | null {
|
|
38
|
+
let atCommandStart = true;
|
|
39
|
+
for (const token of argv) {
|
|
40
|
+
if (atCommandStart && ENV_ASSIGNMENT.test(token)) continue;
|
|
41
|
+
if (SHELL_OPERATORS.has(token)) {
|
|
42
|
+
atCommandStart = true;
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
if (atCommandStart) {
|
|
46
|
+
const runtime = UNSUPPORTED_RUNTIME_BINARIES.get(commandBasename(token));
|
|
47
|
+
if (runtime !== undefined) return runtime;
|
|
48
|
+
atCommandStart = false;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* The one warning. It has to say both halves of what is lost: the loader swap
|
|
56
|
+
* (interception itself) and the net guard (the socket backstop that would
|
|
57
|
+
* otherwise catch the egress), because the guard is installed by the same
|
|
58
|
+
* `--import`ed register module and is therefore just as absent.
|
|
59
|
+
*/
|
|
60
|
+
export function formatUnsupportedRuntimeWarning(runtime: string): string {
|
|
61
|
+
return (
|
|
62
|
+
` ⚠ runtime: pyric interception is not supported under \`${runtime}\`. It does not evaluate ` +
|
|
63
|
+
`Node loader hooks, so the child's firebase/firebase-admin imports will NOT be rewritten and ` +
|
|
64
|
+
`may reach LIVE Firebase. The net-guard socket backstop also only applies under Node, so it ` +
|
|
65
|
+
`will not catch that egress either. Run the command under \`node\` (or \`npx tsx\`) for the ` +
|
|
66
|
+
`sandbox swap. Warning only: nothing was blocked.\n`
|
|
67
|
+
);
|
|
68
|
+
}
|