@pyric/cli 0.1.0-alpha.19 → 0.1.0-alpha.20
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 +9 -9
- package/dist/cli/index.d.ts +2 -2
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +48 -42
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/mcp-proxy.js +3 -3
- package/dist/cli/mcp-proxy.js.map +1 -1
- package/dist/cli/parse-args.d.ts +1 -1
- package/dist/cli/parse-args.d.ts.map +1 -1
- package/dist/cli/parse-args.js +51 -15
- package/dist/cli/parse-args.js.map +1 -1
- package/dist/cli/pyric-config.d.ts +24 -0
- package/dist/cli/pyric-config.d.ts.map +1 -0
- package/dist/cli/pyric-config.js +28 -0
- package/dist/cli/pyric-config.js.map +1 -0
- package/dist/cli/{dev-runner.d.ts → sandbox-runner.d.ts} +33 -36
- package/dist/cli/sandbox-runner.d.ts.map +1 -0
- package/dist/cli/{dev-runner.js → sandbox-runner.js} +90 -55
- package/dist/cli/sandbox-runner.js.map +1 -0
- package/dist/cli/serve.d.ts +6 -4
- package/dist/cli/serve.d.ts.map +1 -1
- package/dist/cli/serve.js +99 -40
- package/dist/cli/serve.js.map +1 -1
- package/dist/cli/snapshot.js +5 -5
- package/dist/cli/snapshot.js.map +1 -1
- package/dist/cli/verify.js +1 -1
- package/dist/cli/verify.js.map +1 -1
- package/dist/functions-rtdb/development-runtime.js +1 -1
- package/dist/functions-rtdb/development-runtime.js.map +1 -1
- package/dist/functions-rtdb/project.js +8 -8
- package/dist/functions-rtdb/project.js.map +1 -1
- package/dist/next/guard.js +1 -1
- package/dist/next/guard.js.map +1 -1
- package/dist/remote/index.d.ts +1 -1
- package/dist/remote/index.js +9 -9
- package/dist/remote/index.js.map +1 -1
- package/dist/serve/bundler.js +10 -10
- package/dist/serve/bundler.js.map +1 -1
- package/dist/serve/entries/ai.d.ts.map +1 -1
- package/dist/serve/entries/ai.js +27 -1
- package/dist/serve/entries/ai.js.map +1 -1
- package/dist/serve/entries/auth-helper-dom.js +1 -1
- package/dist/serve/entries/auth-helper-dom.js.map +1 -1
- package/dist/serve/entries/auth-helper-runtime.js +1 -1
- package/dist/serve/entries/auth-helper-runtime.js.map +1 -1
- package/dist/serve/entries/firestore.js +3 -3
- package/dist/serve/entries/firestore.js.map +1 -1
- package/dist/serve/entries/keepalive.js +1 -1
- package/dist/serve/entries/keepalive.js.map +1 -1
- package/dist/serve/entries/runtime.js +21 -14
- package/dist/serve/entries/runtime.js.map +1 -1
- package/dist/serve/entries/storage.js +1 -1
- package/dist/serve/entries/storage.js.map +1 -1
- package/dist/serve/entries/worker-runtime.js +1 -1
- package/dist/serve/entries/worker-runtime.js.map +1 -1
- package/dist/serve/init-payload.d.ts +4 -0
- package/dist/serve/init-payload.d.ts.map +1 -1
- package/dist/serve/namespace.d.ts +6 -0
- package/dist/serve/namespace.d.ts.map +1 -1
- package/dist/serve/namespace.js +36 -5
- package/dist/serve/namespace.js.map +1 -1
- package/dist/serve/rules.d.ts.map +1 -1
- package/dist/serve/rules.js +44 -21
- package/dist/serve/rules.js.map +1 -1
- package/dist/serve/runtime/chip.d.ts.map +1 -1
- package/dist/serve/runtime/chip.js +32 -1
- package/dist/serve/runtime/chip.js.map +1 -1
- package/dist/serve/runtime/manifest.d.ts +1 -1
- package/dist/serve/runtime/manifest.d.ts.map +1 -1
- package/dist/serve/runtime/manifest.js +1 -1
- package/dist/serve/runtime/manifest.js.map +1 -1
- package/dist/serve/runtime/status.d.ts.map +1 -1
- package/dist/serve/runtime/status.js +23 -0
- package/dist/serve/runtime/status.js.map +1 -1
- package/dist/serve/sandbox-session.d.ts +1 -0
- package/dist/serve/sandbox-session.d.ts.map +1 -1
- package/dist/serve/sandbox-session.js +10 -4
- package/dist/serve/sandbox-session.js.map +1 -1
- package/dist/serve/server.d.ts +7 -0
- package/dist/serve/server.d.ts.map +1 -1
- package/dist/serve/server.js +15 -1
- package/dist/serve/server.js.map +1 -1
- package/dist/serve/site-ui/404.html +1 -1
- package/dist/serve/site-ui/_astro/{RulesCodeEditor.Bl-XMkhD.js → RulesCodeEditor.XtDmHOlN.js} +1 -1
- package/dist/serve/site-ui/_astro/_slug_.Da5VLhW1.css +1 -0
- package/dist/serve/site-ui/_astro/_studio_.BnfYCKoI.css +1 -0
- package/dist/serve/site-ui/_astro/app.B52xr-DK.js +1 -0
- package/dist/serve/site-ui/_astro/app.DWBraPUw.js +12 -0
- package/dist/serve/site-ui/_astro/app.pMSnN6Qw.css +1 -0
- package/dist/serve/site-ui/_astro/{chess-showcase.Dh5D8kqe.js → chess-showcase.B72XYeoh.js} +1 -1
- package/dist/serve/site-ui/_astro/{example-runtime.CuyAjjiG.js → example-runtime.C25_lx6Z.js} +1 -1
- package/dist/serve/site-ui/_astro/index.Tb-31efc.css +1 -0
- package/dist/serve/site-ui/_astro/index.UkCBr-_0.css +1 -0
- package/dist/serve/site-ui/_astro/{sandbox-controls.BP4M5f1M.js → sandbox-controls.DEpnKg-O.js} +11 -11
- package/dist/serve/site-ui/_astro/{seed.CSUkloMi.js → seed.Co0yUJY5.js} +1 -1
- package/dist/serve/site-ui/_astro/{writes.C57paAj2.js → writes.rpjrFzmu.js} +7 -4
- package/dist/serve/site-ui/auth/index.html +5 -3
- package/dist/serve/site-ui/david-east.jpg +0 -0
- package/dist/serve/site-ui/docs/_rhythm/index.html +6 -3
- package/dist/serve/site-ui/docs/_rhythm.md +1 -1
- package/dist/serve/site-ui/docs/agent/set-up-your-agent/index.html +18 -15
- package/dist/serve/site-ui/docs/agent/set-up-your-agent.md +16 -16
- package/dist/serve/site-ui/docs/agent/watch-and-review/index.html +6 -5
- package/dist/serve/site-ui/docs/agent/watch-and-review.md +1 -5
- package/dist/serve/site-ui/docs/agent/work-with-an-agent/index.html +8 -5
- package/dist/serve/site-ui/docs/agent/work-with-an-agent.md +4 -4
- package/dist/serve/site-ui/docs/ai-compat/index.html +5 -2
- package/dist/serve/site-ui/docs/api-reference/index.html +6 -2
- package/dist/serve/site-ui/docs/api-reference.md +1 -0
- package/dist/serve/site-ui/docs/app-compat/index.html +5 -2
- package/dist/serve/site-ui/docs/auth-compat/index.html +5 -2
- package/dist/serve/site-ui/docs/build/ai-logic/index.html +5 -2
- package/dist/serve/site-ui/docs/build/authentication/index.html +7 -4
- package/dist/serve/site-ui/docs/build/authentication.md +2 -2
- package/dist/serve/site-ui/docs/build/cloud-firestore/index.html +5 -2
- package/dist/serve/site-ui/docs/build/cloud-messaging/index.html +5 -2
- package/dist/serve/site-ui/docs/build/cloud-storage/index.html +6 -3
- package/dist/serve/site-ui/docs/build/cloud-storage.md +1 -1
- package/dist/serve/site-ui/docs/build/realtime-database/index.html +9 -6
- package/dist/serve/site-ui/docs/build/realtime-database.md +4 -4
- package/dist/serve/site-ui/docs/conformance-scores/index.html +5 -2
- package/dist/serve/site-ui/docs/create-pyric-reference-api/index.html +6 -3
- package/dist/serve/site-ui/docs/create-pyric-reference-api.md +1 -1
- package/dist/serve/site-ui/docs/database-compat/index.html +5 -2
- package/dist/serve/site-ui/docs/examples/chess/index.html +5 -2
- package/dist/serve/site-ui/docs/examples/index.html +5 -2
- package/dist/serve/site-ui/docs/firestore-compat/index.html +5 -2
- package/dist/serve/site-ui/docs/functions-rtdb-compat/index.html +5 -2
- package/dist/serve/site-ui/docs/get-started/how-the-swap-works/index.html +9 -6
- package/dist/serve/site-ui/docs/get-started/how-the-swap-works.md +5 -5
- package/dist/serve/site-ui/docs/get-started/nextjs/index.html +9 -6
- package/dist/serve/site-ui/docs/get-started/nextjs.md +4 -4
- package/dist/serve/site-ui/docs/get-started/start-building/index.html +14 -9
- package/dist/serve/site-ui/docs/get-started/start-building.md +16 -10
- package/dist/serve/site-ui/docs/get-started/vite/index.html +6 -3
- package/dist/serve/site-ui/docs/get-started/vite.md +1 -1
- package/dist/serve/site-ui/docs/index.json +180 -150
- package/dist/serve/site-ui/docs/messaging-compat/index.html +5 -2
- package/dist/serve/site-ui/docs/observe/resolve-runtime-status/index.html +5 -2
- package/dist/serve/site-ui/docs/observe/see-whats-happening/index.html +6 -4
- package/dist/serve/site-ui/docs/observe/see-whats-happening.md +2 -4
- package/dist/serve/site-ui/docs/observe/shape-your-data/index.html +9 -6
- package/dist/serve/site-ui/docs/observe/shape-your-data.md +4 -4
- package/dist/serve/site-ui/docs/overview/index.html +16 -10
- package/dist/serve/site-ui/docs/overview.md +19 -11
- package/dist/serve/site-ui/docs/pyric-admin-app-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-admin-auth-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-admin-database-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-admin-firestore-reference-api/index.html +8 -5
- package/dist/serve/site-ui/docs/pyric-admin-firestore-reference-api.md +3 -3
- package/dist/serve/site-ui/docs/pyric-admin-messaging-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-admin-reference-api/index.html +501 -0
- package/dist/serve/site-ui/docs/pyric-admin-reference-api.md +587 -0
- package/dist/serve/site-ui/docs/pyric-admin-storage-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-ai-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-ai-scripting-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-app-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-auth-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-cli-assurance-browser-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-cli-assurance-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-cli-bridge-client-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-cli-bridge-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-cli-conformance-browser-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-cli-conformance-docs-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-cli-conformance-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-cli-credentials-node-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-cli-discover-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-cli-next-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-cli-register-app-bridge-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-cli-register-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-cli-remote-reference-api/index.html +6 -3
- package/dist/serve/site-ui/docs/pyric-cli-remote-reference-api.md +1 -1
- package/dist/serve/site-ui/docs/pyric-cli-serve-worker-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-cli-verify-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-cli-vite-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-database-reference-api/index.html +166 -95
- package/dist/serve/site-ui/docs/pyric-database-reference-api.md +107 -1
- package/dist/serve/site-ui/docs/pyric-firestore-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-messaging-reference-api/index.html +10 -4
- package/dist/serve/site-ui/docs/pyric-messaging-reference-api.md +5 -2
- package/dist/serve/site-ui/docs/pyric-messaging-sw-reference-api/index.html +10 -4
- package/dist/serve/site-ui/docs/pyric-messaging-sw-reference-api.md +5 -2
- package/dist/serve/site-ui/docs/pyric-rules-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-sandbox-database-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-sandbox-firestore-reference-api/index.html +6 -3
- package/dist/serve/site-ui/docs/pyric-sandbox-firestore-reference-api.md +2 -2
- package/dist/serve/site-ui/docs/pyric-sandbox-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-storage-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-ui-agents-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-ui-auth-hooks-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-ui-auth-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-ui-events-hooks-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-ui-events-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-ui-firestore-hooks-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-ui-firestore-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-ui-primitives-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-ui-rtdb-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-ui-rules-hooks-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-ui-rules-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-ui-storage-hooks-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-ui-storage-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-ui-traffic-hooks-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/pyric-ui-traffic-reference-api/index.html +5 -2
- package/dist/serve/site-ui/docs/reference/cli/index.html +153 -0
- package/dist/serve/site-ui/docs/reference/cli.md +114 -0
- package/dist/serve/site-ui/docs/rules-compat/index.html +5 -2
- package/dist/serve/site-ui/docs/secure/audit-your-rules/index.html +5 -2
- package/dist/serve/site-ui/docs/secure/firestore-rules-limits/index.html +5 -2
- package/dist/serve/site-ui/docs/secure/read-a-denial/index.html +6 -3
- package/dist/serve/site-ui/docs/secure/read-a-denial.md +1 -1
- package/dist/serve/site-ui/docs/secure/rtdb-rules-in-typescript/index.html +5 -2
- package/dist/serve/site-ui/docs/secure/rules-standard-library/index.html +5 -2
- package/dist/serve/site-ui/docs/secure/secure-it-with-rules/index.html +5 -2
- package/dist/serve/site-ui/docs/secure/simulate-and-lint/index.html +5 -2
- package/dist/serve/site-ui/docs/secure/write-a-rules-test-suite/index.html +5 -2
- package/dist/serve/site-ui/docs/ship/ship-to-production/index.html +7 -4
- package/dist/serve/site-ui/docs/ship/ship-to-production.md +2 -2
- package/dist/serve/site-ui/docs/ship/test-in-node/index.html +9 -6
- package/dist/serve/site-ui/docs/ship/test-in-node.md +4 -4
- package/dist/serve/site-ui/docs/storage-compat/index.html +5 -2
- package/dist/serve/site-ui/docs/trust/how-we-know-it-matches-firebase/index.html +5 -2
- package/dist/serve/site-ui/docs/trust/rules-standard-library/index.html +5 -2
- package/dist/serve/site-ui/docs/trust/versioning-and-compatibility/index.html +5 -2
- package/dist/serve/site-ui/docs/tutorial/index.html +10 -7
- package/dist/serve/site-ui/docs/tutorial.md +4 -4
- package/dist/serve/site-ui/examples/chess/index.html +4 -2
- package/dist/serve/site-ui/firestore/index.html +5 -3
- package/dist/serve/site-ui/hero-charcoal.jpg +0 -0
- package/dist/serve/site-ui/index.html +9 -7
- package/dist/serve/site-ui/llms.txt +4 -3
- package/dist/serve/site-ui/pyric-campfire-full.png +0 -0
- package/dist/serve/site-ui/pyric-campfire.png +0 -0
- package/dist/serve/site-ui/rtdb/index.html +5 -3
- package/dist/serve/site-ui/settings/index.html +5 -3
- package/dist/serve/site-ui/storage/index.html +5 -3
- package/dist/serve/site-ui/studio/index.html +13 -0
- package/dist/serve/site-ui/studio-routes.json +1 -1
- package/dist/serve/site-ui/traffic/index.html +5 -3
- package/dist/serve/studio/routes.d.ts +9 -0
- package/dist/serve/studio/routes.d.ts.map +1 -1
- package/dist/serve/studio/routes.js +47 -7
- package/dist/serve/studio/routes.js.map +1 -1
- package/dist/serve/vite-ai-config.d.ts.map +1 -1
- package/dist/serve/vite-ai-config.js +38 -8
- package/dist/serve/vite-ai-config.js.map +1 -1
- package/dist/serve/vite-module-swap.d.ts.map +1 -1
- package/dist/serve/vite-module-swap.js +0 -28
- package/dist/serve/vite-module-swap.js.map +1 -1
- package/dist/serve/vite-sandbox-generation.d.ts +1 -1
- package/dist/serve/vite-sandbox-generation.d.ts.map +1 -1
- package/dist/serve/vite-sandbox-generation.js +1 -1
- package/dist/serve/vite-sandbox-generation.js.map +1 -1
- package/dist/serve/worker/client/disconnect.js +1 -1
- package/dist/serve/worker/client/disconnect.js.map +1 -1
- package/dist/serve/worker/client/presence.d.ts.map +1 -1
- package/dist/serve/worker/client/presence.js +18 -5
- package/dist/serve/worker/client/presence.js.map +1 -1
- package/dist/serve/worker/host-ai.d.ts.map +1 -1
- package/dist/serve/worker/host-ai.js +15 -0
- package/dist/serve/worker/host-ai.js.map +1 -1
- package/dist/serve/worker/protocol.d.ts +4 -0
- package/dist/serve/worker/protocol.d.ts.map +1 -1
- package/dist/serve/worker/protocol.js.map +1 -1
- package/dist/serve/worker/serve-init.d.ts.map +1 -1
- package/dist/serve/worker/serve-init.js +7 -1
- package/dist/serve/worker/serve-init.js.map +1 -1
- package/package.json +5 -5
- package/src/cli/cli.test.ts +2 -2
- package/src/cli/index.ts +48 -42
- package/src/cli/mcp-proxy.ts +4 -4
- package/src/cli/parse-args.ts +61 -15
- package/src/cli/pyric-config.ts +45 -0
- package/src/cli/{dev-runner.ts → sandbox-runner.ts} +117 -72
- package/src/cli/serve.ts +115 -47
- package/src/cli/snapshot.ts +5 -5
- package/src/cli/verify.ts +1 -1
- package/src/functions-rtdb/development-runtime.ts +1 -1
- package/src/functions-rtdb/project.ts +8 -8
- package/src/next/guard.ts +1 -1
- package/src/remote/index.ts +9 -9
- package/src/serve/bundler.ts +10 -10
- package/src/serve/entries/ai.ts +27 -1
- package/src/serve/entries/auth-helper-dom.ts +1 -1
- package/src/serve/entries/auth-helper-runtime.ts +1 -1
- package/src/serve/entries/firestore.ts +3 -3
- package/src/serve/entries/keepalive.ts +1 -1
- package/src/serve/entries/runtime.ts +19 -14
- package/src/serve/entries/storage.ts +1 -1
- package/src/serve/entries/worker-runtime.ts +1 -1
- package/src/serve/init-payload.ts +4 -0
- package/src/serve/namespace.ts +44 -5
- package/src/serve/rules.ts +47 -22
- package/src/serve/runtime/chip.ts +38 -1
- package/src/serve/runtime/manifest.ts +1 -1
- package/src/serve/runtime/status.ts +24 -0
- package/src/serve/sandbox-session.ts +10 -4
- package/src/serve/server.ts +18 -1
- package/src/serve/studio/routes.ts +63 -7
- package/src/serve/vite-ai-config.ts +37 -7
- package/src/serve/vite-module-swap.ts +0 -28
- package/src/serve/vite-sandbox-generation.ts +1 -1
- package/src/serve/worker/client/disconnect.ts +1 -1
- package/src/serve/worker/client/presence.ts +25 -5
- package/src/serve/worker/host-ai.ts +15 -0
- package/src/serve/worker/protocol.ts +2 -1
- package/src/serve/worker/serve-init.ts +5 -1
- package/README.md.orig +0 -145
- package/dist/cli/dev-runner.d.ts.map +0 -1
- package/dist/cli/dev-runner.js.map +0 -1
- package/dist/serve/site-ui/_astro/_slug_.CXh9yTP1.css +0 -1
- package/dist/serve/site-ui/_astro/_slug_.CupVK4TM.css +0 -1
- package/dist/serve/site-ui/_astro/_studio_.CfxiQWkk.css +0 -1
- package/dist/serve/site-ui/_astro/app.BsFsMjn0.css +0 -1
- package/dist/serve/site-ui/_astro/app.Ce3MTLQm.js +0 -1
- package/dist/serve/site-ui/_astro/app.taqzyjD0.js +0 -11
- package/dist/serve/site-ui/docs/trust/storage-rules-stdlib-research/index.html +0 -582
- package/dist/serve/site-ui/docs/trust/storage-rules-stdlib-research.md +0 -448
package/src/cli/parse-args.ts
CHANGED
|
@@ -12,17 +12,54 @@ export interface ParsedArgs {
|
|
|
12
12
|
subcommand: string | null;
|
|
13
13
|
flags: Map<string, FlagValue>;
|
|
14
14
|
positional: string[];
|
|
15
|
-
/** Everything after a bare `--`, verbatim (e.g. `pyric
|
|
15
|
+
/** Everything after a bare `--`, verbatim (e.g. `pyric sandbox -- npm start`).
|
|
16
16
|
* Optional so hand-built ParsedArgs literals stay valid. */
|
|
17
17
|
passthrough?: string[];
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
export type FlagValue = string | boolean | Array<string | boolean>;
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
const BOOLEAN_FLAGS = new Set([
|
|
23
|
+
'json',
|
|
24
|
+
'bridge',
|
|
25
|
+
'ui',
|
|
26
|
+
'no-ui',
|
|
27
|
+
'no-open',
|
|
28
|
+
'no-run',
|
|
29
|
+
'no-cache',
|
|
30
|
+
'no-watch',
|
|
31
|
+
'no-capture',
|
|
32
|
+
'persist',
|
|
33
|
+
'fresh',
|
|
34
|
+
'force',
|
|
35
|
+
'permissive',
|
|
36
|
+
'help',
|
|
37
|
+
'version',
|
|
38
|
+
]);
|
|
39
|
+
|
|
40
|
+
function isBooleanFlag(key: string): boolean {
|
|
41
|
+
return BOOLEAN_FLAGS.has(key) || key.startsWith('no-');
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const SHORT_VALUE_ALIASES: ReadonlyMap<string, string> = new Map([
|
|
45
|
+
['p', 'port'],
|
|
46
|
+
]);
|
|
47
|
+
|
|
48
|
+
function consumeFlag(
|
|
49
|
+
flags: Map<string, FlagValue>,
|
|
50
|
+
key: string,
|
|
51
|
+
argv: string[],
|
|
52
|
+
currentIndex: number,
|
|
53
|
+
canTakeValue: boolean,
|
|
54
|
+
): number {
|
|
55
|
+
const next = argv[currentIndex + 1];
|
|
56
|
+
if (canTakeValue && next !== undefined && !next.startsWith('-')) {
|
|
57
|
+
setFlag(flags, key, next);
|
|
58
|
+
return currentIndex + 1;
|
|
59
|
+
}
|
|
60
|
+
setFlag(flags, key, true);
|
|
61
|
+
return currentIndex;
|
|
62
|
+
}
|
|
26
63
|
|
|
27
64
|
export function parseArgs(argv: string[]): ParsedArgs {
|
|
28
65
|
const flags = new Map<string, FlagValue>();
|
|
@@ -38,26 +75,31 @@ export function parseArgs(argv: string[]): ParsedArgs {
|
|
|
38
75
|
}
|
|
39
76
|
if (arg === '--') {
|
|
40
77
|
// Everything after a bare `--` belongs to the child command, verbatim
|
|
41
|
-
// — never parsed as flags (`pyric
|
|
78
|
+
// — never parsed as flags (`pyric sandbox -- npm start --port 3000`).
|
|
42
79
|
passthrough.push(...argv.slice(i + 1).filter((a): a is string => a !== undefined));
|
|
43
80
|
break;
|
|
44
81
|
}
|
|
82
|
+
if (isExecutionSubcommand(subcommand) && positional.length > 0) {
|
|
83
|
+
positional.push(arg);
|
|
84
|
+
i += 1;
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
45
87
|
if (arg.startsWith('--')) {
|
|
46
88
|
const eq = arg.indexOf('=');
|
|
47
89
|
if (eq !== -1) {
|
|
48
90
|
setFlag(flags, arg.slice(2, eq), arg.slice(eq + 1));
|
|
49
91
|
} else {
|
|
50
92
|
const key = arg.slice(2);
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
93
|
+
i = consumeFlag(flags, key, argv, i, !isBooleanFlag(key));
|
|
94
|
+
}
|
|
95
|
+
} else if (arg.startsWith('-') && arg !== '-') {
|
|
96
|
+
const raw = arg.slice(1);
|
|
97
|
+
const longKey = SHORT_VALUE_ALIASES.get(raw);
|
|
98
|
+
if (longKey !== undefined) {
|
|
99
|
+
i = consumeFlag(flags, longKey, argv, i, true);
|
|
100
|
+
} else {
|
|
101
|
+
setFlag(flags, raw, true);
|
|
58
102
|
}
|
|
59
|
-
} else if (arg.startsWith('-')) {
|
|
60
|
-
setFlag(flags, arg.slice(1), true);
|
|
61
103
|
} else if (subcommand === null) {
|
|
62
104
|
subcommand = arg;
|
|
63
105
|
} else {
|
|
@@ -68,6 +110,10 @@ export function parseArgs(argv: string[]): ParsedArgs {
|
|
|
68
110
|
return { subcommand, flags, positional, passthrough };
|
|
69
111
|
}
|
|
70
112
|
|
|
113
|
+
function isExecutionSubcommand(subcommand: string | null): boolean {
|
|
114
|
+
return subcommand === 'sandbox';
|
|
115
|
+
}
|
|
116
|
+
|
|
71
117
|
function setFlag(flags: Map<string, FlagValue>, key: string, value: string | boolean): void {
|
|
72
118
|
const current = flags.get(key);
|
|
73
119
|
if (current === undefined) {
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reader for the optional project-level `pyric.json` configuration file.
|
|
3
|
+
*
|
|
4
|
+
* Configures defaults for `pyric sandbox` (such as a default `command`,
|
|
5
|
+
* custom `port`, or explicit `rules` paths) without requiring CLI flags
|
|
6
|
+
* or magic process sniffing.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { readFile } from 'node:fs/promises';
|
|
10
|
+
import { join } from 'node:path';
|
|
11
|
+
|
|
12
|
+
export interface PyricRulesConfig {
|
|
13
|
+
firestore?: string;
|
|
14
|
+
database?: string;
|
|
15
|
+
storage?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface PyricConfig {
|
|
19
|
+
/** Default command to execute under the sandbox if none is passed on CLI. */
|
|
20
|
+
command?: string;
|
|
21
|
+
/** Local port to bind the Pyric sandbox host. */
|
|
22
|
+
port?: number;
|
|
23
|
+
/** Path to Firestore, RTDB, or Storage rules files. */
|
|
24
|
+
rules?: string | PyricRulesConfig;
|
|
25
|
+
/** Project ID label for emulation. */
|
|
26
|
+
project?: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export async function readPyricConfig(cwd: string = process.cwd()): Promise<PyricConfig> {
|
|
30
|
+
const path = join(cwd, 'pyric.json');
|
|
31
|
+
let raw: string;
|
|
32
|
+
try {
|
|
33
|
+
raw = await readFile(path, 'utf-8');
|
|
34
|
+
} catch (e) {
|
|
35
|
+
if ((e as NodeJS.ErrnoException).code === 'ENOENT') return {};
|
|
36
|
+
throw e;
|
|
37
|
+
}
|
|
38
|
+
try {
|
|
39
|
+
return JSON.parse(raw) as PyricConfig;
|
|
40
|
+
} catch (e) {
|
|
41
|
+
throw new Error(
|
|
42
|
+
`pyric: failed to parse pyric.json: ${e instanceof Error ? e.message : String(e)}`,
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The `pyric
|
|
2
|
+
* The `pyric sandbox` child runner starts the configured application command
|
|
3
|
+
* after the host is ready:
|
|
3
4
|
* after the host is up, run the user's OWN dev command with the environment
|
|
4
5
|
* activated so their unchanged firebase-admin/firebase imports resolve to the
|
|
5
6
|
* pyric sandbox:
|
|
@@ -7,23 +8,20 @@
|
|
|
7
8
|
* PYRIC_SANDBOX=remote:<serve url> (the activator)
|
|
8
9
|
* NODE_OPTIONS += --import @pyric/cli/register (the substitution seam)
|
|
9
10
|
*
|
|
10
|
-
* Child-command precedence:
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* defaults to host-only (an explicit `--` still wins — agents can opt in).
|
|
11
|
+
* Child-command precedence: `--no-run`, an explicit command, `--json`, the
|
|
12
|
+
* `pyric.json` command, then host-only. An explicit command still runs with
|
|
13
|
+
* `--json`.
|
|
14
14
|
*
|
|
15
15
|
* Everything decision-shaped here is pure and exported for the unit suite;
|
|
16
16
|
* only `spawnDevChild` touches the process table.
|
|
17
17
|
*/
|
|
18
18
|
import { spawn, type ChildProcess } from 'node:child_process';
|
|
19
|
-
import { existsSync, readFileSync } from 'node:fs';
|
|
20
|
-
import { join } from 'node:path';
|
|
21
19
|
|
|
22
20
|
// ─── First-run race guard ───────────────────────────────────────────────────
|
|
23
21
|
|
|
24
22
|
/**
|
|
25
23
|
* Wait (bounded) for a browser tab to register as the bridge's sandbox peer
|
|
26
|
-
* before the child spawns. `pyric
|
|
24
|
+
* before the child spawns. `pyric sandbox` opens the tab and spawns the child in
|
|
27
25
|
* the same breath; a child whose first line is a sandbox op otherwise races
|
|
28
26
|
* the tab's boot and dies on the no-tab fail-fast — the exact first-run of
|
|
29
27
|
* the two-command story. Polls `/__pyric/health` (`sandboxConnected`).
|
|
@@ -63,65 +61,74 @@ export async function waitForSandboxPeer(
|
|
|
63
61
|
|
|
64
62
|
// ─── Child-command resolution (pure) ───────────────────────────────────────
|
|
65
63
|
|
|
66
|
-
export
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
if (existsSync(join(cwd, 'pnpm-lock.yaml'))) return 'pnpm';
|
|
72
|
-
if (existsSync(join(cwd, 'yarn.lock'))) return 'yarn';
|
|
73
|
-
return 'npm';
|
|
64
|
+
export interface SandboxChildPlan {
|
|
65
|
+
/** argv to spawn — argv[0] is the executable. */
|
|
66
|
+
argv: string[];
|
|
67
|
+
/** Human-readable command for the pre-spawn line. */
|
|
68
|
+
label: string;
|
|
74
69
|
}
|
|
75
70
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
71
|
+
export type DevChildPlan = SandboxChildPlan;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Tokenize a command string into an argv array, preserving quoted strings.
|
|
75
|
+
*/
|
|
76
|
+
export function parseCommandString(cmd: string): string[] {
|
|
77
|
+
const parts: string[] = [];
|
|
78
|
+
const regex = /[^\s"']+|"([^"]*)"|'([^']*)'/g;
|
|
79
|
+
let match: RegExpExecArray | null;
|
|
80
|
+
while ((match = regex.exec(cmd)) !== null) {
|
|
81
|
+
if (match[1] !== undefined) {
|
|
82
|
+
parts.push(match[1]);
|
|
83
|
+
} else if (match[2] !== undefined) {
|
|
84
|
+
parts.push(match[2]);
|
|
85
|
+
} else {
|
|
86
|
+
parts.push(match[0]);
|
|
87
|
+
}
|
|
86
88
|
}
|
|
89
|
+
return parts;
|
|
87
90
|
}
|
|
88
91
|
|
|
89
|
-
export interface
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
92
|
+
export interface ResolveSandboxChildOptions {
|
|
93
|
+
explicitCommand?: string[] | null;
|
|
94
|
+
passthrough?: string[];
|
|
95
|
+
configCommand?: string | null;
|
|
96
|
+
noRun?: boolean;
|
|
97
|
+
json?: boolean;
|
|
94
98
|
}
|
|
95
99
|
|
|
96
100
|
/**
|
|
97
101
|
* Decide what (if anything) to run after the host is up.
|
|
98
102
|
*
|
|
99
|
-
*
|
|
100
|
-
* --no-run
|
|
101
|
-
*
|
|
102
|
-
* --json (no
|
|
103
|
-
*
|
|
104
|
-
* none of the above
|
|
105
|
-
*
|
|
106
|
-
* A `dev` script that itself invokes `pyric dev` is treated as absent —
|
|
107
|
-
* running it would recurse forever (pyric dev → npm run dev → pyric dev …).
|
|
103
|
+
* Precedence:
|
|
104
|
+
* --no-run → null, always
|
|
105
|
+
* explicit CLI command (args or `--`) → that command (wins over everything else)
|
|
106
|
+
* --json (with no explicit command) → null (machine mode defaults to host-only)
|
|
107
|
+
* pyric.json `command` → parsed command argv
|
|
108
|
+
* none of the above → null (host-only)
|
|
108
109
|
*/
|
|
109
|
-
export function
|
|
110
|
-
passthrough: string[];
|
|
111
|
-
noRun: boolean;
|
|
112
|
-
json: boolean;
|
|
113
|
-
devScript: string | null;
|
|
114
|
-
packageManager: PackageManager;
|
|
115
|
-
}): DevChildPlan | null {
|
|
110
|
+
export function resolveSandboxChild(opts: ResolveSandboxChildOptions): SandboxChildPlan | null {
|
|
116
111
|
if (opts.noRun) return null;
|
|
117
|
-
|
|
118
|
-
|
|
112
|
+
|
|
113
|
+
let activeCommand: string[] | null = null;
|
|
114
|
+
if (opts.explicitCommand && opts.explicitCommand.length > 0) {
|
|
115
|
+
activeCommand = opts.explicitCommand;
|
|
116
|
+
} else if (opts.passthrough && opts.passthrough.length > 0) {
|
|
117
|
+
activeCommand = opts.passthrough;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (activeCommand !== null) {
|
|
121
|
+
return { argv: [...activeCommand], label: activeCommand.join(' ') };
|
|
119
122
|
}
|
|
123
|
+
|
|
120
124
|
if (opts.json) return null;
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
125
|
+
|
|
126
|
+
if (opts.configCommand && opts.configCommand.trim().length > 0) {
|
|
127
|
+
const trimmed = opts.configCommand.trim();
|
|
128
|
+
const argv = parseCommandString(trimmed);
|
|
129
|
+
return { argv, label: trimmed };
|
|
124
130
|
}
|
|
131
|
+
|
|
125
132
|
return null;
|
|
126
133
|
}
|
|
127
134
|
|
|
@@ -215,37 +222,73 @@ export function createLinePrefixer(
|
|
|
215
222
|
|
|
216
223
|
// ─── Spawn + lifecycle ─────────────────────────────────────────────────────
|
|
217
224
|
|
|
218
|
-
|
|
219
|
-
|
|
225
|
+
/** How long a signalled child may linger before SIGKILL. */
|
|
226
|
+
const FORCE_KILL_AFTER_MS = 2_000;
|
|
227
|
+
|
|
228
|
+
const SHELL_OPERATORS = new Set(['&&', '||', '|', ';', '&']);
|
|
229
|
+
|
|
230
|
+
export interface SandboxChildHandle {
|
|
220
231
|
exited: Promise<number>;
|
|
221
|
-
/** Forward a signal (Ctrl-C / SIGTERM). Marks the exit as user-initiated
|
|
222
|
-
* so the propagated code is 0, and SIGKILLs a child that lingers. */
|
|
223
232
|
signal(sig: NodeJS.Signals): void;
|
|
224
233
|
child: ChildProcess;
|
|
225
234
|
}
|
|
226
235
|
|
|
227
|
-
|
|
228
|
-
const FORCE_KILL_AFTER_MS = 2_000;
|
|
236
|
+
export type DevChildHandle = SandboxChildHandle;
|
|
229
237
|
|
|
230
238
|
/**
|
|
231
239
|
* Spawn the child with inherited stdin and `[dev]`-prefixed stdout/stderr.
|
|
232
240
|
* In `--json` mode ALL child output goes to stderr — stdout carries exactly
|
|
233
241
|
* the one machine line (the serve --json contract).
|
|
234
242
|
*/
|
|
235
|
-
export function
|
|
236
|
-
plan:
|
|
243
|
+
export function spawnSandboxChild(
|
|
244
|
+
plan: SandboxChildPlan,
|
|
237
245
|
opts: { cwd: string; env: NodeJS.ProcessEnv; json: boolean },
|
|
238
|
-
):
|
|
239
|
-
const
|
|
240
|
-
const
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
246
|
+
): SandboxChildHandle {
|
|
247
|
+
const parts = [...plan.argv];
|
|
248
|
+
const env: NodeJS.ProcessEnv = { ...opts.env };
|
|
249
|
+
|
|
250
|
+
// 1. Extract leading KEY=VAL assignments (e.g. PORT=8080 node server.js)
|
|
251
|
+
while (parts.length > 0 && /^[A-Za-z_][A-Za-z0-9_]*=/.test(parts[0]!)) {
|
|
252
|
+
const token = parts.shift()!;
|
|
253
|
+
const eq = token.indexOf('=');
|
|
254
|
+
const key = token.slice(0, eq);
|
|
255
|
+
const val = token.slice(eq + 1);
|
|
256
|
+
env[key] = val;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// 2. Check for discrete shell operators (&&, ||, |, ;) among top-level tokens
|
|
260
|
+
const hasShellOperators = parts.some((token) => SHELL_OPERATORS.has(token));
|
|
261
|
+
|
|
262
|
+
// 3. Warn if runtime is bun or deno
|
|
263
|
+
if (parts.length > 0 && (parts[0] === 'bun' || parts[0] === 'deno')) {
|
|
264
|
+
const runner = parts[0];
|
|
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
|
+
}
|
|
272
|
+
|
|
273
|
+
const [command, ...args] = parts;
|
|
274
|
+
let child: ChildProcess;
|
|
275
|
+
if (hasShellOperators) {
|
|
276
|
+
child = spawn(plan.label, [], {
|
|
277
|
+
cwd: opts.cwd,
|
|
278
|
+
env,
|
|
279
|
+
stdio: ['inherit', 'pipe', 'pipe'],
|
|
280
|
+
shell: true,
|
|
281
|
+
detached: process.platform !== 'win32',
|
|
282
|
+
});
|
|
283
|
+
} else {
|
|
284
|
+
child = spawn(command!, args, {
|
|
285
|
+
cwd: opts.cwd,
|
|
286
|
+
env,
|
|
287
|
+
stdio: ['inherit', 'pipe', 'pipe'],
|
|
288
|
+
shell: process.platform === 'win32',
|
|
289
|
+
detached: process.platform !== 'win32',
|
|
290
|
+
});
|
|
291
|
+
}
|
|
249
292
|
|
|
250
293
|
const outTarget = opts.json ? process.stderr : process.stdout;
|
|
251
294
|
const out = createLinePrefixer('[dev] ', (line) => outTarget.write(line));
|
|
@@ -267,7 +310,7 @@ export function spawnDevChild(
|
|
|
267
310
|
|
|
268
311
|
const exited = new Promise<number>((resolve) => {
|
|
269
312
|
child.once('error', (e) => {
|
|
270
|
-
process.stderr.write(`pyric
|
|
313
|
+
process.stderr.write(`pyric sandbox: failed to run \`${plan.label}\`: ${e.message}\n`);
|
|
271
314
|
resolve(1);
|
|
272
315
|
});
|
|
273
316
|
child.once('exit', (code, signal) => {
|
|
@@ -301,3 +344,5 @@ export function spawnDevChild(
|
|
|
301
344
|
},
|
|
302
345
|
};
|
|
303
346
|
}
|
|
347
|
+
|
|
348
|
+
export const spawnDevChild = spawnSandboxChild;
|