@pyric/cli 0.1.0-alpha.20 → 0.1.0-alpha.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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/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.BOr2kwae.js +115 -0
- package/dist/serve/site-ui/_astro/app.DhAcImFD.js +1 -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.03a08f9t.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 +1 -1
- package/dist/serve/site-ui/docs/build/cloud-firestore/index.html +1 -1
- 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 +6 -2
- package/dist/serve/site-ui/docs/conformance-scores.md +5 -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/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/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 +2967 -1482
- package/dist/serve/site-ui/docs/messaging-compat/index.html +1 -1
- package/dist/serve/site-ui/docs/observe/resolve-runtime-status/index.html +1 -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/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 +2 -1
- 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 +1 -1
- package/dist/serve/site-ui/docs/pyric-cli-conformance-reference-api/index.html +2 -1
- 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 +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 +24 -2
- 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 +9 -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 +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 +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,17 @@
|
|
|
1
|
+
// Generated by scripts/generate-tool-family-registry.ts. Do not edit.
|
|
2
|
+
import type { ToolFamily } from './tool-families.js';
|
|
3
|
+
import conformance from './tool-family-records/conformance.js';
|
|
4
|
+
import firestoreData from './tool-family-records/firestore-data.js';
|
|
5
|
+
import firestoreInspect from './tool-family-records/firestore-inspect.js';
|
|
6
|
+
import firestoreRules from './tool-family-records/firestore-rules.js';
|
|
7
|
+
import firestoreSimulator from './tool-family-records/firestore-simulator.js';
|
|
8
|
+
import rtdbInspection from './tool-family-records/rtdb-inspection.js';
|
|
9
|
+
|
|
10
|
+
export const TOOL_FAMILIES = [
|
|
11
|
+
{ key: "conformance", ...conformance },
|
|
12
|
+
{ key: "firestore-data", ...firestoreData },
|
|
13
|
+
{ key: "firestore-inspect", ...firestoreInspect },
|
|
14
|
+
{ key: "firestore-rules", ...firestoreRules },
|
|
15
|
+
{ key: "firestore-simulator", ...firestoreSimulator },
|
|
16
|
+
{ key: "rtdb-inspection", ...rtdbInspection },
|
|
17
|
+
] as const satisfies readonly ToolFamily[];
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool family contract shared by both sides of the bridge.
|
|
3
|
+
*
|
|
4
|
+
* A family is authored as one record under `tool-family-records/`: its
|
|
5
|
+
* transport, its position in the default `tools/list` order, and the exact
|
|
6
|
+
* tool names its factory yields. `scripts/generate-tool-family-registry.ts`
|
|
7
|
+
* aggregates the records into `tool-families.generated.ts`. This module reads
|
|
8
|
+
* only that aggregate, so the browser bundle and the MCP process share one
|
|
9
|
+
* manifest without either importing the other's factories.
|
|
10
|
+
*
|
|
11
|
+
* Factories live in `server/tool-family-factories.ts` (Node) and
|
|
12
|
+
* `client/tool-family-factories.ts` (browser). Each map is typed against the
|
|
13
|
+
* family keys derived here, so a record without a factory, or a factory
|
|
14
|
+
* without a record, fails to compile.
|
|
15
|
+
*/
|
|
16
|
+
import { TOOL_FAMILIES } from './tool-families.generated.js';
|
|
17
|
+
|
|
18
|
+
export type ToolTransport = 'forwarded' | 'in-process';
|
|
19
|
+
|
|
20
|
+
/** Authored in one record file per family. The key is the filename without `.ts`; the generator adds it. */
|
|
21
|
+
export interface ToolFamilyRecord {
|
|
22
|
+
/** `forwarded`: executed by the browser sandbox peer. `in-process`: executed in the MCP process. */
|
|
23
|
+
readonly transport: ToolTransport;
|
|
24
|
+
/** Stable position in the default `tools/list` order. Unique across all records; authored with gaps of 10. */
|
|
25
|
+
readonly order: number;
|
|
26
|
+
/** Exact names the family factory yields for the default surface, in factory order. */
|
|
27
|
+
readonly tools: readonly string[];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface ToolFamily extends ToolFamilyRecord {
|
|
31
|
+
readonly key: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
type RegisteredFamily = (typeof TOOL_FAMILIES)[number];
|
|
35
|
+
export type ForwardedFamilyKey = Extract<RegisteredFamily, { transport: 'forwarded' }>['key'];
|
|
36
|
+
export type InProcessFamilyKey = Extract<RegisteredFamily, { transport: 'in-process' }>['key'];
|
|
37
|
+
|
|
38
|
+
function assertUnique(label: string, values: readonly (string | number)[]): void {
|
|
39
|
+
const seen = new Set<string | number>();
|
|
40
|
+
for (const value of values) {
|
|
41
|
+
if (seen.has(value)) throw new Error(`duplicate tool family ${label} '${value}'`);
|
|
42
|
+
seen.add(value);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function validateFamilies(families: readonly RegisteredFamily[]): readonly RegisteredFamily[] {
|
|
47
|
+
assertUnique('key', families.map((family) => family.key));
|
|
48
|
+
assertUnique('order', families.map((family) => family.order));
|
|
49
|
+
assertUnique('tool name', families.flatMap((family) => family.tools));
|
|
50
|
+
return [...families].sort((a, b) => a.order - b.order);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const FAMILIES_BY_ORDER = validateFamilies(TOOL_FAMILIES);
|
|
54
|
+
|
|
55
|
+
/** Families of one transport, sorted by `order`. Validates once at load: duplicate key, order, or tool name throws. */
|
|
56
|
+
export function toolFamilies<T extends ToolTransport>(
|
|
57
|
+
transport: T,
|
|
58
|
+
): readonly Extract<RegisteredFamily, { transport: T }>[] {
|
|
59
|
+
return FAMILIES_BY_ORDER.filter(
|
|
60
|
+
(family): family is Extract<RegisteredFamily, { transport: T }> =>
|
|
61
|
+
family.transport === transport,
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Fail closed when a factory yields a different name set from the records.
|
|
67
|
+
* Both sides call this with the same message so drift reads the same
|
|
68
|
+
* wherever it surfaces.
|
|
69
|
+
*/
|
|
70
|
+
export function assertExactToolNames(
|
|
71
|
+
label: string,
|
|
72
|
+
actual: readonly string[],
|
|
73
|
+
expected: readonly string[],
|
|
74
|
+
): void {
|
|
75
|
+
const actualSorted = [...actual].sort();
|
|
76
|
+
const expectedSorted = [...expected].sort();
|
|
77
|
+
if (
|
|
78
|
+
actualSorted.length !== expectedSorted.length ||
|
|
79
|
+
actualSorted.some((name, index) => name !== expectedSorted[index])
|
|
80
|
+
) {
|
|
81
|
+
throw new Error(
|
|
82
|
+
`${label} drifted from the default MCP contract\n` +
|
|
83
|
+
`expected: ${expected.join(', ')}\n` +
|
|
84
|
+
`actual: ${actual.join(', ')}`,
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ToolFamilyRecord } from '../tool-families.js';
|
|
2
|
+
export default {
|
|
3
|
+
transport: 'forwarded',
|
|
4
|
+
order: 20,
|
|
5
|
+
tools: [
|
|
6
|
+
'firestore_get_document',
|
|
7
|
+
'firestore_list_documents',
|
|
8
|
+
'firestore_create_document',
|
|
9
|
+
'firestore_add_document',
|
|
10
|
+
'firestore_update_document',
|
|
11
|
+
'firestore_delete_document',
|
|
12
|
+
'firestore_batch_write',
|
|
13
|
+
'firestore_query_where',
|
|
14
|
+
],
|
|
15
|
+
} as const satisfies ToolFamilyRecord;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ToolFamilyRecord } from '../tool-families.js';
|
|
2
|
+
export default {
|
|
3
|
+
transport: 'in-process',
|
|
4
|
+
order: 50,
|
|
5
|
+
tools: [
|
|
6
|
+
'firestore_simulate_rules',
|
|
7
|
+
'firestore_rules_stdlib_list',
|
|
8
|
+
'firestore_rules_stdlib_get',
|
|
9
|
+
'firestore_lint_rules',
|
|
10
|
+
'firestore_resolve_modules',
|
|
11
|
+
'rules_stdlib_list',
|
|
12
|
+
'rules_stdlib_get',
|
|
13
|
+
'rules_resolve_modules',
|
|
14
|
+
],
|
|
15
|
+
} as const satisfies ToolFamilyRecord;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ToolFamilyRecord } from '../tool-families.js';
|
|
2
|
+
export default {
|
|
3
|
+
transport: 'forwarded',
|
|
4
|
+
order: 10,
|
|
5
|
+
tools: [
|
|
6
|
+
'firestore_simulator_create',
|
|
7
|
+
'firestore_simulator_execute',
|
|
8
|
+
'firestore_simulator_read',
|
|
9
|
+
'firestore_simulator_batch',
|
|
10
|
+
'firestore_create_with_auto_id',
|
|
11
|
+
'firestore_simulator_undo',
|
|
12
|
+
'firestore_simulator_redo',
|
|
13
|
+
'firestore_simulator_events',
|
|
14
|
+
'firestore_simulator_transaction',
|
|
15
|
+
],
|
|
16
|
+
} as const satisfies ToolFamilyRecord;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Externalization presets and helpers for Node backend bundlers.
|
|
3
|
+
*
|
|
4
|
+
* Prevents backend bundlers (Rolldown, esbuild, tsup, Rollup, Vite, Webpack)
|
|
5
|
+
* from inlining Firebase and Firebase Admin SDKs into bundled server outputs,
|
|
6
|
+
* preserving runtime interception by `@pyric/cli/register` under `pyric sandbox`.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* RegExp patterns matching Firebase packages for bundlers that accept RegExp
|
|
11
|
+
* in their external configuration (Rolldown, Rollup, Vite, Webpack).
|
|
12
|
+
*/
|
|
13
|
+
export const pyricRollupExternals: readonly RegExp[] = Object.freeze([
|
|
14
|
+
/^firebase-admin(\/.*)?$/,
|
|
15
|
+
/^firebase(\/.*)?$/,
|
|
16
|
+
/^@firebase(\/.*)?$/,
|
|
17
|
+
]);
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Wildcard string patterns matching Firebase packages for bundlers that require
|
|
21
|
+
* string arrays with glob wildcards (esbuild, tsup).
|
|
22
|
+
*/
|
|
23
|
+
export const pyricEsbuildExternals: readonly string[] = Object.freeze([
|
|
24
|
+
'firebase-admin',
|
|
25
|
+
'firebase-admin/*',
|
|
26
|
+
'firebase',
|
|
27
|
+
'firebase/*',
|
|
28
|
+
'@firebase/*',
|
|
29
|
+
]);
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Universal predicate returning true if a module specifier belongs to Firebase
|
|
33
|
+
* or Firebase Admin SDK surfaces intercepted by Pyric.
|
|
34
|
+
*
|
|
35
|
+
* Compatible with bundlers that accept a function in their external setting
|
|
36
|
+
* (Rolldown, Rollup, Vite, Webpack).
|
|
37
|
+
*/
|
|
38
|
+
export function isPyricExternal(id: string): boolean {
|
|
39
|
+
if (typeof id !== 'string' || id.length === 0) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
return pyricRollupExternals.some((regex) => regex.test(id));
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Convenience presets mapping bundler names to their supported external pattern format.
|
|
47
|
+
*/
|
|
48
|
+
export const pyricExternals = Object.freeze({
|
|
49
|
+
rolldown: pyricRollupExternals,
|
|
50
|
+
rollup: pyricRollupExternals,
|
|
51
|
+
vite: pyricRollupExternals,
|
|
52
|
+
webpack: pyricRollupExternals,
|
|
53
|
+
esbuild: pyricEsbuildExternals,
|
|
54
|
+
tsup: pyricEsbuildExternals,
|
|
55
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@pyric/cli/bundler` — externalization presets and helpers for Node backend
|
|
3
|
+
* bundlers (Rolldown, esbuild, tsup, Rollup, Vite) to preserve `@pyric/cli/register`
|
|
4
|
+
* runtime sandbox interception.
|
|
5
|
+
*
|
|
6
|
+
* // rolldown.config.ts / rollup.config.js
|
|
7
|
+
* import { pyricExternals } from '@pyric/cli/bundler';
|
|
8
|
+
* export default { external: pyricExternals.rolldown };
|
|
9
|
+
*
|
|
10
|
+
* // vite.config.ts (SSR / Node backend builds)
|
|
11
|
+
* export default { build: { rollupOptions: { external: pyricExternals.vite } } };
|
|
12
|
+
*
|
|
13
|
+
* // tsup.config.ts / esbuild.config.mjs
|
|
14
|
+
* export default { external: pyricExternals.esbuild };
|
|
15
|
+
*/
|
|
16
|
+
export {
|
|
17
|
+
pyricRollupExternals,
|
|
18
|
+
pyricEsbuildExternals,
|
|
19
|
+
isPyricExternal,
|
|
20
|
+
pyricExternals,
|
|
21
|
+
} from './externals.js';
|
package/src/cli/cli.test.ts
CHANGED
|
@@ -461,47 +461,3 @@ describe('runInit', () => {
|
|
|
461
461
|
expect(io.getOut()).toContain('skipped package.json'); // unchanged merge
|
|
462
462
|
});
|
|
463
463
|
});
|
|
464
|
-
|
|
465
|
-
describe('scanForInlinedFirebase', () => {
|
|
466
|
-
it('flags a bundled chunk that inlines real-SDK endpoint hosts', async () => {
|
|
467
|
-
const { scanForInlinedFirebase } = await import('./serve.js');
|
|
468
|
-
const { mkdtempSync, mkdirSync, writeFileSync } = await import('node:fs');
|
|
469
|
-
const { tmpdir } = await import('node:os');
|
|
470
|
-
const { join } = await import('node:path');
|
|
471
|
-
const dir = mkdtempSync(join(tmpdir(), 'pyric-inline-scan-'));
|
|
472
|
-
mkdirSync(join(dir, 'assets'));
|
|
473
|
-
writeFileSync(
|
|
474
|
-
join(dir, 'assets', 'index-abc.js'),
|
|
475
|
-
'fetch("https://identitytoolkit.googleapis.com/v1/projects?key="+k)',
|
|
476
|
-
);
|
|
477
|
-
const hits = scanForInlinedFirebase(dir);
|
|
478
|
-
expect(hits).toEqual(['assets/index-abc.js']);
|
|
479
|
-
});
|
|
480
|
-
|
|
481
|
-
it('stays clean for an unbundled app importing firebase by bare specifier', async () => {
|
|
482
|
-
const { scanForInlinedFirebase } = await import('./serve.js');
|
|
483
|
-
const { mkdtempSync, writeFileSync } = await import('node:fs');
|
|
484
|
-
const { tmpdir } = await import('node:os');
|
|
485
|
-
const { join } = await import('node:path');
|
|
486
|
-
const dir = mkdtempSync(join(tmpdir(), 'pyric-inline-clean-'));
|
|
487
|
-
writeFileSync(
|
|
488
|
-
join(dir, 'main.js'),
|
|
489
|
-
"import { getAuth } from 'firebase/auth'; import { getFirestore } from 'firebase/firestore';",
|
|
490
|
-
);
|
|
491
|
-
expect(scanForInlinedFirebase(dir)).toEqual([]);
|
|
492
|
-
});
|
|
493
|
-
|
|
494
|
-
it('ignores hidden frameworks and build cache directories like .next and .git', async () => {
|
|
495
|
-
const { scanForInlinedFirebase } = await import('./serve.js');
|
|
496
|
-
const { mkdtempSync, mkdirSync, writeFileSync } = await import('node:fs');
|
|
497
|
-
const { tmpdir } = await import('node:os');
|
|
498
|
-
const { join } = await import('node:path');
|
|
499
|
-
const dir = mkdtempSync(join(tmpdir(), 'pyric-inline-ignore-'));
|
|
500
|
-
mkdirSync(join(dir, '.next'));
|
|
501
|
-
writeFileSync(
|
|
502
|
-
join(dir, '.next', 'bundle.js'),
|
|
503
|
-
'fetch("https://identitytoolkit.googleapis.com/v1/projects?key="+k)',
|
|
504
|
-
);
|
|
505
|
-
expect(scanForInlinedFirebase(dir)).toEqual([]);
|
|
506
|
-
});
|
|
507
|
-
});
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Detect a served frontend build that inlined the real Firebase SDK.
|
|
3
|
+
*
|
|
4
|
+
* The served import map remaps only bare `firebase/*` specifiers, so a plain
|
|
5
|
+
* `vite build` that compiled the SDK into an app chunk cannot be sandboxed:
|
|
6
|
+
* its calls reach real Google endpoints while the injected banner claims
|
|
7
|
+
* otherwise. `cli/serve.ts` refuses such a dist rather than serving it.
|
|
8
|
+
*
|
|
9
|
+
* Only the SDK fingerprint hosts are matched, never the full endpoint catalog.
|
|
10
|
+
* This check throws, and a dist can legitimately carry a bare callable URL, a
|
|
11
|
+
* public asset URL, or a `databaseURL` literal without any Firebase SDK in it.
|
|
12
|
+
*
|
|
13
|
+
* Backend bundles are deliberately out of scope. `withPyric` externalizes
|
|
14
|
+
* firebase and firebase-admin, the backend-bundler docs tell users to mark them
|
|
15
|
+
* external, and the net guard reports real egress at runtime with attribution,
|
|
16
|
+
* which a grep over build output cannot do.
|
|
17
|
+
*/
|
|
18
|
+
import { readdirSync, readFileSync, statSync } from 'node:fs';
|
|
19
|
+
import { join } from 'node:path';
|
|
20
|
+
import { SDK_FINGERPRINT_HOSTS } from '../google-endpoints.js';
|
|
21
|
+
|
|
22
|
+
/** Depth limit for the walk. */
|
|
23
|
+
const MAX_DEPTH = 4;
|
|
24
|
+
|
|
25
|
+
/** Total script files read. */
|
|
26
|
+
const MAX_FILES = 200;
|
|
27
|
+
|
|
28
|
+
/** Script extensions worth reading in served frontend output. */
|
|
29
|
+
const SCRIPT_FILE = /\.(js|mjs)$/;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Scan `dir` for inlined SDK fingerprints and return the offending paths,
|
|
33
|
+
* relative to `dir`. Bounded: depth 4, 200 script files, first hit per file.
|
|
34
|
+
*/
|
|
35
|
+
export function scanForInlinedFirebase(dir: string): string[] {
|
|
36
|
+
const hits: string[] = [];
|
|
37
|
+
let scanned = 0;
|
|
38
|
+
const walk = (current: string, rel: string, depth: number): void => {
|
|
39
|
+
if (depth > MAX_DEPTH || scanned >= MAX_FILES) return;
|
|
40
|
+
let names: string[];
|
|
41
|
+
try {
|
|
42
|
+
names = readdirSync(current);
|
|
43
|
+
} catch {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
for (const name of names) {
|
|
47
|
+
if (scanned >= MAX_FILES) return;
|
|
48
|
+
const path = join(current, name);
|
|
49
|
+
const relPath = rel ? `${rel}/${name}` : name;
|
|
50
|
+
let stat;
|
|
51
|
+
try {
|
|
52
|
+
stat = statSync(path);
|
|
53
|
+
} catch {
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
if (stat.isDirectory()) {
|
|
57
|
+
// The pyric namespace itself never lands in hosting.public, but a
|
|
58
|
+
// node_modules inside a served dir would be a scan-cost trap.
|
|
59
|
+
// Dot-directories (.next, .git, .pyric) are internal caches.
|
|
60
|
+
if (name === 'node_modules' || name.startsWith('.')) continue;
|
|
61
|
+
walk(path, relPath, depth + 1);
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
if (!SCRIPT_FILE.test(name)) continue;
|
|
65
|
+
scanned++;
|
|
66
|
+
let text: string;
|
|
67
|
+
try {
|
|
68
|
+
text = readFileSync(path, 'utf8');
|
|
69
|
+
} catch {
|
|
70
|
+
continue; // unreadable asset
|
|
71
|
+
}
|
|
72
|
+
if (SDK_FINGERPRINT_HOSTS.some((host) => text.includes(host))) hits.push(relPath);
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
walk(dir, '', 0);
|
|
76
|
+
return hits;
|
|
77
|
+
}
|
|
@@ -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;
|