@runeditrun/rer 0.0.0-stage → 0.1.0
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/LICENSE +21 -0
- package/README.md +154 -2
- package/bin/rer.mjs +3 -0
- package/cli/README.md +243 -0
- package/cli/adapter.mjs +10 -0
- package/cli/ai-local.mjs +65 -0
- package/cli/archive-path.mjs +52 -0
- package/cli/archive-vite.mjs +55 -0
- package/cli/archive.mjs +8 -0
- package/cli/auth-copy.mjs +80 -0
- package/cli/bounded.mjs +70 -0
- package/cli/cache-doctor.mjs +63 -0
- package/cli/container-transfer.mjs +35 -0
- package/cli/container.mjs +62 -0
- package/cli/contract.mjs +25 -0
- package/cli/dependencies.mjs +45 -0
- package/cli/dependency-approval.mjs +33 -0
- package/cli/dependency-doctor.mjs +34 -0
- package/cli/dependency-input.mjs +43 -0
- package/cli/deploy-config.mjs +118 -0
- package/cli/deploy.mjs +37 -0
- package/cli/dev-identity.mjs +80 -0
- package/cli/errors.mjs +14 -0
- package/cli/export.mjs +42 -0
- package/cli/font-cache.mjs +29 -0
- package/cli/hosted-output.mjs +110 -0
- package/cli/independent.mjs +29 -0
- package/cli/inspect.mjs +174 -0
- package/cli/jsonc.mjs +111 -0
- package/cli/lifecycle.mjs +148 -0
- package/cli/local.mjs +100 -0
- package/cli/main.mjs +57 -0
- package/cli/managed-server.mjs +143 -0
- package/cli/node-runtime-cache.mjs +68 -0
- package/cli/node-runtime-discovery.mjs +56 -0
- package/cli/node-runtime-download.mjs +59 -0
- package/cli/node-runtime.mjs +50 -0
- package/cli/output.mjs +22 -0
- package/cli/parse.mjs +77 -0
- package/cli/port.mjs +52 -0
- package/cli/portability-worker.mjs +56 -0
- package/cli/portability.mjs +66 -0
- package/cli/preview-cache.mjs +99 -0
- package/cli/project.mjs +48 -0
- package/cli/release.mjs +24 -0
- package/cli/runtime-front-door.mjs +46 -0
- package/cli/scheduled.mjs +81 -0
- package/cli/server-activity.mjs +12 -0
- package/cli/server-proxy.mjs +93 -0
- package/cli/server-registry.mjs +177 -0
- package/cli/server-resources.mjs +22 -0
- package/cli/settings.mjs +15 -0
- package/cli/setup-answers.mjs +29 -0
- package/cli/setup-input.mjs +113 -0
- package/cli/shared.mjs +7 -0
- package/cli/transfers.mjs +33 -0
- package/cli/version.mjs +36 -0
- package/composition/git-source.mjs +111 -0
- package/edition-authoring/files.mjs +81 -0
- package/edition-authoring/manifest.mjs +65 -0
- package/global/README.md +155 -0
- package/global/checkout.mjs +72 -0
- package/global/cli/command.mjs +13 -0
- package/global/cli/install.mjs +75 -0
- package/global/cli/layout.mjs +45 -0
- package/global/cli/status.mjs +54 -0
- package/global/cli/uninstall.mjs +36 -0
- package/global/delegate.mjs +13 -0
- package/global/launch/capacity.mjs +72 -0
- package/global/launch/dev.mjs +129 -0
- package/global/launch/facts.mjs +93 -0
- package/global/launch/failure.mjs +5 -0
- package/global/launch/local-defaults.mjs +4 -0
- package/global/launch/prepare.mjs +61 -0
- package/global/launch/render.mjs +44 -0
- package/global/launch/state.mjs +97 -0
- package/global/launch/steps.mjs +81 -0
- package/global/launch/worker.mjs +43 -0
- package/global/list.mjs +59 -0
- package/global/main.mjs +53 -0
- package/global/package-info.mjs +38 -0
- package/global/registry.mjs +24 -0
- package/global/rer.mjs +29 -0
- package/global/update/archive.mjs +89 -0
- package/global/update/command.mjs +90 -0
- package/global/update/latest.mjs +6 -0
- package/global/update/notice.mjs +58 -0
- package/global/update/registry.mjs +47 -0
- package/global/version.mjs +29 -0
- package/install.sh +144 -0
- package/modules/ai/LICENSE +21 -0
- package/modules/ai/README.md +90 -0
- package/modules/ai/client.mjs +71 -0
- package/modules/ai/config.mjs +39 -0
- package/modules/ai/dev/index.d.mts +6 -0
- package/modules/ai/dev/index.mjs +64 -0
- package/modules/ai/dev/outbox.mjs +33 -0
- package/modules/ai/errors.mjs +28 -0
- package/modules/ai/fake/index.d.mts +3 -0
- package/modules/ai/fake/index.mjs +82 -0
- package/modules/ai/index.d.mts +10 -0
- package/modules/ai/index.mjs +3 -0
- package/modules/ai/package.json +6 -0
- package/modules/container/README.md +156 -0
- package/modules/container/adapters/d1.mjs +34 -0
- package/modules/container/adapters/egress.mjs +40 -0
- package/modules/container/adapters/jobs.mjs +47 -0
- package/modules/container/adapters/objects.mjs +84 -0
- package/modules/container/adapters/retained.mjs +14 -0
- package/modules/container/adapters/sqlite-error.mjs +7 -0
- package/modules/container/adapters/sqlite-worker.mjs +26 -0
- package/modules/container/assets.mjs +14 -0
- package/modules/container/bindings.mjs +1 -0
- package/modules/container/boundary.mjs +38 -0
- package/modules/container/build.mjs +65 -0
- package/modules/container/deploy-input.mjs +17 -0
- package/modules/container/entrypoint.sh +5 -0
- package/modules/container/host.mjs +43 -0
- package/modules/container/ingress.mjs +23 -0
- package/modules/container/lock.mjs +11 -0
- package/modules/container/migrations.mjs +16 -0
- package/modules/container/node-engine.mjs +39 -0
- package/modules/container/portability-schema.mjs +14 -0
- package/modules/container/remote/deploy.py +76 -0
- package/modules/container/remote/files.py +275 -0
- package/modules/container/remote/resources.py +157 -0
- package/modules/container/runner.mjs +10 -0
- package/modules/container/ssh-plan.mjs +44 -0
- package/modules/container/ssh.mjs +63 -0
- package/modules/container/transfer.mjs +27 -0
- package/modules/container/worker-engine.mjs +32 -0
- package/modules/dependencies/README.md +211 -0
- package/modules/dependencies/approval.mjs +51 -0
- package/modules/dependencies/auth.mjs +40 -0
- package/modules/dependencies/authority.mjs +14 -0
- package/modules/dependencies/crypto.mjs +13 -0
- package/modules/dependencies/index.d.mts +23 -0
- package/modules/dependencies/index.mjs +113 -0
- package/modules/dependencies/logout.mjs +42 -0
- package/modules/dependencies/native.mjs +9 -0
- package/modules/dependencies/protocol.mjs +23 -0
- package/modules/dependencies/schema/approval-attempt.sql +3 -0
- package/modules/dependencies/schema/dependencies.sql +15 -0
- package/modules/dependencies/store.mjs +19 -0
- package/modules/deploy-kit/README.md +308 -0
- package/modules/deploy-kit/artifact.mjs +47 -0
- package/modules/deploy-kit/build-modules.mjs +21 -0
- package/modules/deploy-kit/check.mjs +13 -0
- package/modules/deploy-kit/cli.mjs +50 -0
- package/modules/deploy-kit/container-config.mjs +8 -0
- package/modules/deploy-kit/default-stage.mjs +14 -0
- package/modules/deploy-kit/deploy.mjs +80 -0
- package/modules/deploy-kit/health-request.mjs +86 -0
- package/modules/deploy-kit/health.mjs +99 -0
- package/modules/deploy-kit/index.mjs +12 -0
- package/modules/deploy-kit/local-only.mjs +10 -0
- package/modules/deploy-kit/migrations.mjs +48 -0
- package/modules/deploy-kit/owner-cli.mjs +63 -0
- package/modules/deploy-kit/owner.mjs +297 -0
- package/modules/deploy-kit/prepare.mjs +62 -0
- package/modules/deploy-kit/provider.mjs +99 -0
- package/modules/deploy-kit/queue-consumer.mjs +10 -0
- package/modules/deploy-kit/receipt.mjs +16 -0
- package/modules/deploy-kit/render.mjs +47 -0
- package/modules/deploy-kit/resources.mjs +106 -0
- package/modules/deploy-kit/service-grants.mjs +25 -0
- package/modules/deploy-kit/sql-safety.mjs +94 -0
- package/modules/deploy-kit/sql-tokens.mjs +49 -0
- package/modules/deploy-kit/teardown.mjs +100 -0
- package/modules/deploy-kit/templates.mjs +31 -0
- package/modules/deploy-kit/validation.mjs +58 -0
- package/modules/deploy-kit/worker.mjs +105 -0
- package/modules/erasure/CONTRACT.md +90 -0
- package/modules/erasure/README.md +221 -0
- package/modules/erasure/audit.mjs +23 -0
- package/modules/erasure/blobs.mjs +45 -0
- package/modules/erasure/cascade.mjs +91 -0
- package/modules/erasure/completion.mjs +62 -0
- package/modules/erasure/declaration.mjs +51 -0
- package/modules/erasure/fence.mjs +19 -0
- package/modules/erasure/index.d.mts +62 -0
- package/modules/erasure/index.mjs +85 -0
- package/modules/erasure/order.mjs +56 -0
- package/modules/erasure/plan.mjs +121 -0
- package/modules/erasure/rate.mjs +57 -0
- package/modules/erasure/receipt.mjs +32 -0
- package/modules/erasure/root.mjs +21 -0
- package/modules/erasure/schema/erasure-rates.sql +5 -0
- package/modules/erasure/schema/erasure.sql +27 -0
- package/modules/erasure/scope.mjs +29 -0
- package/modules/erasure/sql.mjs +23 -0
- package/modules/erasure/verification.mjs +69 -0
- package/modules/integrations/core/CONTRACT.md +50 -0
- package/modules/integrations/core/README.md +27 -0
- package/modules/integrations/core/crypto.ts +19 -0
- package/modules/integrations/core/database.ts +21 -0
- package/modules/integrations/core/delivery.ts +97 -0
- package/modules/integrations/core/destination.ts +13 -0
- package/modules/integrations/core/index.ts +7 -0
- package/modules/integrations/core/node-transport.ts +72 -0
- package/modules/integrations/core/public-address.ts +57 -0
- package/modules/integrations/core/repository.ts +74 -0
- package/modules/integrations/core/schema.sql +36 -0
- package/modules/integrations/core/sqlite.ts +20 -0
- package/modules/integrations/core/timestamped-body-signature.ts +38 -0
- package/modules/integrations/core/tokens.ts +71 -0
- package/modules/integrations/core/types.ts +52 -0
- package/modules/integrations/core/upgrade-token-usage-context.sql +5 -0
- package/modules/integrations/core/webhook.ts +73 -0
- package/modules/job-queue/README.md +173 -0
- package/modules/job-queue/cli.mjs +64 -0
- package/modules/job-queue/command.mjs +64 -0
- package/modules/job-queue/config.mjs +48 -0
- package/modules/job-queue/identity.mjs +48 -0
- package/modules/job-queue/index.mjs +135 -0
- package/modules/job-queue/membership.mjs +30 -0
- package/modules/job-queue/module.json +10 -0
- package/modules/job-queue/policy.mjs +29 -0
- package/modules/job-queue/processes.mjs +80 -0
- package/modules/job-queue/resources.mjs +37 -0
- package/modules/job-queue/storage.mjs +64 -0
- package/modules/job-queue/supervisor.mjs +30 -0
- package/modules/job-queue/waiting.mjs +16 -0
- package/modules/mail/LICENSE +21 -0
- package/modules/mail/README.md +336 -0
- package/modules/mail/doctor.mjs +81 -0
- package/modules/mail/index.mjs +8 -0
- package/modules/mail/live-proof/README.md +113 -0
- package/modules/mail/live-proof/run.mjs +55 -0
- package/modules/mail/package.json +19 -0
- package/modules/mail/pnpm-lock.yaml +537 -0
- package/modules/mail/src/adapters/cloudflare/README.md +84 -0
- package/modules/mail/src/adapters/cloudflare/headers.mjs +63 -0
- package/modules/mail/src/adapters/cloudflare/index.mjs +47 -0
- package/modules/mail/src/adapters/cloudflare/response.mjs +99 -0
- package/modules/mail/src/adapters/messaging/README.md +92 -0
- package/modules/mail/src/adapters/messaging/contract.mjs +66 -0
- package/modules/mail/src/adapters/messaging/event-schema.mjs +28 -0
- package/modules/mail/src/adapters/messaging/index.mjs +61 -0
- package/modules/mail/src/adapters/messaging/jws.mjs +68 -0
- package/modules/mail/src/adapters/messaging/request.mjs +52 -0
- package/modules/mail/src/adapters/messaging/serialize.mjs +21 -0
- package/modules/mail/src/adapters/resend/README.md +120 -0
- package/modules/mail/src/adapters/resend/index.mjs +22 -0
- package/modules/mail/src/adapters/resend/response.mjs +54 -0
- package/modules/mail/src/adapters/resend/serialize.mjs +46 -0
- package/modules/mail/src/adapters/resend/size.mjs +99 -0
- package/modules/mail/src/adapters/sendgrid/README.md +75 -0
- package/modules/mail/src/adapters/sendgrid/index.mjs +35 -0
- package/modules/mail/src/adapters/sendgrid/serialize.mjs +104 -0
- package/modules/mail/src/core/errors.mjs +9 -0
- package/modules/mail/src/core/transport.mjs +33 -0
- package/modules/mail/src/core/validation.mjs +172 -0
- package/modules/mail/src/development/index.d.mts +37 -0
- package/modules/mail/src/development/index.mjs +35 -0
- package/modules/mail/src/development/outbox.mjs +78 -0
- package/modules/mail/src/development/schema.sql +9 -0
- package/modules/mail/src/development/viewer-html.mjs +42 -0
- package/modules/mail/src/development/viewer.mjs +65 -0
- package/modules/mail/src/doctor/README.md +107 -0
- package/modules/mail/src/doctor/common.mjs +64 -0
- package/modules/mail/src/doctor/dns.mjs +102 -0
- package/modules/mail/src/doctor/index.mjs +28 -0
- package/modules/mail/src/doctor/probe.mjs +66 -0
- package/modules/mail/src/doctor/receive.mjs +81 -0
- package/modules/mail/src/doctor/records.mjs +45 -0
- package/modules/mail/src/events/README.md +268 -0
- package/modules/mail/src/events/d1-schema.sql +25 -0
- package/modules/mail/src/events/d1-storage.mjs +76 -0
- package/modules/mail/src/events/index.mjs +3 -0
- package/modules/mail/src/events/intake.mjs +201 -0
- package/modules/mail/src/events/storage.mjs +52 -0
- package/modules/mail/src/events/verify.mjs +92 -0
- package/modules/mail/src/inbound/README.md +137 -0
- package/modules/mail/src/inbound/bytes.mjs +91 -0
- package/modules/mail/src/inbound/headers.mjs +143 -0
- package/modules/mail/src/inbound/index.mjs +29 -0
- package/modules/mail/src/inbound/mime.mjs +36 -0
- package/modules/mail/src/inbound/multipart.mjs +27 -0
- package/modules/mail/src/inbound/resend-attachment.mjs +43 -0
- package/modules/mail/src/inbound/resend.mjs +54 -0
- package/modules/mail/src/inbound/sendgrid.mjs +60 -0
- package/modules/mail/src/sender.mjs +33 -0
- package/modules/mail/src/sendgrid-email/index.d.mts +33 -0
- package/modules/mail/src/sendgrid-email/index.mjs +86 -0
- package/modules/mail/src/unsubscribe/index.mjs +142 -0
- package/modules/operator-auth/README.md +599 -0
- package/modules/operator-auth/accounts/adapter.mjs +41 -0
- package/modules/operator-auth/accounts/admin.mjs +159 -0
- package/modules/operator-auth/accounts/credentials.mjs +27 -0
- package/modules/operator-auth/accounts/editor-owner.mjs +13 -0
- package/modules/operator-auth/accounts/index.d.mts +9 -0
- package/modules/operator-auth/accounts/index.mjs +9 -0
- package/modules/operator-auth/accounts/native.d.mts +38 -0
- package/modules/operator-auth/accounts/native.mjs +171 -0
- package/modules/operator-auth/accounts/oa.mjs +90 -0
- package/modules/operator-auth/accounts/provider-control.mjs +50 -0
- package/modules/operator-auth/accounts/provider-pin.mjs +14 -0
- package/modules/operator-auth/accounts/roles.mjs +26 -0
- package/modules/operator-auth/accounts/schema/dependency-setup.sql +17 -0
- package/modules/operator-auth/accounts/schema/dev-sessions.sql +22 -0
- package/modules/operator-auth/accounts/schema/domain-rules-step-up.sql +20 -0
- package/modules/operator-auth/accounts/schema/invitation-cancellation.sql +17 -0
- package/modules/operator-auth/accounts/schema/operator-auth.sql +142 -0
- package/modules/operator-auth/accounts/schema/provider-control.sql +30 -0
- package/modules/operator-auth/accounts/schema/provider-pins.sql +6 -0
- package/modules/operator-auth/accounts/settings-page.mjs +4 -0
- package/modules/operator-auth/accounts/store.mjs +246 -0
- package/modules/operator-auth/branding.mjs +66 -0
- package/modules/operator-auth/config.mjs +35 -0
- package/modules/operator-auth/conformance/README.md +81 -0
- package/modules/operator-auth/conformance/index.d.mts +43 -0
- package/modules/operator-auth/conformance/index.mjs +300 -0
- package/modules/operator-auth/conformance/presentation.mjs +57 -0
- package/modules/operator-auth/crypto.mjs +17 -0
- package/modules/operator-auth/dev/badge.mjs +62 -0
- package/modules/operator-auth/dev/index.d.mts +14 -0
- package/modules/operator-auth/dev/index.mjs +137 -0
- package/modules/operator-auth/dev/personas.mjs +17 -0
- package/modules/operator-auth/dev/sign-in-as.d.mts +3 -0
- package/modules/operator-auth/dev/sign-in-as.mjs +25 -0
- package/modules/operator-auth/dev-admission.d.mts +4 -0
- package/modules/operator-auth/dev-admission.mjs +10 -0
- package/modules/operator-auth/dev-gate.mjs +86 -0
- package/modules/operator-auth/docs/README.md +78 -0
- package/modules/operator-auth/docs/native-accounts.md +313 -0
- package/modules/operator-auth/docs/tanstack-start.md +218 -0
- package/modules/operator-auth/docs/vite-spa.md +144 -0
- package/modules/operator-auth/errors.mjs +9 -0
- package/modules/operator-auth/http.mjs +42 -0
- package/modules/operator-auth/identity/admission.mjs +105 -0
- package/modules/operator-auth/identity/after-confirm.mjs +18 -0
- package/modules/operator-auth/identity/email-link/confirmation.mjs +14 -0
- package/modules/operator-auth/identity/email-link/index.d.mts +48 -0
- package/modules/operator-auth/identity/email-link/index.mjs +128 -0
- package/modules/operator-auth/identity/email-link/message.mjs +16 -0
- package/modules/operator-auth/identity/index.d.mts +7 -0
- package/modules/operator-auth/identity/index.mjs +5 -0
- package/modules/operator-auth/identity/oidc/README.md +171 -0
- package/modules/operator-auth/identity/oidc/client-auth.mjs +16 -0
- package/modules/operator-auth/identity/oidc/config.mjs +102 -0
- package/modules/operator-auth/identity/oidc/crypto.mjs +29 -0
- package/modules/operator-auth/identity/oidc/errors.mjs +5 -0
- package/modules/operator-auth/identity/oidc/index.d.mts +33 -0
- package/modules/operator-auth/identity/oidc/index.mjs +287 -0
- package/modules/operator-auth/identity/oidc/jwt.mjs +102 -0
- package/modules/operator-auth/identity/oidc/network.mjs +93 -0
- package/modules/operator-auth/identity/oidc/presets.mjs +26 -0
- package/modules/operator-auth/identity/oidc/schema/oidc.sql +50 -0
- package/modules/operator-auth/identity/oidc/store.mjs +68 -0
- package/modules/operator-auth/identity/principal.mjs +28 -0
- package/modules/operator-auth/index.d.mts +223 -0
- package/modules/operator-auth/index.mjs +11 -0
- package/modules/operator-auth/input.mjs +55 -0
- package/modules/operator-auth/local-cli.mjs +16 -0
- package/modules/operator-auth/page.mjs +34 -0
- package/modules/operator-auth/policy.mjs +20 -0
- package/modules/operator-auth/routes.mjs +91 -0
- package/modules/operator-auth/service.mjs +152 -0
- package/modules/operator-auth/signin/index.mjs +67 -0
- package/modules/owner-claim/README.md +137 -0
- package/modules/owner-claim/idp.mjs +40 -0
- package/modules/owner-claim/index.d.mts +27 -0
- package/modules/owner-claim/index.mjs +39 -0
- package/modules/owner-claim/page.mjs +11 -0
- package/modules/owner-claim/schema/idp.sql +4 -0
- package/modules/owner-claim/schema/owner-claim.sql +18 -0
- package/modules/owner-claim/transaction.mjs +87 -0
- package/modules/owner-claim/verify.mjs +80 -0
- package/modules/portability/README.md +444 -0
- package/modules/portability/bridge.mjs +102 -0
- package/modules/portability/catalogue.mjs +118 -0
- package/modules/portability/cli-options.mjs +38 -0
- package/modules/portability/cli.mjs +56 -0
- package/modules/portability/copies.mjs +68 -0
- package/modules/portability/dev-data.mjs +32 -0
- package/modules/portability/diff.mjs +33 -0
- package/modules/portability/export.mjs +129 -0
- package/modules/portability/files.mjs +65 -0
- package/modules/portability/format.mjs +122 -0
- package/modules/portability/generated.mjs +60 -0
- package/modules/portability/hash.mjs +79 -0
- package/modules/portability/http.mjs +42 -0
- package/modules/portability/import.mjs +185 -0
- package/modules/portability/index.d.mts +58 -0
- package/modules/portability/index.mjs +22 -0
- package/modules/portability/journal.mjs +49 -0
- package/modules/portability/legacy-files.mjs +43 -0
- package/modules/portability/legacy-safety.mjs +27 -0
- package/modules/portability/lines.mjs +36 -0
- package/modules/portability/migration-history.mjs +18 -0
- package/modules/portability/migration-statements.mjs +23 -0
- package/modules/portability/payloads.mjs +52 -0
- package/modules/portability/provider-data.mjs +25 -0
- package/modules/portability/restore-safety.mjs +30 -0
- package/modules/portability/schema/portability.sql +25 -0
- package/modules/portability/storage.mjs +49 -0
- package/modules/release/README.md +212 -0
- package/modules/release/catalogue.mjs +79 -0
- package/modules/release/export.mjs +51 -0
- package/modules/release/produce.mjs +136 -0
- package/modules/release/public-child-transport-state.cjs +29 -0
- package/modules/release/public-child.mjs +71 -0
- package/modules/release/public-git.mjs +21 -0
- package/modules/release/publication-scan.mjs +22 -0
- package/modules/release/publish-handoff.mjs +37 -0
- package/modules/release/source.mjs +71 -0
- package/modules/release/test-summary.mjs +50 -0
- package/onboarding/README.md +163 -0
- package/onboarding/activity.mjs +31 -0
- package/onboarding/adapter-auth.mjs +88 -0
- package/onboarding/adapter-hosting.mjs +35 -0
- package/onboarding/adapter-labels.mjs +13 -0
- package/onboarding/adapter-settings.mjs +129 -0
- package/onboarding/adapter.mjs +238 -0
- package/onboarding/agent-handoff.mjs +9 -0
- package/onboarding/app-processes.mjs +21 -0
- package/onboarding/archive-output.d.mts +3 -0
- package/onboarding/archive-output.mjs +54 -0
- package/onboarding/command-custody.mjs +24 -0
- package/onboarding/command-recovery.mjs +8 -0
- package/onboarding/commands.mjs +166 -0
- package/onboarding/dependency-approval.mjs +36 -0
- package/onboarding/dev-identity.mjs +23 -0
- package/onboarding/email.mjs +24 -0
- package/onboarding/failures.mjs +42 -0
- package/onboarding/input-limits.mjs +7 -0
- package/onboarding/installer-inputs.mjs +24 -0
- package/onboarding/launcher.mjs +34 -0
- package/onboarding/local/build-files.mjs +64 -0
- package/onboarding/local/build.mjs +49 -0
- package/onboarding/local/environment.mjs +30 -0
- package/onboarding/local/files.mjs +35 -0
- package/onboarding/local/operation.mjs +166 -0
- package/onboarding/local/owner.mjs +34 -0
- package/onboarding/local/process-table.mjs +114 -0
- package/onboarding/local/recovery.mjs +79 -0
- package/onboarding/local/state.mjs +31 -0
- package/onboarding/metadata.mjs +7 -0
- package/onboarding/operator-install.mjs +45 -0
- package/onboarding/operator-installer.mjs +39 -0
- package/onboarding/operator-prerequisites.mjs +27 -0
- package/onboarding/package.json +6 -0
- package/onboarding/prefill.mjs +16 -0
- package/onboarding/private-files.mjs +97 -0
- package/onboarding/private.mjs +35 -0
- package/onboarding/process-cleanup.mjs +134 -0
- package/onboarding/process-diagnostics.mjs +91 -0
- package/onboarding/process-scope.mjs +118 -0
- package/onboarding/process-table.mjs +118 -0
- package/onboarding/process-tree.mjs +36 -0
- package/onboarding/production-modules.mjs +22 -0
- package/onboarding/production-options.mjs +40 -0
- package/onboarding/production-plan.mjs +8 -0
- package/onboarding/production-runtime.mjs +30 -0
- package/onboarding/project-vite.mjs +14 -0
- package/onboarding/providers.mjs +289 -0
- package/onboarding/queue.mjs +53 -0
- package/onboarding/queued-entry.mjs +34 -0
- package/onboarding/readiness.mjs +59 -0
- package/onboarding/redaction-jwt.mjs +32 -0
- package/onboarding/redaction.mjs +298 -0
- package/onboarding/schema/SETUP.schema.json +514 -0
- package/onboarding/schema/dependencies.mjs +35 -0
- package/onboarding/schema/json-schema.mjs +202 -0
- package/onboarding/schema/setup-validation.mjs +325 -0
- package/onboarding/secrets.mjs +21 -0
- package/onboarding/server.mjs +188 -0
- package/onboarding/setup-manifest.mjs +116 -0
- package/onboarding/state.mjs +46 -0
- package/onboarding/theme-files.mjs +37 -0
- package/onboarding/theme.mjs +118 -0
- package/onboarding/ui/activity.js +98 -0
- package/onboarding/ui/address-client.mjs +33 -0
- package/onboarding/ui/app.js +377 -0
- package/onboarding/ui/index.html +1 -0
- package/onboarding/ui/model-core.mjs +127 -0
- package/onboarding/ui/model.mjs +5 -0
- package/onboarding/ui/style.css +63 -0
- package/onboarding/ui/theme.css +37 -0
- package/onboarding/ui/workspace-art.js +30 -0
- package/onboarding/wrangler-auth.mjs +43 -0
- package/operations/README.md +246 -0
- package/operations/operations.mjs +168 -0
- package/operations/project-operations.mjs +157 -0
- package/package.json +11 -4
- package/scripts/publish-check/README.md +72 -0
- package/scripts/publish-check/checksum_maps.py +52 -0
- package/scripts/publish-check/cli.py +34 -0
- package/scripts/publish-check/command_arguments.py +51 -0
- package/scripts/publish-check/command_shell_quotes.py +41 -0
- package/scripts/publish-check/command_source_quotes.py +120 -0
- package/scripts/publish-check/content_identities.py +250 -0
- package/scripts/publish-check/copy_identities.py +41 -0
- package/scripts/publish-check/der.py +61 -0
- package/scripts/publish-check/destination.py +117 -0
- package/scripts/publish-check/env_values.py +74 -0
- package/scripts/publish-check/font_licence.py +23 -0
- package/scripts/publish-check/git_history.py +115 -0
- package/scripts/publish-check/github_refs.py +217 -0
- package/scripts/publish-check/gitleaks.py +72 -0
- package/scripts/publish-check/gitleaks.toml +40 -0
- package/scripts/publish-check/history_scan.py +176 -0
- package/scripts/publish-check/hit_location.py +18 -0
- package/scripts/publish-check/hygiene_config.py +42 -0
- package/scripts/publish-check/hygiene_text.py +11 -0
- package/scripts/publish-check/identity-recipe.mjs +54 -0
- package/scripts/publish-check/json_identity.py +79 -0
- package/scripts/publish-check/license-exceptions.json +11 -0
- package/scripts/publish-check/licenses.py +49 -0
- package/scripts/publish-check/policy.py +18 -0
- package/scripts/publish-check/project_identity.py +89 -0
- package/scripts/publish-check/provenance.py +91 -0
- package/scripts/publish-check/provenance_pins.py +33 -0
- package/scripts/publish-check/public_base.py +63 -0
- package/scripts/publish-check/public_hygiene.py +80 -0
- package/scripts/publish-check/publication-config.json +12 -0
- package/scripts/publish-check/publication_config.py +34 -0
- package/scripts/publish-check/report.py +52 -0
- package/scripts/publish-check/repository_commands.py +75 -0
- package/scripts/publish-check/repository_intent.py +52 -0
- package/scripts/publish-check/reviewed.py +41 -0
- package/scripts/publish-check/source_hashes.mjs +6 -0
- package/scripts/publish-check/tree_scan.py +88 -0
- package/scripts/publish-check/trust_bundle.py +87 -0
- package/scripts/publish-check.mjs +58 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Run Edit Run
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,155 @@
|
|
|
1
|
-
#
|
|
1
|
+
# rer
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
`rer` is the Run Edit Run command. Install it once, then run `rer <verb>` in any
|
|
4
|
+
Run Edit Run checkout: every verb runs that checkout's own pinned copy, so a
|
|
5
|
+
checkout always gets the behaviour it was built and tested with.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
Any one of these leaves `rer` on your PATH:
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
npx -y @runeditrun/rer cli install # user install in ~/.local/share/rer, launcher ~/.local/bin/rer
|
|
13
|
+
curl -fsSL https://runeditrun.com/install.sh | sh # the same user install, without npm
|
|
14
|
+
npm install -g @runeditrun/rer # npm's own global layout
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
`install.sh` is the file at the root of this package. It reads the version, the
|
|
18
|
+
tarball and its sha512 integrity from the npm registry (`npm_config_registry`,
|
|
19
|
+
default `https://registry.npmjs.org`; `RER_VERSION=X` pins an exact version,
|
|
20
|
+
otherwise the latest), checks the download's integrity, file count and size,
|
|
21
|
+
refuses archives with absolute paths, `..` entries, links or devices, then runs
|
|
22
|
+
the package's own `rer cli install`. A failed or refused download leaves the
|
|
23
|
+
version you had selected.
|
|
24
|
+
|
|
25
|
+
No installer edits shell profiles. When `~/.local/bin` is not on your PATH, the
|
|
26
|
+
install prints the exact line to add for your shell. The launcher runs `node` from
|
|
27
|
+
PATH, so a Node upgrade does not break it. A re-run with the same build changes
|
|
28
|
+
nothing; a different build is installed beside the current one, the previous one
|
|
29
|
+
is kept and older ones are removed. It refuses to replace a `~/.local/bin/rer`
|
|
30
|
+
that it did not write.
|
|
31
|
+
|
|
32
|
+
`rer --version` prints this rer's version; inside a checkout a second line
|
|
33
|
+
names the version the checkout pins, or says that its vendored copy is
|
|
34
|
+
unversioned (exported before copies recorded one).
|
|
35
|
+
|
|
36
|
+
`rer cli status` shows the version, the digest of the installed contents, the
|
|
37
|
+
install channel (`npx`, `script` or `npm-global`), the launcher, the install root
|
|
38
|
+
and every other `rer` on PATH. `rer cli uninstall` removes the launcher and the
|
|
39
|
+
install root it runs only; `~/.rer` (servers, jobs, Node runtimes) is untouched.
|
|
40
|
+
An npm global `rer` prints its `npm uninstall -g` command and leaves a user
|
|
41
|
+
install in place.
|
|
42
|
+
|
|
43
|
+
### Requirements
|
|
44
|
+
|
|
45
|
+
- macOS or Linux, on x64 or arm64. WSL2 counts as Linux.
|
|
46
|
+
- Node 22 or later on PATH; `rer` stops with one line naming the minimum on an
|
|
47
|
+
older Node.
|
|
48
|
+
- For `install.sh`: `curl` and `tar`.
|
|
49
|
+
- For `rer dev` in a checkout: the checkout's own package manager (pnpm for
|
|
50
|
+
Run Edit Run seeds).
|
|
51
|
+
|
|
52
|
+
Not supported: native Windows (`install.sh` and `rer` say to use WSL2), and
|
|
53
|
+
`OPERATIONS.json` version 1 projects.
|
|
54
|
+
|
|
55
|
+
## Update
|
|
56
|
+
|
|
57
|
+
```sh
|
|
58
|
+
rer update # the latest published version
|
|
59
|
+
rer update --version X # exactly X
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
`rer update` follows the way `rer` was installed. A user install (`npx` or
|
|
63
|
+
`install.sh`) downloads the version from the registry, checks it as `install.sh`
|
|
64
|
+
does and switches to it atomically, keeping the previous version and the same
|
|
65
|
+
channel; a damaged or mismatched download leaves the current version selected.
|
|
66
|
+
It says "already current" when the registry's version has the same contents. A
|
|
67
|
+
development build (`<version>-dev.g<sha8>`) moves to the release once that
|
|
68
|
+
version is published, and a different build of the same version counts as an
|
|
69
|
+
update. An npm global install runs `npm install -g @runeditrun/rer@X` for its own
|
|
70
|
+
prefix; when npm fails (for example, a prefix only root can write), `rer update`
|
|
71
|
+
exits non-zero with npm's message and the exact command to run.
|
|
72
|
+
|
|
73
|
+
In a terminal, `rer` checks the registry at most once a day and prints one line
|
|
74
|
+
when a newer version is published. It never prints in `--json` output or when
|
|
75
|
+
output is not a terminal, never delays a command by more than about 1.5 seconds,
|
|
76
|
+
and `RER_NO_UPDATE_CHECK=1` turns it off.
|
|
77
|
+
|
|
78
|
+
## Launch a checkout
|
|
79
|
+
|
|
80
|
+
```sh
|
|
81
|
+
rer dev
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
In a first-party checkout this is the whole launch. It installs dependencies when
|
|
85
|
+
`node_modules` is missing, incomplete (no `node_modules/.modules.yaml`, or an
|
|
86
|
+
install a launch started did not finish) or older than the lockfile, sets up a local owner
|
|
87
|
+
(`owner@<checkout-name>.test`) on the first free port from 8787 when the checkout
|
|
88
|
+
has never been set up (`--port N` picks the port), fills any setup answer the
|
|
89
|
+
seed declares a `localDefault` for in `rer-setup.json` (a literal, a generated
|
|
90
|
+
secret kept only in the checkout's private settings, or the chosen local
|
|
91
|
+
origin), starts the app and prints:
|
|
92
|
+
|
|
93
|
+
```
|
|
94
|
+
RER_READY http://127.0.0.1:8787
|
|
95
|
+
RER_SIGNED_IN owner@cradle.test
|
|
96
|
+
RER_OPEN http://127.0.0.1:8787/__dev/key#...
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
or `RER_SIGN_IN <outbox>` for a seed that signs in through its development outbox.
|
|
100
|
+
It never prompts and never re-runs setup on a checkout that is already set up. A
|
|
101
|
+
setup a launch started that was stopped or failed is run again by the next
|
|
102
|
+
`rer dev`, keeping the owner and origin it saved, unless a setup has finished
|
|
103
|
+
there since (for example your own `rer setup`). A checkout whose pin reports it is
|
|
104
|
+
not set up (`rer describe`'s `local.prepared`) but that already holds an owner
|
|
105
|
+
(`local.ownerSaved`, for example when a newer manifest requires another setting)
|
|
106
|
+
finishes setup keeping that owner and origin. A required setup answer with no value and no
|
|
107
|
+
`localDefault` stops the launch with exit 3 and setup's message naming it.
|
|
108
|
+
|
|
109
|
+
Inside a checkout `rer` acts on the nearest `OPERATIONS.json` at or above the
|
|
110
|
+
working directory; `--cwd DIR` names the project root itself, exactly as
|
|
111
|
+
`node scripts/rer.mjs` reads it.
|
|
112
|
+
|
|
113
|
+
Without a terminal (an agent's shell tool) it returns as soon as the app is ready
|
|
114
|
+
and leaves it running, printing the server's private log path; in a terminal it
|
|
115
|
+
stays in the foreground and Ctrl-C stops it. `--detach` and `--foreground`
|
|
116
|
+
override the choice, and `--json` prints `progress` events and the ready event. A
|
|
117
|
+
first launch can take minutes: it prints a progress line at least every 30
|
|
118
|
+
seconds, and if the calling command is killed the launch carries on; run
|
|
119
|
+
`rer dev` again to reattach. A second `rer dev` reprints the ready lines.
|
|
120
|
+
`rer dev --stop` stops the server.
|
|
121
|
+
|
|
122
|
+
Servers started through `rer` (`rer dev`, `rer preview`) get a 10-server limit and a 12-hour idle timeout
|
|
123
|
+
unless you set `RER_SERVER_LIMIT`, `RER_SERVER_IDLE_SECONDS` or `--idle-timeout`.
|
|
124
|
+
`rer` supplies them only to checkouts whose pinned copy applies lower defaults
|
|
125
|
+
or does not report its own (`rer describe` reports `defaults`), so a current
|
|
126
|
+
checkout never records a limit you did not set.
|
|
127
|
+
A start is never refused for machine load alone unless `RER_SERVERS_LOAD_THRESHOLD`
|
|
128
|
+
or `RER_JOBS_LOAD_THRESHOLD` is set; memory and disk guards stay.
|
|
129
|
+
|
|
130
|
+
## Find what to launch
|
|
131
|
+
|
|
132
|
+
```sh
|
|
133
|
+
rer list [DIR] [--json]
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
lists the checkouts in a folder, newest change first, with their profile
|
|
137
|
+
(`first-party`, `independent` or `unsupported`), whether `rer dev` can launch
|
|
138
|
+
them, whether they are set up, and their running URL.
|
|
139
|
+
|
|
140
|
+
Independent projects (an `OPERATIONS.json` version 2 without a seed contract) run
|
|
141
|
+
their declared commands with `rer <verb> [-- args]`; zero-setup launching does not
|
|
142
|
+
apply to them. `OPERATIONS.json` version 1 is not supported.
|
|
143
|
+
|
|
144
|
+
## Verbs
|
|
145
|
+
|
|
146
|
+
In a checkout, every verb runs that checkout's own pinned `rer`; `rer VERB --help`
|
|
147
|
+
there lists its flags:
|
|
148
|
+
|
|
149
|
+
`install`, `setup`, `dev`, `preview`, `build`, `verify`, `reset --yes`, `deploy`,
|
|
150
|
+
`export`, `import`, `outbox`, `doctor`, `describe`, `check`, `release`.
|
|
151
|
+
|
|
152
|
+
Anywhere: `rer list [DIR]`, `rer cli status|install|uninstall`, `rer update`,
|
|
153
|
+
`rer --version` and `rer --help`.
|
|
154
|
+
|
|
155
|
+
Licence: MIT.
|
package/bin/rer.mjs
ADDED
package/cli/README.md
ADDED
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
# Portable command sources
|
|
2
|
+
|
|
3
|
+
`bin/rer.mjs` dispatches `cli/main.mjs`. Parsing/contract declarations, project
|
|
4
|
+
resolution, output/exits, shared lifecycle orchestration, local state/reset,
|
|
5
|
+
transfers, independent argv and diagnostics are separate modules. `dev-identity.mjs`
|
|
6
|
+
holds the per-checkout dev key (`.rer/local/dev-key.env`), the `RER_OPEN` URL,
|
|
7
|
+
the managed-installation refusal and the build-output dev-layer scan. Release retains
|
|
8
|
+
its own compatibility parser and producer and does not use the generic executor.
|
|
9
|
+
|
|
10
|
+
The browser installer that `rer install` opens, and Base's sign-in confirmation and
|
|
11
|
+
`/setup` frames, wear the seed's declared theme (`public/rer-theme.css`); the
|
|
12
|
+
contract and token table are under "Seed theme" in `onboarding/README.md`.
|
|
13
|
+
|
|
14
|
+
`node scripts/export-cli.mjs SEED_ROOT` copies the deterministic `sourceRoots`
|
|
15
|
+
in `cli/export.mjs`, preserving their relative topology under
|
|
16
|
+
`scripts/base-cli/`. `inventory.json` lists every source and SHA-256. Python
|
|
17
|
+
publication tooling and its data are included for release. The thin seed
|
|
18
|
+
`scripts/rer.mjs` dispatches that copy. `cli/shared.mjs` is the sole relocation
|
|
19
|
+
boundary and imports the existing `scripts/base-onboarding/`; no second onboarding
|
|
20
|
+
tree or neighboring checkout is used. The foundation composition maps copy these
|
|
21
|
+
same sources from an explicit committed Base revision and record their provenance.
|
|
22
|
+
|
|
23
|
+
`node scripts/export-reference.mjs NEW_PATH` creates a standalone copy of the
|
|
24
|
+
reference with runtime imports relocated into its own source tree and an explicit
|
|
25
|
+
transformation inventory. It preserves source/tool pins and the real app; it does
|
|
26
|
+
not substitute an application fixture. Frozen dependency installation occurs
|
|
27
|
+
separately. Refresh copied sources with the export tools after shared edits.
|
|
28
|
+
|
|
29
|
+
Every first-party seed declares `commandAdapter` alongside its installer hooks.
|
|
30
|
+
`localInstaller.run` supplies shared setup lifecycle behavior; the RER command
|
|
31
|
+
path propagates failures as nonzero exits. Setup and the seed's configured local
|
|
32
|
+
workflow use `onboarding/commands.mjs`, local locks/recovery and the same
|
|
33
|
+
owner/sign-in hooks. The reference hook declaration is
|
|
34
|
+
`onboarding/operator-installer.mjs`. Seeds own answers, real migrations,
|
|
35
|
+
internal build/dev/verify targets and deployment policy. The CLI owns flags,
|
|
36
|
+
pins, containment, cancellation, capture, output and sequencing.
|
|
37
|
+
|
|
38
|
+
Successful terminal setup saves declared nonsecret installer answers in owned
|
|
39
|
+
0600 storage under `.seed/installer`. A non-interactive repeat reuses those
|
|
40
|
+
answers, with explicit flags or an answers file taking precedence. Runtime
|
|
41
|
+
bindings remain separate: a local mail transport need not be a hosted setup
|
|
42
|
+
choice. Retained settings still determine secret readiness and owner conflicts;
|
|
43
|
+
setup never rebinds an existing owner. A newly required unanswered field causes
|
|
44
|
+
exit 3 with its manifest name and accepted input shape. Reset clears the saved
|
|
45
|
+
answers with the rest of the local installer state.
|
|
46
|
+
For older installations without an answer record, a runtime selection outside
|
|
47
|
+
the installer field's choices cannot replace an adapter-declared local choice.
|
|
48
|
+
Explicit answers and recorded installer choices still undergo strict validation.
|
|
49
|
+
|
|
50
|
+
Local `export --output FILE` and `import --input FILE --yes` use the Base
|
|
51
|
+
portability implementation through the shared command runner and real Wrangler
|
|
52
|
+
bindings. Seed adapters declare their database, buckets and archive policy.
|
|
53
|
+
Export writes a new 0600 archive and reports its verified content hash, resource
|
|
54
|
+
counts, exclusions and configuration names. Import applies migrations, verifies
|
|
55
|
+
the archive and restores atomically into an empty destination. Stop dev or
|
|
56
|
+
preview before either operation. `import --journal LATER_ARCHIVE` also applies
|
|
57
|
+
the erasure journal of a later archive from the same installation, so a fresh
|
|
58
|
+
destination refuses rows erased since. Erasure-fence refusals (`erased_row`,
|
|
59
|
+
`erasure_epoch`, `later_journal`) exit 4. Reset preserves exports. Remote transfer is
|
|
60
|
+
available only when the adapter declares complete resource coverage; an
|
|
61
|
+
unsupported target exits 4.
|
|
62
|
+
|
|
63
|
+
Local D1 transfer includes SQLite VIRTUAL and STORED generated columns. Archives
|
|
64
|
+
retain their schema and carry only writable base cells; native expressions and
|
|
65
|
+
indexes in the migrated destination recompute on restore. The public runner's
|
|
66
|
+
generated-column journey compares every visible SQL cell as well as the archived
|
|
67
|
+
base rows across a fresh installation. Ordinary-table archives from before this
|
|
68
|
+
support remain compatible with the same schema.
|
|
69
|
+
|
|
70
|
+
Every first-party seed verifies local export/import/export equivalence for its
|
|
71
|
+
supported domain and resource data. In default-seed, each export advances the
|
|
72
|
+
included authority generation, so archive hashes may differ even when retained
|
|
73
|
+
domain and identity rows are equal. The technical foundation currently has no
|
|
74
|
+
product domain or background jobs; default-seed retains its durable jobs and
|
|
75
|
+
schedule records while omitting transient queue delivery state, local runtime
|
|
76
|
+
caches and logs, local outbox, transfer bookkeeping, provider credentials,
|
|
77
|
+
provider link keys and transient provider sessions. People, external identity
|
|
78
|
+
bindings, the installation sector and the original owner claim are retained.
|
|
79
|
+
Retained dependency links are marked as needing re-link, and provider sign-in
|
|
80
|
+
and first-setup enablement are off after import. Restore does not re-dispatch
|
|
81
|
+
jobs. Run setup after restore to create local configuration and initiate the
|
|
82
|
+
owner-approved provider re-link. The original owner recovers access through
|
|
83
|
+
ordinary native sign-in; setup does not grant a new owner. A new binding or
|
|
84
|
+
product effect needs an explicit policy and integrated proof.
|
|
85
|
+
|
|
86
|
+
Setup reads the declared `rer-setup.json` with the shared reader and validates
|
|
87
|
+
answers against the shared manifest model. The manifest owns fields and managed
|
|
88
|
+
secret generation. `--owner-email` maps to its owner-claim email field; private
|
|
89
|
+
`--answers` uses declared field names. Existing owner, settings and data are kept.
|
|
90
|
+
The owner name is prompted or defaulted only when the installer model declares
|
|
91
|
+
the adapter's name field (normally `displayName`). Nameless installers proceed
|
|
92
|
+
without it and refuse `--owner-name`.
|
|
93
|
+
|
|
94
|
+
Run `node --test --test-concurrency=2 cli/*.test.mjs` from Base. Base's shared tests
|
|
95
|
+
stay in Base; exported seeds carry runtime source and their own adopting tests.
|
|
96
|
+
|
|
97
|
+
## Managed local serving
|
|
98
|
+
|
|
99
|
+
Choose `pnpm run preview` for a fixed production build and `pnpm run dev` for
|
|
100
|
+
source editing with Vite HMR. Preview fingerprints actual source, configuration,
|
|
101
|
+
lockfiles, tool versions and output bytes in a nonsecret `.rer/local` receipt;
|
|
102
|
+
changed or incomplete output is rebuilt. Changes made while serving do not
|
|
103
|
+
rebuild preview. A build that regenerates its own files declares them as
|
|
104
|
+
`generatedOutputs` on the command adapter (see the seed command contract); those
|
|
105
|
+
paths are not inputs, while any other file touched during the build is refused by name. Both use the same `.wrangler/state`, saved owner and ordinary
|
|
106
|
+
fresh sign-in through the development outbox. Stop before changing modes.
|
|
107
|
+
Stop dev or preview before build, verification or data transfer; use the
|
|
108
|
+
documented `--stop` flag or Ctrl-C.
|
|
109
|
+
|
|
110
|
+
The shared public dev/preview proxy gives font bytes a real browser cache
|
|
111
|
+
lifetime so dev stylesheet replacement does not revalidate them on every page
|
|
112
|
+
load. Package fonts and content-hashed URLs are public and immutable for a year;
|
|
113
|
+
unhashed source fonts are public and fresh for an hour. Other response headers
|
|
114
|
+
are preserved, including CSS/JavaScript font imports and error responses. After
|
|
115
|
+
editing a font, hard reload the browser to fetch the changed bytes. Preview
|
|
116
|
+
continues to serve its fixed build; stop and restart it to rebuild edited source.
|
|
117
|
+
Existing seeds receive this policy by refreshing `scripts/base-cli/` with
|
|
118
|
+
`node scripts/export-cli.mjs SEED_ROOT` from Base (which also refreshes its paired
|
|
119
|
+
onboarding copy). For production, adopt the persistent root-head stylesheet,
|
|
120
|
+
primary preload and matched fallback described in `export/UI-CONVENTIONS.md`.
|
|
121
|
+
|
|
122
|
+
Both are managed foreground servers; their first invocation stays active while
|
|
123
|
+
serving. A compatible repeated invocation verifies the registered application,
|
|
124
|
+
prints its safe ready/outbox URLs and exits without a new build or sign-in.
|
|
125
|
+
Explicit conflicting host, port or timeout, or the other mode, refuses with
|
|
126
|
+
exit 4 and the correct stop command. `--stop` is idempotent;
|
|
127
|
+
start-only flags cannot accompany it. It requires no setup or tool versions.
|
|
128
|
+
|
|
129
|
+
### Scheduled triggers under dev
|
|
130
|
+
|
|
131
|
+
`rer dev` runs the Cron Triggers a project declares (`triggers.crons` in
|
|
132
|
+
`wrangler.jsonc` or `wrangler.json`) on their schedule, so alert evaluation,
|
|
133
|
+
retries and checks work on the owner's computer as they do deployed. Each
|
|
134
|
+
minute the CLI calls the local runtime's scheduled test endpoint
|
|
135
|
+
(`/cdn-cgi/handler/scheduled?cron=EXPRESSION`) for every trigger whose
|
|
136
|
+
expression matches, in UTC, and prints one line per run:
|
|
137
|
+
`RER_SCHEDULED 2026-10-10T18:32:00Z "* * * * *" ok 7ms` (or `failed (HTTP 500) ...`;
|
|
138
|
+
`--json` emits a `scheduled` event with `cron`, `ok`, `status`, `ms`). A run that
|
|
139
|
+
is still going when its next minute arrives is reported as skipped. The grammar
|
|
140
|
+
is the one the deploy kit accepts: five numeric fields with lists, ranges and
|
|
141
|
+
steps, day of week 1 (Sunday) to 7; anything else refuses `dev` at start by
|
|
142
|
+
name. Runs go straight to the runtime, so they do not count as activity for the
|
|
143
|
+
idle timeout, and they stop with `dev` (explicit stop, idle timeout, Ctrl-C or
|
|
144
|
+
an application exit). `preview` does not run schedules. A seed that does not
|
|
145
|
+
want this declares one adapter option: `commandAdapter(lifecycle, { scheduled: false, ... })`.
|
|
146
|
+
|
|
147
|
+
### The CLI's own sign-in requests
|
|
148
|
+
|
|
149
|
+
`setup` and every `dev` start ask the local application for one ordinary
|
|
150
|
+
sign-in message (and `setup` claims the first owner) so the outbox is ready.
|
|
151
|
+
Those requests carry `x-rer-local-cli`, an HMAC-SHA256 of `local-cli\0sign-in`
|
|
152
|
+
keyed by the installation's private session secret (the setting the adapter
|
|
153
|
+
declares as `sessionSecretKey`, default `SESSION_SECRET`)
|
|
154
|
+
(`onboarding/adapter-auth.mjs`; checked in
|
|
155
|
+
`modules/operator-auth/local-cli.mjs`). A server in local (loopback) mode skips
|
|
156
|
+
the sign-in and owner-claim rate limit for a request with a valid proof, so
|
|
157
|
+
restarting `dev` any number of times never spends the owner's sign-in budget; a
|
|
158
|
+
person's own sign-in requests, and every request to a non-local server, still
|
|
159
|
+
count exactly as before. Seeds receive the change by refreshing their copies as
|
|
160
|
+
described above.
|
|
161
|
+
|
|
162
|
+
Idle timeout is `--idle-timeout SECONDS`, then `RER_SERVER_IDLE_SECONDS`, then
|
|
163
|
+
43200 seconds (12 hours). Only positive integer seconds are accepted. HTTP requests,
|
|
164
|
+
including assets/outbox, reset inactivity; a live request/stream prevents idle
|
|
165
|
+
shutdown. Internal health probes and Vite HMR control traffic do not prolong
|
|
166
|
+
serving; application WebSocket data messages count. Explicit stop and idle
|
|
167
|
+
expiry clean up owned descendants before releasing state and capacity.
|
|
168
|
+
|
|
169
|
+
The private registry defaults to the OS user's `~/.rer/servers` independently
|
|
170
|
+
of checkout and Codex home; `RER_SERVERS_DIR` selects an isolated directory.
|
|
171
|
+
The combined dev/preview cap is 10 (`RER_SERVER_LIMIT`, positive integer; a limit recorded by a server that did not set it never lowers the cap).
|
|
172
|
+
Starting reservations count. At the cap a start is refused with a plain message
|
|
173
|
+
naming each running server, its checkout and its stop command; rer never stops
|
|
174
|
+
another checkout's server to make room, in any mode. A run that declares itself
|
|
175
|
+
a test or CI journey with `RER_SERVER_JOURNEY=1`, on its own `--port`, neither
|
|
176
|
+
counts toward the cap nor is refused by it; its port must be free, as for any
|
|
177
|
+
server. Concurrent policy uses the stricter active limit among counted servers.
|
|
178
|
+
Symlink/cwd spellings share an instance; distinct worktrees remain distinct.
|
|
179
|
+
A start is also refused while available memory is below 1.5 GiB (`RER_SERVERS_MIN_MEMORY_BYTES`,
|
|
180
|
+
bytes, 0 for no floor), with the memory, the floor, the running servers and the override named.
|
|
181
|
+
Journeys and reuse of a checkout's own server are not refused. `dev` runs the project's own vite
|
|
182
|
+
entry with the pinned Node (no `pnpm exec` wrapper process); `preview`'s resident process holds only
|
|
183
|
+
Miniflare, while a short-lived child resolves the Worker options with Wrangler and hands them over
|
|
184
|
+
through a pipe (secrets never reach an argument).
|
|
185
|
+
|
|
186
|
+
Bounded workflows enter the queue before checkout custody. Managed serving
|
|
187
|
+
reserves under a short machine transaction, releases that transaction, then takes
|
|
188
|
+
checkout custody before finite preparation. A competing local operation refuses
|
|
189
|
+
immediately rather than waiting with a lease. Cleanup stops processes and releases private/state custody
|
|
190
|
+
before removing a generation's registry record. Stop waits never need
|
|
191
|
+
the machine transaction during process cleanup. A stale generation cannot remove
|
|
192
|
+
its replacement. Unverifiable foreign processes are never adopted or signalled.
|
|
193
|
+
|
|
194
|
+
## Bounded work
|
|
195
|
+
|
|
196
|
+
Heavy commands share the dependency-free Base job queue module exported with
|
|
197
|
+
the CLI: install/build/verify, browser suites, setup preparation and temporary app,
|
|
198
|
+
deploy's local build/validation, release's expensive phases and local transfer
|
|
199
|
+
resource work. Serving uses the registry, with finite preparation queued.
|
|
200
|
+
Labels include project, initiating verb/phase and a safe checkout digest. Use
|
|
201
|
+
`node scripts/base-cli/modules/job-queue/cli.mjs status` to inspect admission.
|
|
202
|
+
Waits go to redacted progress/stderr. Nested commands validate live lease
|
|
203
|
+
membership and actual process ancestry before sharing the admitted slot.
|
|
204
|
+
Direct documented browser/runtime entrypoints and indirect package scripts join
|
|
205
|
+
the same executor. Original-caller `CI=true` skips admission; `CI=false` and unset CI queue.
|
|
206
|
+
Heavy verbs alone accept `--no-queue`, only with `CI=true`. Synthesized install
|
|
207
|
+
child CI does not change the original decision. Inspection/help/outbox URL,
|
|
208
|
+
stop and reset inventory/removal do not start a heavy job or application.
|
|
209
|
+
|
|
210
|
+
Run the CLI contract and current first-party seed checks as part of Base's
|
|
211
|
+
documented verification workflow. Structural `check` results and local runtime
|
|
212
|
+
checks do not establish hosted acceptance or provider delivery.
|
|
213
|
+
|
|
214
|
+
Portable hosting adds `--platform workers|container` to build, deploy, dev,
|
|
215
|
+
preview and local export/import. Workers remains the default; container support
|
|
216
|
+
must be declared in deploy.json. Container deploy takes `--host ssh://user@host`
|
|
217
|
+
and a private `--env-file`. See [container hosting](../modules/container/README.md)
|
|
218
|
+
for image/runtime, secrets, SSH and owner setup. `rer archive diff BEFORE AFTER`
|
|
219
|
+
validates both archives and lists changes written during a move without merging.
|
|
220
|
+
|
|
221
|
+
Container SSH deployment also accepts `--image IMAGE` to select an existing local
|
|
222
|
+
image instead of building, and `--bind-address`, `--http-port`, `--https-port` to
|
|
223
|
+
override `deploy.json`'s `container.ingress` bindings. Image identity is pinned
|
|
224
|
+
before transfer. See `modules/container/README.md` for the remote Python/Docker
|
|
225
|
+
requirements, ownership refusal rules and shared TCP/SNI proxy routing.
|
|
226
|
+
|
|
227
|
+
## The installable `rer` command
|
|
228
|
+
|
|
229
|
+
`@runeditrun/rer` packages these same portable sources with `onboarding/` at
|
|
230
|
+
Base's own layout and the global launcher in `global/`. Build it from a Base
|
|
231
|
+
checkout root with `node scripts/rer-package.mjs --out DIR`; the last stdout line
|
|
232
|
+
is the tarball's path. `global/package.json` is the one file that names the next
|
|
233
|
+
release version; a build from a commit not tagged `rer-v<version>` is stamped
|
|
234
|
+
`<version>-dev.g<sha8>`. The installed `rer` finds the nearest `OPERATIONS.json`
|
|
235
|
+
(or exactly `--cwd`, with no upward search) and runs the checkout's pinned `node_modules/@runeditrun/rer`, else
|
|
236
|
+
its vendored `scripts/rer.mjs` in process, else its own bundled `bin/rer.mjs`.
|
|
237
|
+
Global verbs: `rer cli status|install|uninstall`, `rer list [DIR]`, `rer update`,
|
|
238
|
+
and the zero-setup `rer dev`, which composes the pinned dispatcher's public verbs so it
|
|
239
|
+
works on every pin. `global/README.md` is the package's own README; the package
|
|
240
|
+
root also carries the script installer, `install.sh`, kept in `global/`. The build is
|
|
241
|
+
reproducible and `.github/workflows/rer-release.yml` publishes it; see
|
|
242
|
+
`scripts/rer-package/README.md`. `verify:rer` packs, installs and launches it end
|
|
243
|
+
to end, and drives `install.sh` and `rer update` against a local registry.
|
package/cli/adapter.mjs
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { verbs, releaseFlags } from './contract.mjs';
|
|
2
|
+
|
|
3
|
+
// Declarative seed boundary; all spawning, secret custody and readiness live in
|
|
4
|
+
// the existing onboarding kit. No adapter gets a second executor.
|
|
5
|
+
export function commandAdapter(lifecycle, options) {
|
|
6
|
+
const result = { version: 1, ...lifecycle, ...options, state: '.wrangler/state', settings: options.settings ?? ['.dev.vars', '.dev.vars.previous'] };
|
|
7
|
+
result.verbs = Object.fromEntries(Object.entries(verbs).filter(([verb]) => !['export', 'import'].includes(verb) || typeof result.portability?.[verb] === 'function').map(([verb, definition]) => [verb, { flags: [...definition.flags] }]));
|
|
8
|
+
result.verbs.release = { flags: [...releaseFlags] };
|
|
9
|
+
return result;
|
|
10
|
+
}
|
package/cli/ai-local.mjs
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { lstat, readFile } from 'node:fs/promises';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { contained } from './project.mjs';
|
|
4
|
+
import { shared } from './shared.mjs';
|
|
5
|
+
import { refuse, missing } from './errors.mjs';
|
|
6
|
+
import { aiConfig, aiDiagnostics } from '../modules/ai/index.mjs';
|
|
7
|
+
import { validBaseUrl } from '../modules/ai/config.mjs';
|
|
8
|
+
|
|
9
|
+
export const MODELS_FILE = '.rer/local/models.json';
|
|
10
|
+
export async function readLiveModels(root) {
|
|
11
|
+
let file;
|
|
12
|
+
try { file = await contained(root, MODELS_FILE, { privateFile: true }); }
|
|
13
|
+
catch (error) { if (error.code === 'missing_input') return null; throw error; }
|
|
14
|
+
for (const path of ['.rer', '.rer/local', MODELS_FILE]) {
|
|
15
|
+
const status = await lstat(join(root, path));
|
|
16
|
+
if ((status.mode & 0o777) !== (path === MODELS_FILE ? 0o600 : 0o700) || (process.getuid && status.uid !== process.getuid())) throw refuse('Live-dev Models storage requires owned directories 0700 and models.json 0600.');
|
|
17
|
+
}
|
|
18
|
+
let values;
|
|
19
|
+
try { values = JSON.parse(await readFile(file, 'utf8')); } catch { throw refuse('The local Models dev-app file is malformed.'); }
|
|
20
|
+
if (!validBaseUrl(values.service) || typeof values.key !== 'string' || !/^mdl_[A-Za-z0-9_-]{16,}$/.test(values.key)) throw refuse('Use a Models URL and a dev-app key in the local Models file. Provider keys are refused.');
|
|
21
|
+
return { baseUrl: values.service, apiKey: values.key };
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** URL is nonsecret; a dev-app key enters through stdin only, never argv. */
|
|
25
|
+
export async function prepareLiveModels(root, options, store, signal) {
|
|
26
|
+
if ((options.models ?? 'fake') !== 'live') return undefined;
|
|
27
|
+
let live = await readLiveModels(root);
|
|
28
|
+
if (options.modelsService) {
|
|
29
|
+
if (live) throw refuse('A local Models key already exists. Remove models.json explicitly to replace it.');
|
|
30
|
+
if (!validBaseUrl(options.modelsService) || process.stdin.isTTY) throw refuse('Pipe the dev-app key on stdin with --models live --models-service URL.');
|
|
31
|
+
let key = '';
|
|
32
|
+
for await (const chunk of process.stdin) { key += chunk; if (key.length > 4096) throw refuse('The Models key input is too large.'); }
|
|
33
|
+
key = key.trim();
|
|
34
|
+
if (!/^mdl_[A-Za-z0-9_-]{16,}$/.test(key)) throw refuse('Use a Models dev-app key; provider keys are refused.');
|
|
35
|
+
const { privateDirectory, writePrivateFile } = await shared('private-files.mjs');
|
|
36
|
+
const directory = await privateDirectory(root, ['.rer', 'local']);
|
|
37
|
+
await writePrivateFile(join(directory, 'models.json'), JSON.stringify({ service: options.modelsService, key }) + '\n');
|
|
38
|
+
live = await readLiveModels(root);
|
|
39
|
+
}
|
|
40
|
+
if (!live) throw missing('Live dev needs .rer/local/models.json. Create a capped, expiring, cheap-models-only Models dev app, then pipe its key with --models-service URL.');
|
|
41
|
+
store.addSecrets([live.apiKey]);
|
|
42
|
+
const url = live.baseUrl.replace(/\/$/, '') + (live.baseUrl.replace(/\/$/, '').endsWith('/v1') ? '/models' : '/v1/models');
|
|
43
|
+
let providers;
|
|
44
|
+
try {
|
|
45
|
+
const response = await fetch(url, { headers: { authorization: `Bearer ${live.apiKey}` }, redirect: 'error', signal: AbortSignal.any([signal, AbortSignal.timeout(10000)]) });
|
|
46
|
+
if (!response.ok) { await response.body?.cancel(); throw Error(); }
|
|
47
|
+
const listing = await response.json();
|
|
48
|
+
providers = [...new Set(listing.data.flatMap(model => model.providers))];
|
|
49
|
+
if (!providers.length || !providers.every(provider => typeof provider === 'string' && /^[a-zA-Z0-9_-]{1,40}$/.test(provider))) throw Error();
|
|
50
|
+
} catch { throw refuse('The Models dev app could not list its allowed providers. No live-dev server was started.'); }
|
|
51
|
+
store.report(`RER_MODELS_LIVE ${new URL(live.baseUrl).origin} via ${providers.join(', ')}`);
|
|
52
|
+
return live;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export async function localAiDiagnostics(project, overrides = {}) {
|
|
56
|
+
let values = {};
|
|
57
|
+
try {
|
|
58
|
+
const { readSettings } = await shared('adapter-settings.mjs');
|
|
59
|
+
if (project.adapter?.hooks?.secrets) values = (await readSettings(project.root, project.adapter.hooks.secrets)).values;
|
|
60
|
+
} catch {}
|
|
61
|
+
const issues = aiDiagnostics(aiConfig({ ...values, ...overrides }, project.adapter?.ai?.features));
|
|
62
|
+
try { await readLiveModels(project.root); }
|
|
63
|
+
catch { issues.push({ feature: 'live-dev', code: 'ai_misconfigured', message: 'The local Models dev-app file or its permissions are unsafe.' }); }
|
|
64
|
+
return issues;
|
|
65
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { lstat, realpath } from 'node:fs/promises';
|
|
2
|
+
import { isAbsolute, relative, resolve, parse, sep, dirname, basename } from 'node:path';
|
|
3
|
+
import { contained } from './project.mjs';
|
|
4
|
+
import { refuse } from './errors.mjs';
|
|
5
|
+
import { viteServesArchive } from './archive-vite.mjs';
|
|
6
|
+
|
|
7
|
+
const message = 'Save the archive at a normalized path inside this checkout\'s exports/ (exports/x.rer, ./exports/x.rer or an absolute path there), or at an absolute path outside this checkout. Traversal (..), unsafe symlinks and paths served by the app are refused.';
|
|
8
|
+
// Static refusals (shape, location, links) run here and touch nothing. `unserved()` then asks the seed's
|
|
9
|
+
// real Vite configuration whether the app would serve the path; the caller runs it after prepareData, because
|
|
10
|
+
// that configuration may need a file only prepareData generates (a checkout that never built has none yet).
|
|
11
|
+
export async function locateExport(root, file) {
|
|
12
|
+
const checkout = await realpath(root);
|
|
13
|
+
const located = destination => ({ path: destination, unserved: () => requireUnserved(checkout, destination) });
|
|
14
|
+
if ((!isAbsolute(file) && file.includes('\\')) || file.split(/[\\/]/).includes('..')) throw refuse(message);
|
|
15
|
+
if (!isAbsolute(file)) {
|
|
16
|
+
return located(await insideExports(checkout, relative(checkout, resolve(checkout, file))));
|
|
17
|
+
}
|
|
18
|
+
let destination = resolve(file); const within = relative(checkout, destination);
|
|
19
|
+
if (inside(within)) return located(await insideExports(checkout, within));
|
|
20
|
+
// Resolve existing ancestors, including platform temporary-directory aliases.
|
|
21
|
+
// A link outside the checkout must not put the export back inside it.
|
|
22
|
+
let current = parse(destination).root;
|
|
23
|
+
const parts = destination.slice(current.length).split(sep);
|
|
24
|
+
for (const [index, part] of parts.entries()) {
|
|
25
|
+
current = resolve(current, part);
|
|
26
|
+
const status = await lstat(current).catch(error => { if (error.code === 'ENOENT') return null; throw error; });
|
|
27
|
+
if (!status) break;
|
|
28
|
+
const actual = await realpath(current), name = relative(checkout, actual);
|
|
29
|
+
// Parent aliases (such as macOS /var) can lead to the real checkout root.
|
|
30
|
+
// Once there, validate the remaining path without resolving its symlinks.
|
|
31
|
+
if (!name && !status.isSymbolicLink()) return located(await insideExports(checkout, parts.slice(index + 1).join(sep)));
|
|
32
|
+
if (inside(name)) throw refuse(message);
|
|
33
|
+
if (index === parts.length - 1 && status.isSymbolicLink()) throw refuse(message);
|
|
34
|
+
current = actual;
|
|
35
|
+
destination = resolve(current, ...parts.slice(index + 1));
|
|
36
|
+
}
|
|
37
|
+
return located(destination);
|
|
38
|
+
}
|
|
39
|
+
const inside = path => !path || (!isAbsolute(path) && path !== '..' && !path.startsWith('..' + sep));
|
|
40
|
+
async function insideExports(checkout, path) {
|
|
41
|
+
if (!path.startsWith('exports' + sep) || !inside(path)) throw refuse(message);
|
|
42
|
+
return contained(checkout, path, { optional: true });
|
|
43
|
+
}
|
|
44
|
+
async function requireUnserved(root, destination) {
|
|
45
|
+
try { if (await viteServesArchive(root, destination)) throw Error('Served destination'); }
|
|
46
|
+
catch { throw refuse(message); }
|
|
47
|
+
}
|
|
48
|
+
export async function locateImport(root, file) {
|
|
49
|
+
if (!isAbsolute(file)) return { path: await contained(root, file, { privateFile: true }), unserved: async () => {} };
|
|
50
|
+
const { path, unserved } = await locateExport(root, file);
|
|
51
|
+
return { path: await contained(dirname(path), basename(path), { privateFile: true }), unserved };
|
|
52
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { access, lstat, realpath } from 'node:fs/promises';
|
|
2
|
+
import { createRequire } from 'node:module';
|
|
3
|
+
import { join, relative, resolve, isAbsolute, sep, dirname, basename } from 'node:path';
|
|
4
|
+
import { pathToFileURL } from 'node:url';
|
|
5
|
+
|
|
6
|
+
const inside = (parent, child) => { const path = relative(parent, child); return !path || (!isAbsolute(path) && path !== '..' && !path.startsWith('..' + sep)); };
|
|
7
|
+
async function resolvedDirectory(directory) {
|
|
8
|
+
const pending = [];
|
|
9
|
+
for (;;) {
|
|
10
|
+
const actual = await realpath(directory).catch(error => { if (error.code === 'ENOENT') return null; throw error; });
|
|
11
|
+
if (actual) return resolve(actual, ...pending);
|
|
12
|
+
const status = await lstat(directory).catch(error => { if (error.code === 'ENOENT') return null; throw error; });
|
|
13
|
+
if (status?.isSymbolicLink()) throw new Error('Configured served directory has an unresolved link.');
|
|
14
|
+
pending.unshift(basename(directory)); directory = dirname(directory);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
function buildDirectories(config) {
|
|
18
|
+
const builds = [config.build, ...Object.values(config.environments ?? {}).map(environment => environment.build)].filter(Boolean);
|
|
19
|
+
return builds.flatMap(build => {
|
|
20
|
+
const outputs = Array.isArray(build.rollupOptions?.output) ? build.rollupOptions.output : [build.rollupOptions?.output];
|
|
21
|
+
return [build.outDir, ...outputs.filter(Boolean).flatMap(output => [output.dir, output.file && dirname(output.file)])];
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
// Resolve the actual config, including plugin hooks and Vite's implicit
|
|
25
|
+
// filesystem allowance. Reading the file alone misses folders a plugin adds.
|
|
26
|
+
export async function viteServesArchive(root, destination) {
|
|
27
|
+
const names = ['vite.config.ts','vite.config.mts','vite.config.js','vite.config.mjs','vite.config.cjs','vite.config.cts'];
|
|
28
|
+
let configFile;
|
|
29
|
+
for (const name of names) if (await access(join(root, name)).then(() => true, error => { if (error.code === 'ENOENT') return false; throw error; })) { configFile = join(root, name); break; }
|
|
30
|
+
if (!configFile) return false;
|
|
31
|
+
const require = createRequire(join(root, 'package.json'));
|
|
32
|
+
const { resolveConfig } = await import(pathToFileURL(require.resolve('vite')).href);
|
|
33
|
+
for (const command of ['serve', 'build']) {
|
|
34
|
+
const mode = command === 'build' ? 'production' : 'development';
|
|
35
|
+
const previousNodeEnv = process.env.NODE_ENV, previousCloudflareBuild = process.env.CLOUDFLARE_VITE_BUILD;
|
|
36
|
+
let config;
|
|
37
|
+
try {
|
|
38
|
+
process.env.NODE_ENV = previousNodeEnv ?? mode;
|
|
39
|
+
config = await resolveConfig({ root, configFile, mode, logLevel: 'silent' }, command, mode, mode);
|
|
40
|
+
} finally {
|
|
41
|
+
if (previousNodeEnv === undefined) delete process.env.NODE_ENV; else process.env.NODE_ENV = previousNodeEnv;
|
|
42
|
+
if (previousCloudflareBuild === undefined) delete process.env.CLOUDFLARE_VITE_BUILD; else process.env.CLOUDFLARE_VITE_BUILD = previousCloudflareBuild;
|
|
43
|
+
}
|
|
44
|
+
const base = config.root;
|
|
45
|
+
if (config.server?.fs?.strict === false) return true;
|
|
46
|
+
const directories = [config.publicDir, ...buildDirectories(config), ...config.server.fs.allow].filter(path => typeof path === 'string');
|
|
47
|
+
for (const name of directories) {
|
|
48
|
+
// An uncreated output/public folder can still sit below /tmp or another
|
|
49
|
+
// linked ancestor. Compare its future real location with the export path.
|
|
50
|
+
const directory = await resolvedDirectory(resolve(base, name));
|
|
51
|
+
if (inside(directory, destination)) return true;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return false;
|
|
55
|
+
}
|
package/cli/archive.mjs
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Readable } from 'node:stream';
|
|
2
|
+
import { createReadStream } from 'node:fs';
|
|
3
|
+
import { diffArchives } from '../modules/portability/diff.mjs';
|
|
4
|
+
import { invalid } from './errors.mjs';
|
|
5
|
+
export async function archiveCommand(args,out) {
|
|
6
|
+
if (args.length!==3 || args[0]!=='diff') throw invalid('Usage: rer archive diff BEFORE AFTER');
|
|
7
|
+
const result=await diffArchives(Readable.toWeb(createReadStream(args[1])),Readable.toWeb(createReadStream(args[2]))); out.human(JSON.stringify(result,null,2)); return 0;
|
|
8
|
+
}
|