@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.
Files changed (526) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +154 -2
  3. package/bin/rer.mjs +3 -0
  4. package/cli/README.md +243 -0
  5. package/cli/adapter.mjs +10 -0
  6. package/cli/ai-local.mjs +65 -0
  7. package/cli/archive-path.mjs +52 -0
  8. package/cli/archive-vite.mjs +55 -0
  9. package/cli/archive.mjs +8 -0
  10. package/cli/auth-copy.mjs +80 -0
  11. package/cli/bounded.mjs +70 -0
  12. package/cli/cache-doctor.mjs +63 -0
  13. package/cli/container-transfer.mjs +35 -0
  14. package/cli/container.mjs +62 -0
  15. package/cli/contract.mjs +25 -0
  16. package/cli/dependencies.mjs +45 -0
  17. package/cli/dependency-approval.mjs +33 -0
  18. package/cli/dependency-doctor.mjs +34 -0
  19. package/cli/dependency-input.mjs +43 -0
  20. package/cli/deploy-config.mjs +118 -0
  21. package/cli/deploy.mjs +37 -0
  22. package/cli/dev-identity.mjs +80 -0
  23. package/cli/errors.mjs +14 -0
  24. package/cli/export.mjs +42 -0
  25. package/cli/font-cache.mjs +29 -0
  26. package/cli/hosted-output.mjs +110 -0
  27. package/cli/independent.mjs +29 -0
  28. package/cli/inspect.mjs +174 -0
  29. package/cli/jsonc.mjs +111 -0
  30. package/cli/lifecycle.mjs +148 -0
  31. package/cli/local.mjs +100 -0
  32. package/cli/main.mjs +57 -0
  33. package/cli/managed-server.mjs +143 -0
  34. package/cli/node-runtime-cache.mjs +68 -0
  35. package/cli/node-runtime-discovery.mjs +56 -0
  36. package/cli/node-runtime-download.mjs +59 -0
  37. package/cli/node-runtime.mjs +50 -0
  38. package/cli/output.mjs +22 -0
  39. package/cli/parse.mjs +77 -0
  40. package/cli/port.mjs +52 -0
  41. package/cli/portability-worker.mjs +56 -0
  42. package/cli/portability.mjs +66 -0
  43. package/cli/preview-cache.mjs +99 -0
  44. package/cli/project.mjs +48 -0
  45. package/cli/release.mjs +24 -0
  46. package/cli/runtime-front-door.mjs +46 -0
  47. package/cli/scheduled.mjs +81 -0
  48. package/cli/server-activity.mjs +12 -0
  49. package/cli/server-proxy.mjs +93 -0
  50. package/cli/server-registry.mjs +177 -0
  51. package/cli/server-resources.mjs +22 -0
  52. package/cli/settings.mjs +15 -0
  53. package/cli/setup-answers.mjs +29 -0
  54. package/cli/setup-input.mjs +113 -0
  55. package/cli/shared.mjs +7 -0
  56. package/cli/transfers.mjs +33 -0
  57. package/cli/version.mjs +36 -0
  58. package/composition/git-source.mjs +111 -0
  59. package/edition-authoring/files.mjs +81 -0
  60. package/edition-authoring/manifest.mjs +65 -0
  61. package/global/README.md +155 -0
  62. package/global/checkout.mjs +72 -0
  63. package/global/cli/command.mjs +13 -0
  64. package/global/cli/install.mjs +75 -0
  65. package/global/cli/layout.mjs +45 -0
  66. package/global/cli/status.mjs +54 -0
  67. package/global/cli/uninstall.mjs +36 -0
  68. package/global/delegate.mjs +13 -0
  69. package/global/launch/capacity.mjs +72 -0
  70. package/global/launch/dev.mjs +129 -0
  71. package/global/launch/facts.mjs +93 -0
  72. package/global/launch/failure.mjs +5 -0
  73. package/global/launch/local-defaults.mjs +4 -0
  74. package/global/launch/prepare.mjs +61 -0
  75. package/global/launch/render.mjs +44 -0
  76. package/global/launch/state.mjs +97 -0
  77. package/global/launch/steps.mjs +81 -0
  78. package/global/launch/worker.mjs +43 -0
  79. package/global/list.mjs +59 -0
  80. package/global/main.mjs +53 -0
  81. package/global/package-info.mjs +38 -0
  82. package/global/registry.mjs +24 -0
  83. package/global/rer.mjs +29 -0
  84. package/global/update/archive.mjs +89 -0
  85. package/global/update/command.mjs +90 -0
  86. package/global/update/latest.mjs +6 -0
  87. package/global/update/notice.mjs +58 -0
  88. package/global/update/registry.mjs +47 -0
  89. package/global/version.mjs +29 -0
  90. package/install.sh +144 -0
  91. package/modules/ai/LICENSE +21 -0
  92. package/modules/ai/README.md +90 -0
  93. package/modules/ai/client.mjs +71 -0
  94. package/modules/ai/config.mjs +39 -0
  95. package/modules/ai/dev/index.d.mts +6 -0
  96. package/modules/ai/dev/index.mjs +64 -0
  97. package/modules/ai/dev/outbox.mjs +33 -0
  98. package/modules/ai/errors.mjs +28 -0
  99. package/modules/ai/fake/index.d.mts +3 -0
  100. package/modules/ai/fake/index.mjs +82 -0
  101. package/modules/ai/index.d.mts +10 -0
  102. package/modules/ai/index.mjs +3 -0
  103. package/modules/ai/package.json +6 -0
  104. package/modules/container/README.md +156 -0
  105. package/modules/container/adapters/d1.mjs +34 -0
  106. package/modules/container/adapters/egress.mjs +40 -0
  107. package/modules/container/adapters/jobs.mjs +47 -0
  108. package/modules/container/adapters/objects.mjs +84 -0
  109. package/modules/container/adapters/retained.mjs +14 -0
  110. package/modules/container/adapters/sqlite-error.mjs +7 -0
  111. package/modules/container/adapters/sqlite-worker.mjs +26 -0
  112. package/modules/container/assets.mjs +14 -0
  113. package/modules/container/bindings.mjs +1 -0
  114. package/modules/container/boundary.mjs +38 -0
  115. package/modules/container/build.mjs +65 -0
  116. package/modules/container/deploy-input.mjs +17 -0
  117. package/modules/container/entrypoint.sh +5 -0
  118. package/modules/container/host.mjs +43 -0
  119. package/modules/container/ingress.mjs +23 -0
  120. package/modules/container/lock.mjs +11 -0
  121. package/modules/container/migrations.mjs +16 -0
  122. package/modules/container/node-engine.mjs +39 -0
  123. package/modules/container/portability-schema.mjs +14 -0
  124. package/modules/container/remote/deploy.py +76 -0
  125. package/modules/container/remote/files.py +275 -0
  126. package/modules/container/remote/resources.py +157 -0
  127. package/modules/container/runner.mjs +10 -0
  128. package/modules/container/ssh-plan.mjs +44 -0
  129. package/modules/container/ssh.mjs +63 -0
  130. package/modules/container/transfer.mjs +27 -0
  131. package/modules/container/worker-engine.mjs +32 -0
  132. package/modules/dependencies/README.md +211 -0
  133. package/modules/dependencies/approval.mjs +51 -0
  134. package/modules/dependencies/auth.mjs +40 -0
  135. package/modules/dependencies/authority.mjs +14 -0
  136. package/modules/dependencies/crypto.mjs +13 -0
  137. package/modules/dependencies/index.d.mts +23 -0
  138. package/modules/dependencies/index.mjs +113 -0
  139. package/modules/dependencies/logout.mjs +42 -0
  140. package/modules/dependencies/native.mjs +9 -0
  141. package/modules/dependencies/protocol.mjs +23 -0
  142. package/modules/dependencies/schema/approval-attempt.sql +3 -0
  143. package/modules/dependencies/schema/dependencies.sql +15 -0
  144. package/modules/dependencies/store.mjs +19 -0
  145. package/modules/deploy-kit/README.md +308 -0
  146. package/modules/deploy-kit/artifact.mjs +47 -0
  147. package/modules/deploy-kit/build-modules.mjs +21 -0
  148. package/modules/deploy-kit/check.mjs +13 -0
  149. package/modules/deploy-kit/cli.mjs +50 -0
  150. package/modules/deploy-kit/container-config.mjs +8 -0
  151. package/modules/deploy-kit/default-stage.mjs +14 -0
  152. package/modules/deploy-kit/deploy.mjs +80 -0
  153. package/modules/deploy-kit/health-request.mjs +86 -0
  154. package/modules/deploy-kit/health.mjs +99 -0
  155. package/modules/deploy-kit/index.mjs +12 -0
  156. package/modules/deploy-kit/local-only.mjs +10 -0
  157. package/modules/deploy-kit/migrations.mjs +48 -0
  158. package/modules/deploy-kit/owner-cli.mjs +63 -0
  159. package/modules/deploy-kit/owner.mjs +297 -0
  160. package/modules/deploy-kit/prepare.mjs +62 -0
  161. package/modules/deploy-kit/provider.mjs +99 -0
  162. package/modules/deploy-kit/queue-consumer.mjs +10 -0
  163. package/modules/deploy-kit/receipt.mjs +16 -0
  164. package/modules/deploy-kit/render.mjs +47 -0
  165. package/modules/deploy-kit/resources.mjs +106 -0
  166. package/modules/deploy-kit/service-grants.mjs +25 -0
  167. package/modules/deploy-kit/sql-safety.mjs +94 -0
  168. package/modules/deploy-kit/sql-tokens.mjs +49 -0
  169. package/modules/deploy-kit/teardown.mjs +100 -0
  170. package/modules/deploy-kit/templates.mjs +31 -0
  171. package/modules/deploy-kit/validation.mjs +58 -0
  172. package/modules/deploy-kit/worker.mjs +105 -0
  173. package/modules/erasure/CONTRACT.md +90 -0
  174. package/modules/erasure/README.md +221 -0
  175. package/modules/erasure/audit.mjs +23 -0
  176. package/modules/erasure/blobs.mjs +45 -0
  177. package/modules/erasure/cascade.mjs +91 -0
  178. package/modules/erasure/completion.mjs +62 -0
  179. package/modules/erasure/declaration.mjs +51 -0
  180. package/modules/erasure/fence.mjs +19 -0
  181. package/modules/erasure/index.d.mts +62 -0
  182. package/modules/erasure/index.mjs +85 -0
  183. package/modules/erasure/order.mjs +56 -0
  184. package/modules/erasure/plan.mjs +121 -0
  185. package/modules/erasure/rate.mjs +57 -0
  186. package/modules/erasure/receipt.mjs +32 -0
  187. package/modules/erasure/root.mjs +21 -0
  188. package/modules/erasure/schema/erasure-rates.sql +5 -0
  189. package/modules/erasure/schema/erasure.sql +27 -0
  190. package/modules/erasure/scope.mjs +29 -0
  191. package/modules/erasure/sql.mjs +23 -0
  192. package/modules/erasure/verification.mjs +69 -0
  193. package/modules/integrations/core/CONTRACT.md +50 -0
  194. package/modules/integrations/core/README.md +27 -0
  195. package/modules/integrations/core/crypto.ts +19 -0
  196. package/modules/integrations/core/database.ts +21 -0
  197. package/modules/integrations/core/delivery.ts +97 -0
  198. package/modules/integrations/core/destination.ts +13 -0
  199. package/modules/integrations/core/index.ts +7 -0
  200. package/modules/integrations/core/node-transport.ts +72 -0
  201. package/modules/integrations/core/public-address.ts +57 -0
  202. package/modules/integrations/core/repository.ts +74 -0
  203. package/modules/integrations/core/schema.sql +36 -0
  204. package/modules/integrations/core/sqlite.ts +20 -0
  205. package/modules/integrations/core/timestamped-body-signature.ts +38 -0
  206. package/modules/integrations/core/tokens.ts +71 -0
  207. package/modules/integrations/core/types.ts +52 -0
  208. package/modules/integrations/core/upgrade-token-usage-context.sql +5 -0
  209. package/modules/integrations/core/webhook.ts +73 -0
  210. package/modules/job-queue/README.md +173 -0
  211. package/modules/job-queue/cli.mjs +64 -0
  212. package/modules/job-queue/command.mjs +64 -0
  213. package/modules/job-queue/config.mjs +48 -0
  214. package/modules/job-queue/identity.mjs +48 -0
  215. package/modules/job-queue/index.mjs +135 -0
  216. package/modules/job-queue/membership.mjs +30 -0
  217. package/modules/job-queue/module.json +10 -0
  218. package/modules/job-queue/policy.mjs +29 -0
  219. package/modules/job-queue/processes.mjs +80 -0
  220. package/modules/job-queue/resources.mjs +37 -0
  221. package/modules/job-queue/storage.mjs +64 -0
  222. package/modules/job-queue/supervisor.mjs +30 -0
  223. package/modules/job-queue/waiting.mjs +16 -0
  224. package/modules/mail/LICENSE +21 -0
  225. package/modules/mail/README.md +336 -0
  226. package/modules/mail/doctor.mjs +81 -0
  227. package/modules/mail/index.mjs +8 -0
  228. package/modules/mail/live-proof/README.md +113 -0
  229. package/modules/mail/live-proof/run.mjs +55 -0
  230. package/modules/mail/package.json +19 -0
  231. package/modules/mail/pnpm-lock.yaml +537 -0
  232. package/modules/mail/src/adapters/cloudflare/README.md +84 -0
  233. package/modules/mail/src/adapters/cloudflare/headers.mjs +63 -0
  234. package/modules/mail/src/adapters/cloudflare/index.mjs +47 -0
  235. package/modules/mail/src/adapters/cloudflare/response.mjs +99 -0
  236. package/modules/mail/src/adapters/messaging/README.md +92 -0
  237. package/modules/mail/src/adapters/messaging/contract.mjs +66 -0
  238. package/modules/mail/src/adapters/messaging/event-schema.mjs +28 -0
  239. package/modules/mail/src/adapters/messaging/index.mjs +61 -0
  240. package/modules/mail/src/adapters/messaging/jws.mjs +68 -0
  241. package/modules/mail/src/adapters/messaging/request.mjs +52 -0
  242. package/modules/mail/src/adapters/messaging/serialize.mjs +21 -0
  243. package/modules/mail/src/adapters/resend/README.md +120 -0
  244. package/modules/mail/src/adapters/resend/index.mjs +22 -0
  245. package/modules/mail/src/adapters/resend/response.mjs +54 -0
  246. package/modules/mail/src/adapters/resend/serialize.mjs +46 -0
  247. package/modules/mail/src/adapters/resend/size.mjs +99 -0
  248. package/modules/mail/src/adapters/sendgrid/README.md +75 -0
  249. package/modules/mail/src/adapters/sendgrid/index.mjs +35 -0
  250. package/modules/mail/src/adapters/sendgrid/serialize.mjs +104 -0
  251. package/modules/mail/src/core/errors.mjs +9 -0
  252. package/modules/mail/src/core/transport.mjs +33 -0
  253. package/modules/mail/src/core/validation.mjs +172 -0
  254. package/modules/mail/src/development/index.d.mts +37 -0
  255. package/modules/mail/src/development/index.mjs +35 -0
  256. package/modules/mail/src/development/outbox.mjs +78 -0
  257. package/modules/mail/src/development/schema.sql +9 -0
  258. package/modules/mail/src/development/viewer-html.mjs +42 -0
  259. package/modules/mail/src/development/viewer.mjs +65 -0
  260. package/modules/mail/src/doctor/README.md +107 -0
  261. package/modules/mail/src/doctor/common.mjs +64 -0
  262. package/modules/mail/src/doctor/dns.mjs +102 -0
  263. package/modules/mail/src/doctor/index.mjs +28 -0
  264. package/modules/mail/src/doctor/probe.mjs +66 -0
  265. package/modules/mail/src/doctor/receive.mjs +81 -0
  266. package/modules/mail/src/doctor/records.mjs +45 -0
  267. package/modules/mail/src/events/README.md +268 -0
  268. package/modules/mail/src/events/d1-schema.sql +25 -0
  269. package/modules/mail/src/events/d1-storage.mjs +76 -0
  270. package/modules/mail/src/events/index.mjs +3 -0
  271. package/modules/mail/src/events/intake.mjs +201 -0
  272. package/modules/mail/src/events/storage.mjs +52 -0
  273. package/modules/mail/src/events/verify.mjs +92 -0
  274. package/modules/mail/src/inbound/README.md +137 -0
  275. package/modules/mail/src/inbound/bytes.mjs +91 -0
  276. package/modules/mail/src/inbound/headers.mjs +143 -0
  277. package/modules/mail/src/inbound/index.mjs +29 -0
  278. package/modules/mail/src/inbound/mime.mjs +36 -0
  279. package/modules/mail/src/inbound/multipart.mjs +27 -0
  280. package/modules/mail/src/inbound/resend-attachment.mjs +43 -0
  281. package/modules/mail/src/inbound/resend.mjs +54 -0
  282. package/modules/mail/src/inbound/sendgrid.mjs +60 -0
  283. package/modules/mail/src/sender.mjs +33 -0
  284. package/modules/mail/src/sendgrid-email/index.d.mts +33 -0
  285. package/modules/mail/src/sendgrid-email/index.mjs +86 -0
  286. package/modules/mail/src/unsubscribe/index.mjs +142 -0
  287. package/modules/operator-auth/README.md +599 -0
  288. package/modules/operator-auth/accounts/adapter.mjs +41 -0
  289. package/modules/operator-auth/accounts/admin.mjs +159 -0
  290. package/modules/operator-auth/accounts/credentials.mjs +27 -0
  291. package/modules/operator-auth/accounts/editor-owner.mjs +13 -0
  292. package/modules/operator-auth/accounts/index.d.mts +9 -0
  293. package/modules/operator-auth/accounts/index.mjs +9 -0
  294. package/modules/operator-auth/accounts/native.d.mts +38 -0
  295. package/modules/operator-auth/accounts/native.mjs +171 -0
  296. package/modules/operator-auth/accounts/oa.mjs +90 -0
  297. package/modules/operator-auth/accounts/provider-control.mjs +50 -0
  298. package/modules/operator-auth/accounts/provider-pin.mjs +14 -0
  299. package/modules/operator-auth/accounts/roles.mjs +26 -0
  300. package/modules/operator-auth/accounts/schema/dependency-setup.sql +17 -0
  301. package/modules/operator-auth/accounts/schema/dev-sessions.sql +22 -0
  302. package/modules/operator-auth/accounts/schema/domain-rules-step-up.sql +20 -0
  303. package/modules/operator-auth/accounts/schema/invitation-cancellation.sql +17 -0
  304. package/modules/operator-auth/accounts/schema/operator-auth.sql +142 -0
  305. package/modules/operator-auth/accounts/schema/provider-control.sql +30 -0
  306. package/modules/operator-auth/accounts/schema/provider-pins.sql +6 -0
  307. package/modules/operator-auth/accounts/settings-page.mjs +4 -0
  308. package/modules/operator-auth/accounts/store.mjs +246 -0
  309. package/modules/operator-auth/branding.mjs +66 -0
  310. package/modules/operator-auth/config.mjs +35 -0
  311. package/modules/operator-auth/conformance/README.md +81 -0
  312. package/modules/operator-auth/conformance/index.d.mts +43 -0
  313. package/modules/operator-auth/conformance/index.mjs +300 -0
  314. package/modules/operator-auth/conformance/presentation.mjs +57 -0
  315. package/modules/operator-auth/crypto.mjs +17 -0
  316. package/modules/operator-auth/dev/badge.mjs +62 -0
  317. package/modules/operator-auth/dev/index.d.mts +14 -0
  318. package/modules/operator-auth/dev/index.mjs +137 -0
  319. package/modules/operator-auth/dev/personas.mjs +17 -0
  320. package/modules/operator-auth/dev/sign-in-as.d.mts +3 -0
  321. package/modules/operator-auth/dev/sign-in-as.mjs +25 -0
  322. package/modules/operator-auth/dev-admission.d.mts +4 -0
  323. package/modules/operator-auth/dev-admission.mjs +10 -0
  324. package/modules/operator-auth/dev-gate.mjs +86 -0
  325. package/modules/operator-auth/docs/README.md +78 -0
  326. package/modules/operator-auth/docs/native-accounts.md +313 -0
  327. package/modules/operator-auth/docs/tanstack-start.md +218 -0
  328. package/modules/operator-auth/docs/vite-spa.md +144 -0
  329. package/modules/operator-auth/errors.mjs +9 -0
  330. package/modules/operator-auth/http.mjs +42 -0
  331. package/modules/operator-auth/identity/admission.mjs +105 -0
  332. package/modules/operator-auth/identity/after-confirm.mjs +18 -0
  333. package/modules/operator-auth/identity/email-link/confirmation.mjs +14 -0
  334. package/modules/operator-auth/identity/email-link/index.d.mts +48 -0
  335. package/modules/operator-auth/identity/email-link/index.mjs +128 -0
  336. package/modules/operator-auth/identity/email-link/message.mjs +16 -0
  337. package/modules/operator-auth/identity/index.d.mts +7 -0
  338. package/modules/operator-auth/identity/index.mjs +5 -0
  339. package/modules/operator-auth/identity/oidc/README.md +171 -0
  340. package/modules/operator-auth/identity/oidc/client-auth.mjs +16 -0
  341. package/modules/operator-auth/identity/oidc/config.mjs +102 -0
  342. package/modules/operator-auth/identity/oidc/crypto.mjs +29 -0
  343. package/modules/operator-auth/identity/oidc/errors.mjs +5 -0
  344. package/modules/operator-auth/identity/oidc/index.d.mts +33 -0
  345. package/modules/operator-auth/identity/oidc/index.mjs +287 -0
  346. package/modules/operator-auth/identity/oidc/jwt.mjs +102 -0
  347. package/modules/operator-auth/identity/oidc/network.mjs +93 -0
  348. package/modules/operator-auth/identity/oidc/presets.mjs +26 -0
  349. package/modules/operator-auth/identity/oidc/schema/oidc.sql +50 -0
  350. package/modules/operator-auth/identity/oidc/store.mjs +68 -0
  351. package/modules/operator-auth/identity/principal.mjs +28 -0
  352. package/modules/operator-auth/index.d.mts +223 -0
  353. package/modules/operator-auth/index.mjs +11 -0
  354. package/modules/operator-auth/input.mjs +55 -0
  355. package/modules/operator-auth/local-cli.mjs +16 -0
  356. package/modules/operator-auth/page.mjs +34 -0
  357. package/modules/operator-auth/policy.mjs +20 -0
  358. package/modules/operator-auth/routes.mjs +91 -0
  359. package/modules/operator-auth/service.mjs +152 -0
  360. package/modules/operator-auth/signin/index.mjs +67 -0
  361. package/modules/owner-claim/README.md +137 -0
  362. package/modules/owner-claim/idp.mjs +40 -0
  363. package/modules/owner-claim/index.d.mts +27 -0
  364. package/modules/owner-claim/index.mjs +39 -0
  365. package/modules/owner-claim/page.mjs +11 -0
  366. package/modules/owner-claim/schema/idp.sql +4 -0
  367. package/modules/owner-claim/schema/owner-claim.sql +18 -0
  368. package/modules/owner-claim/transaction.mjs +87 -0
  369. package/modules/owner-claim/verify.mjs +80 -0
  370. package/modules/portability/README.md +444 -0
  371. package/modules/portability/bridge.mjs +102 -0
  372. package/modules/portability/catalogue.mjs +118 -0
  373. package/modules/portability/cli-options.mjs +38 -0
  374. package/modules/portability/cli.mjs +56 -0
  375. package/modules/portability/copies.mjs +68 -0
  376. package/modules/portability/dev-data.mjs +32 -0
  377. package/modules/portability/diff.mjs +33 -0
  378. package/modules/portability/export.mjs +129 -0
  379. package/modules/portability/files.mjs +65 -0
  380. package/modules/portability/format.mjs +122 -0
  381. package/modules/portability/generated.mjs +60 -0
  382. package/modules/portability/hash.mjs +79 -0
  383. package/modules/portability/http.mjs +42 -0
  384. package/modules/portability/import.mjs +185 -0
  385. package/modules/portability/index.d.mts +58 -0
  386. package/modules/portability/index.mjs +22 -0
  387. package/modules/portability/journal.mjs +49 -0
  388. package/modules/portability/legacy-files.mjs +43 -0
  389. package/modules/portability/legacy-safety.mjs +27 -0
  390. package/modules/portability/lines.mjs +36 -0
  391. package/modules/portability/migration-history.mjs +18 -0
  392. package/modules/portability/migration-statements.mjs +23 -0
  393. package/modules/portability/payloads.mjs +52 -0
  394. package/modules/portability/provider-data.mjs +25 -0
  395. package/modules/portability/restore-safety.mjs +30 -0
  396. package/modules/portability/schema/portability.sql +25 -0
  397. package/modules/portability/storage.mjs +49 -0
  398. package/modules/release/README.md +212 -0
  399. package/modules/release/catalogue.mjs +79 -0
  400. package/modules/release/export.mjs +51 -0
  401. package/modules/release/produce.mjs +136 -0
  402. package/modules/release/public-child-transport-state.cjs +29 -0
  403. package/modules/release/public-child.mjs +71 -0
  404. package/modules/release/public-git.mjs +21 -0
  405. package/modules/release/publication-scan.mjs +22 -0
  406. package/modules/release/publish-handoff.mjs +37 -0
  407. package/modules/release/source.mjs +71 -0
  408. package/modules/release/test-summary.mjs +50 -0
  409. package/onboarding/README.md +163 -0
  410. package/onboarding/activity.mjs +31 -0
  411. package/onboarding/adapter-auth.mjs +88 -0
  412. package/onboarding/adapter-hosting.mjs +35 -0
  413. package/onboarding/adapter-labels.mjs +13 -0
  414. package/onboarding/adapter-settings.mjs +129 -0
  415. package/onboarding/adapter.mjs +238 -0
  416. package/onboarding/agent-handoff.mjs +9 -0
  417. package/onboarding/app-processes.mjs +21 -0
  418. package/onboarding/archive-output.d.mts +3 -0
  419. package/onboarding/archive-output.mjs +54 -0
  420. package/onboarding/command-custody.mjs +24 -0
  421. package/onboarding/command-recovery.mjs +8 -0
  422. package/onboarding/commands.mjs +166 -0
  423. package/onboarding/dependency-approval.mjs +36 -0
  424. package/onboarding/dev-identity.mjs +23 -0
  425. package/onboarding/email.mjs +24 -0
  426. package/onboarding/failures.mjs +42 -0
  427. package/onboarding/input-limits.mjs +7 -0
  428. package/onboarding/installer-inputs.mjs +24 -0
  429. package/onboarding/launcher.mjs +34 -0
  430. package/onboarding/local/build-files.mjs +64 -0
  431. package/onboarding/local/build.mjs +49 -0
  432. package/onboarding/local/environment.mjs +30 -0
  433. package/onboarding/local/files.mjs +35 -0
  434. package/onboarding/local/operation.mjs +166 -0
  435. package/onboarding/local/owner.mjs +34 -0
  436. package/onboarding/local/process-table.mjs +114 -0
  437. package/onboarding/local/recovery.mjs +79 -0
  438. package/onboarding/local/state.mjs +31 -0
  439. package/onboarding/metadata.mjs +7 -0
  440. package/onboarding/operator-install.mjs +45 -0
  441. package/onboarding/operator-installer.mjs +39 -0
  442. package/onboarding/operator-prerequisites.mjs +27 -0
  443. package/onboarding/package.json +6 -0
  444. package/onboarding/prefill.mjs +16 -0
  445. package/onboarding/private-files.mjs +97 -0
  446. package/onboarding/private.mjs +35 -0
  447. package/onboarding/process-cleanup.mjs +134 -0
  448. package/onboarding/process-diagnostics.mjs +91 -0
  449. package/onboarding/process-scope.mjs +118 -0
  450. package/onboarding/process-table.mjs +118 -0
  451. package/onboarding/process-tree.mjs +36 -0
  452. package/onboarding/production-modules.mjs +22 -0
  453. package/onboarding/production-options.mjs +40 -0
  454. package/onboarding/production-plan.mjs +8 -0
  455. package/onboarding/production-runtime.mjs +30 -0
  456. package/onboarding/project-vite.mjs +14 -0
  457. package/onboarding/providers.mjs +289 -0
  458. package/onboarding/queue.mjs +53 -0
  459. package/onboarding/queued-entry.mjs +34 -0
  460. package/onboarding/readiness.mjs +59 -0
  461. package/onboarding/redaction-jwt.mjs +32 -0
  462. package/onboarding/redaction.mjs +298 -0
  463. package/onboarding/schema/SETUP.schema.json +514 -0
  464. package/onboarding/schema/dependencies.mjs +35 -0
  465. package/onboarding/schema/json-schema.mjs +202 -0
  466. package/onboarding/schema/setup-validation.mjs +325 -0
  467. package/onboarding/secrets.mjs +21 -0
  468. package/onboarding/server.mjs +188 -0
  469. package/onboarding/setup-manifest.mjs +116 -0
  470. package/onboarding/state.mjs +46 -0
  471. package/onboarding/theme-files.mjs +37 -0
  472. package/onboarding/theme.mjs +118 -0
  473. package/onboarding/ui/activity.js +98 -0
  474. package/onboarding/ui/address-client.mjs +33 -0
  475. package/onboarding/ui/app.js +377 -0
  476. package/onboarding/ui/index.html +1 -0
  477. package/onboarding/ui/model-core.mjs +127 -0
  478. package/onboarding/ui/model.mjs +5 -0
  479. package/onboarding/ui/style.css +63 -0
  480. package/onboarding/ui/theme.css +37 -0
  481. package/onboarding/ui/workspace-art.js +30 -0
  482. package/onboarding/wrangler-auth.mjs +43 -0
  483. package/operations/README.md +246 -0
  484. package/operations/operations.mjs +168 -0
  485. package/operations/project-operations.mjs +157 -0
  486. package/package.json +11 -4
  487. package/scripts/publish-check/README.md +72 -0
  488. package/scripts/publish-check/checksum_maps.py +52 -0
  489. package/scripts/publish-check/cli.py +34 -0
  490. package/scripts/publish-check/command_arguments.py +51 -0
  491. package/scripts/publish-check/command_shell_quotes.py +41 -0
  492. package/scripts/publish-check/command_source_quotes.py +120 -0
  493. package/scripts/publish-check/content_identities.py +250 -0
  494. package/scripts/publish-check/copy_identities.py +41 -0
  495. package/scripts/publish-check/der.py +61 -0
  496. package/scripts/publish-check/destination.py +117 -0
  497. package/scripts/publish-check/env_values.py +74 -0
  498. package/scripts/publish-check/font_licence.py +23 -0
  499. package/scripts/publish-check/git_history.py +115 -0
  500. package/scripts/publish-check/github_refs.py +217 -0
  501. package/scripts/publish-check/gitleaks.py +72 -0
  502. package/scripts/publish-check/gitleaks.toml +40 -0
  503. package/scripts/publish-check/history_scan.py +176 -0
  504. package/scripts/publish-check/hit_location.py +18 -0
  505. package/scripts/publish-check/hygiene_config.py +42 -0
  506. package/scripts/publish-check/hygiene_text.py +11 -0
  507. package/scripts/publish-check/identity-recipe.mjs +54 -0
  508. package/scripts/publish-check/json_identity.py +79 -0
  509. package/scripts/publish-check/license-exceptions.json +11 -0
  510. package/scripts/publish-check/licenses.py +49 -0
  511. package/scripts/publish-check/policy.py +18 -0
  512. package/scripts/publish-check/project_identity.py +89 -0
  513. package/scripts/publish-check/provenance.py +91 -0
  514. package/scripts/publish-check/provenance_pins.py +33 -0
  515. package/scripts/publish-check/public_base.py +63 -0
  516. package/scripts/publish-check/public_hygiene.py +80 -0
  517. package/scripts/publish-check/publication-config.json +12 -0
  518. package/scripts/publish-check/publication_config.py +34 -0
  519. package/scripts/publish-check/report.py +52 -0
  520. package/scripts/publish-check/repository_commands.py +75 -0
  521. package/scripts/publish-check/repository_intent.py +52 -0
  522. package/scripts/publish-check/reviewed.py +41 -0
  523. package/scripts/publish-check/source_hashes.mjs +6 -0
  524. package/scripts/publish-check/tree_scan.py +88 -0
  525. package/scripts/publish-check/trust_bundle.py +87 -0
  526. 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
- # Temporary Holding Version
1
+ # rer
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
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
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ import { main } from '../cli/main.mjs';
3
+ process.exitCode = await main();
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.
@@ -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
+ }
@@ -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
+ }
@@ -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
+ }