@rehearsal-db/core 0.1.0-beta.6 → 0.1.0-beta.7

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/CHANGELOG.md CHANGED
@@ -5,6 +5,30 @@ a Changelog, and versions will follow Semantic Versioning after the package exis
5
5
 
6
6
  ## Unreleased
7
7
 
8
+ ## [0.1.0-beta.7] - 2026-10-02
9
+
10
+ ### Added
11
+
12
+ - A concise roadmap prioritizes real-project acceptance, easier baseline onboarding,
13
+ and another ordinary PostgreSQL project before further database expansion.
14
+ - A preview-first cleanup command for old baseline generations, the current project's
15
+ disposable runtime, and explicitly selected older unused Supabase images. Applying a
16
+ cleanup requires the exact digest from its preview.
17
+ - First-run setup now generates a fully populated, commented configuration that explains
18
+ safe defaults, project-specific checks, and optional local-only settings in place.
19
+
20
+ ### Changed
21
+
22
+ - Rehearsal now respects user-owned Colima CPU, memory, and disk settings. Projects may
23
+ configure Colima auto-start and baseline retention in `rehearsal.config.mjs`.
24
+
25
+ ### Fixed
26
+
27
+ - Beta publishing now updates both npm's `beta` and `latest` tags after registry
28
+ verification, keeping the package page and default install on the newest reviewed
29
+ beta. A protected manual repair path fixes existing tag drift without storing an npm
30
+ token or choosing an arbitrary version.
31
+
8
32
  ## [0.1.0-beta.6] - 2026-10-02
9
33
 
10
34
  ### Changed
@@ -170,7 +194,8 @@ a Changelog, and versions will follow Semantic Versioning after the package exis
170
194
  publication uses short-lived trusted OIDC, and every release tag must already exist on
171
195
  protected `main`.
172
196
 
173
- [Unreleased]: https://github.com/Ddupasquier/rehearsal-db/compare/v0.1.0-beta.6...HEAD
197
+ [Unreleased]: https://github.com/Ddupasquier/rehearsal-db/compare/v0.1.0-beta.7...HEAD
198
+ [0.1.0-beta.7]: https://github.com/Ddupasquier/rehearsal-db/compare/v0.1.0-beta.6...v0.1.0-beta.7
174
199
  [0.1.0-beta.6]: https://github.com/Ddupasquier/rehearsal-db/compare/v0.1.0-beta.5...v0.1.0-beta.6
175
200
  [0.1.0-beta.5]: https://github.com/Ddupasquier/rehearsal-db/compare/v0.1.0-beta.4...v0.1.0-beta.5
176
201
  [0.1.0-beta.4]: https://github.com/Ddupasquier/rehearsal-db/compare/v0.1.0-beta.3...v0.1.0-beta.4
package/README.md CHANGED
@@ -31,9 +31,11 @@ npm install --save-dev @rehearsal-db/core@beta
31
31
  npx rehearsal
32
32
  ```
33
33
 
34
- The guide shows your progress and offers the next safe action. On first use, choose
35
- **Set the stage**, select Supabase or PostgreSQL, review the preview, and confirm the files
36
- it will create. Existing files are never overwritten.
34
+ The first run detects your project and offers to create a commented
35
+ `rehearsal.config.mjs` with the project name, migration paths, commands, ports, and safe
36
+ defaults already filled in. Choose **Set the stage**, select Supabase or PostgreSQL,
37
+ review the preview, and confirm the files it will create. Existing files are never
38
+ overwritten.
37
39
 
38
40
  For PostgreSQL, download the reviewed local image once before running the guide:
39
41
 
@@ -61,6 +63,10 @@ Start with synthetic data. Rehearsal does not copy or sanitize production data f
61
63
  5. Run the rehearsal and your application proof.
62
64
  6. Test the local application, then verify, reset, stop, or discard the runtime.
63
65
 
66
+ When local disk space gets tight, choose **Clean up disk space** in the guide. Rehearsal
67
+ previews old baseline generations first and keeps runtime or shared-image removal
68
+ explicit.
69
+
64
70
  Press `Ctrl+Z` at any guided prompt to exit the whole session. Choose **Get help**, or run
65
71
  `npx rehearsal support`, to create a privacy-safe diagnostic report.
66
72
 
@@ -98,6 +104,7 @@ Start here:
98
104
  - [Getting started](docs/getting-started.md) — set up your own project
99
105
  - [Safe hands-on tutorial](docs/tutorial.md) — try the full flow in a disposable project
100
106
  - [Troubleshooting](docs/troubleshooting.md) — fix common setup problems
107
+ - [Next steps](docs/roadmap.md) — see the current product sequence
101
108
 
102
109
  Reference:
103
110
 
package/docs/commands.md CHANGED
@@ -59,11 +59,36 @@ and process exit code, not parse human-facing text.
59
59
  | `npx rehearsal reset` | Discard runtime edits and restore the baseline. |
60
60
  | `npx rehearsal stop` | Stop the runtime but keep its local state. |
61
61
  | `npx rehearsal discard` | Remove this project's disposable runtime and volume. |
62
+ | `npx rehearsal cleanup` | Preview conservative cleanup without removing anything. |
62
63
 
63
64
  In a terminal, the guide displays candidate filenames and asks for confirmation. In a
64
65
  script, copy the digest from `candidates` into `--confirm-candidates`. Adding, removing,
65
66
  reordering, or editing a migration changes that digest.
66
67
 
68
+ ## Clean up disk space
69
+
70
+ Start with a preview:
71
+
72
+ ```bash
73
+ npx rehearsal cleanup
74
+ ```
75
+
76
+ By default, cleanup selects only old baseline generations beyond the retention setting
77
+ in `rehearsal.config.mjs`. Add options to broaden the preview:
78
+
79
+ | Command option | Additional resources considered |
80
+ | ------------------- | ---------------------------------------------------------------------- |
81
+ | `--include-runtime` | This project's disposable runtime and its database volumes. |
82
+ | `--include-images` | Older unused Supabase images; the newest image for each service stays. |
83
+ | `--write` | Apply the exact freshly verified preview. |
84
+ | `--confirm-cleanup` | Full cleanup digest printed by the preview; required with `--write`. |
85
+
86
+ Image cleanup never removes an image used by any running or stopped container and never
87
+ runs a global Docker prune. Images may be shared by projects and can be downloaded again,
88
+ so they remain excluded unless you explicitly add `--include-images`. Database volumes
89
+ belonging to other projects are never included. This follows
90
+ [Docker's conservative pruning guidance](https://docs.docker.com/engine/manage-resources/pruning/).
91
+
67
92
  ## Common options
68
93
 
69
94
  | Option | Meaning |
@@ -74,5 +99,9 @@ reordering, or editing a migration changes that digest.
74
99
  | `--plain` | Disable decorative interactive prompts. |
75
100
  | `--config=<path>` | Use a specific config file inside the project. |
76
101
  | `--target=supabase\|postgresql` | Choose the setup target. |
102
+ | `--include-runtime` | Include this project's runtime in a cleanup preview. |
103
+ | `--include-images` | Include older unused Supabase images in a cleanup preview. |
104
+ | `--confirm-cleanup=<digest>` | Confirm the exact cleanup set printed by the preview. |
105
+ | `--write` | Apply a setup, policy, or cleanup preview. |
77
106
 
78
107
  Run `npx rehearsal --help` to print the command list available in your installed version.
@@ -6,29 +6,55 @@ Most users should let the guide create this file:
6
6
  npx rehearsal
7
7
  ```
8
8
 
9
- Use this page when reviewing or changing the generated `rehearsal.config.mjs`. The schema
10
- is strict: misspelled fields, unknown fields, and unsupported versions are errors. The
11
- `.mjs` extension works in both CommonJS and ESM projects.
9
+ The first run uses your chosen database type and detects the project name, migration
10
+ folder, package-manager commands, and free local ports. After you approve the setup
11
+ preview, it creates a commented `rehearsal.config.mjs` with those values filled in.
12
+ Installation itself does not use a `postinstall` script or silently modify the project.
13
+
14
+ Review lines marked `CHECK`, especially the application proof command. Optional settings
15
+ are present as commented examples, and secrets never belong in this file. Rehearsal will
16
+ not overwrite an existing config.
17
+
18
+ Use this page when changing the generated file. The schema is strict: misspelled fields,
19
+ unknown fields, and unsupported versions are errors. The `.mjs` extension works in both
20
+ CommonJS and ESM projects.
12
21
 
13
22
  ```ts
23
+ // @ts-check
14
24
  import { defineRehearsalConfig } from "@rehearsal-db/core";
15
25
 
16
26
  export default defineRehearsalConfig({
27
+ // Configuration format. Rehearsal will explain if an upgrade is ever needed.
17
28
  schemaVersion: 1,
29
+ // Stable local name used in Rehearsal labels and reports.
18
30
  project: { name: "example-app" },
31
+
32
+ // Project files Rehearsal reads. Every path stays inside this repository.
19
33
  supabase: {
20
34
  workdir: ".",
21
35
  migrationDirectory: "supabase/migrations",
22
36
  rehearsalConfig: "infrastructure/rehearsal/supabase/config.toml",
23
37
  runtimeWorkdir: ".rehearsal/runtime",
38
+
39
+ // Optional; configure both keys together.
40
+ // serviceEnvironmentFile: ".env.rehearsal-service.local",
41
+ // serviceEnvironmentVariables: ["LOCAL_IDP_CLIENT_ID", "LOCAL_IDP_SECRET"],
24
42
  },
25
43
  baseline: {
26
44
  artifactDirectory: ".rehearsal",
27
45
  sanitizationPolicy: "infrastructure/rehearsal/sanitization-policy.json",
28
46
  },
47
+ containerRuntime: {
48
+ autoStartColima: true,
49
+ },
50
+ cleanup: {
51
+ retainBaselineGenerations: 2,
52
+ },
29
53
  application: {
54
+ // CHECK: replace these when the detected package scripts are not correct.
30
55
  startCommand: "npm run dev:rehearsal",
31
56
  proofCommand: "npm run test:rehearsal",
57
+ environmentFile: ".rehearsal/runtime.env",
32
58
  },
33
59
  runtime: {
34
60
  target: "supabase",
@@ -38,7 +64,16 @@ export default defineRehearsalConfig({
38
64
  databasePort: 58322,
39
65
  studioPort: 58323,
40
66
  },
41
- safety: { hostedAccess: "disabled", outboundNetwork: "deny" },
67
+ safety: {
68
+ allowedHosts: ["127.0.0.1", "::1", "localhost"],
69
+ blockedEnvironmentVariables: [
70
+ "SUPABASE_ACCESS_TOKEN",
71
+ "SUPABASE_DB_PASSWORD",
72
+ "SUPABASE_PROJECT_ID",
73
+ ],
74
+ hostedAccess: "disabled",
75
+ outboundNetwork: "deny",
76
+ },
42
77
  });
43
78
  ```
44
79
 
@@ -51,6 +86,26 @@ All paths resolve inside the consuming project. The artifact directory must be n
51
86
  Rehearsal never overwrites this config. To start over, move the existing file somewhere
52
87
  safe, run setup again, and compare the two files before deleting either one.
53
88
 
89
+ ## Container runtime and cleanup
90
+
91
+ ```ts
92
+ containerRuntime: {
93
+ autoStartColima: true,
94
+ },
95
+ cleanup: {
96
+ retainBaselineGenerations: 2,
97
+ },
98
+ ```
99
+
100
+ Rehearsal uses whichever Docker-compatible engine already answers `docker info`. If none
101
+ is running and `autoStartColima` is `true`, Rehearsal may run `colima start`. It respects
102
+ the user's Colima CPU, memory, and disk settings and never changes them. Set the field to
103
+ `false` when you prefer to start Docker or Colima yourself.
104
+
105
+ `retainBaselineGenerations` controls how many immutable baseline generations survive
106
+ `rehearsal cleanup`; it must be at least 1. Runtime deletion and shared-image inspection
107
+ are command choices, not automatic retention settings. See [CLI commands](commands.md).
108
+
54
109
  ## Supabase service environment
55
110
 
56
111
  Some local identity providers need a client ID and secret. Configure both fields or
@@ -67,9 +122,12 @@ terminate at local Auth. They do not grant hosted database access.
67
122
 
68
123
  ## Safety fields
69
124
 
70
- Version 1 accepts loopback hosts only. `hostedAccess` can only be `disabled`, and
71
- `outboundNetwork` can only be `deny`. Ambient hosted Supabase variables are quarantined
72
- from child processes. There is no force flag to weaken these rules.
125
+ Version 1 accepts loopback runtime URLs only. `hostedAccess` can only be `disabled`, and
126
+ `outboundNetwork` can only be `deny`. Common hosted Supabase and PostgreSQL credentials
127
+ are quarantined from child processes. These fields are fail-closed configuration rules,
128
+ not a host firewall: trusted project proof commands and runtime adapters remain ordinary
129
+ local code and must be reviewed. There is no force flag to weaken the configuration
130
+ rules.
73
131
 
74
132
  ## Ports and project identity
75
133
 
package/docs/releasing.md CHANGED
@@ -52,7 +52,16 @@ publication must change and prove the workflow before narrowing that permission.
52
52
  protected integration branches and rerun their complete verification.
53
53
 
54
54
  The workflow publishes prereleases under the `beta` dist-tag and refuses a stable
55
- version. A stable tag requires a later contract, compatibility, and release decision.
55
+ version. While Rehearsal has no stable release, the workflow also moves `latest` to the
56
+ same reviewed beta. This keeps the npm package page and the ordinary
57
+ `npm install @rehearsal-db/core` command current. When Rehearsal gains a stable release,
58
+ `latest` must switch to the stable line while `beta` continues to identify prereleases.
59
+
60
+ The trusted publisher allows `npm dist-tag` only so this workflow can maintain those two
61
+ tags without a stored npm token. A manual workflow run from `main` can repair the tags
62
+ for the exact prerelease version currently recorded in `package.json`; it cannot publish
63
+ a package or select a different version. The protected `npm` environment still supplies
64
+ the human approval gate.
56
65
 
57
66
  Creating the repository, passing CI, extracting the engine, merging a release branch,
58
67
  or creating a tag does not authorize npm publication. Publication requires explicit
@@ -0,0 +1,39 @@
1
+ # Next steps
2
+
3
+ The current Rehearsal beta supports guided Supabase and ordinary PostgreSQL rehearsals.
4
+ The next work should be driven by real project use before adding more database targets.
5
+
6
+ ## 1. Complete the first real-project acceptance run
7
+
8
+ Update an existing Supabase application to `@rehearsal-db/core@beta` on its own clean
9
+ branch, then prove:
10
+
11
+ - `doctor` reports `READY`;
12
+ - the intended candidate migrations are the only candidates;
13
+ - a complete rehearsal and the application proof pass;
14
+ - verify, reset, stop, and restart behave as expected.
15
+
16
+ Record any confusing instruction or unnecessary manual step. Those findings should guide
17
+ the next usability changes.
18
+
19
+ ## 2. Simplify baseline onboarding
20
+
21
+ Make safe records, migration evidence, and sanitization-policy review easier for a new
22
+ developer. Reduce manual file preparation without weakening review, checksum, or
23
+ local-only safety rules.
24
+
25
+ ## 3. Validate another ordinary PostgreSQL project
26
+
27
+ Use a non-Supabase application with real migration history and a synthetic baseline.
28
+ Fix general PostgreSQL problems before adding provider-specific behavior.
29
+
30
+ ## 4. Consider PostgreSQL service compatibility
31
+
32
+ Only after the ordinary PostgreSQL workflow is reliable, evaluate compatibility needs
33
+ for individual PostgreSQL services. Keep rehearsals disposable and local; hosted database
34
+ execution remains outside the current safety model.
35
+
36
+ ## Later
37
+
38
+ MySQL, MongoDB, and unrelated database families require different migration and restore
39
+ behavior. They remain out of scope until the PostgreSQL experience is proven and stable.
@@ -39,6 +39,29 @@ writes setup files.
39
39
  Start Docker Desktop or Colima, confirm `docker info`, then rerun `rehearsal doctor`.
40
40
  Restarting the computer is rarely necessary.
41
41
 
42
+ ## Docker or Colima is out of disk space
43
+
44
+ Preview what Rehearsal can safely remove:
45
+
46
+ ```bash
47
+ npx rehearsal cleanup --include-images
48
+ ```
49
+
50
+ Review the list, then add `--write` and the printed `--confirm-cleanup` digest. Rehearsal
51
+ keeps the newest Supabase image for each service, refuses images used by any running or
52
+ stopped container, and never runs a global Docker or volume prune. Add
53
+ `--include-runtime` only when this project's disposable database may also be removed.
54
+
55
+ For example, copy the full digest from your preview:
56
+
57
+ ```bash
58
+ npx rehearsal cleanup --include-images --write --confirm-cleanup=PASTE_FULL_DIGEST_HERE
59
+ ```
60
+
61
+ For Colima, disk capacity belongs to the user rather than the project. Increase it with
62
+ `colima stop` followed by a larger `colima start --disk <GiB>` value. Rehearsal respects
63
+ that configuration and does not choose a disk size.
64
+
42
65
  ## The guide does not show styled menus
43
66
 
44
67
  Rehearsal uses numbered menus when terminal styling is unavailable, `NO_COLOR` is set, or
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rehearsal-db/core",
3
- "version": "0.1.0-beta.6",
3
+ "version": "0.1.0-beta.7",
4
4
  "private": false,
5
5
  "description": "Safely rehearse PostgreSQL and Supabase migrations against sanitized, production-shaped data.",
6
6
  "repository": {
@@ -62,14 +62,13 @@ export const localCommandSucceeds = (
62
62
  stdio: "ignore",
63
63
  }).status === 0;
64
64
 
65
- export const ensureLocalContainerRuntime = ({ cwd = process.cwd() } = {}) => {
65
+ export const ensureLocalContainerRuntime = ({
66
+ cwd = process.cwd(),
67
+ autoStartColima = true,
68
+ } = {}) => {
66
69
  if (localCommandSucceeds("docker", ["info"], { cwd })) return;
67
- if (localCommandSucceeds("colima", ["version"], { cwd })) {
68
- runLocalCommand(
69
- "colima",
70
- ["start", "--cpu", "4", "--memory", "4", "--disk", "40"],
71
- { cwd },
72
- );
70
+ if (autoStartColima && localCommandSucceeds("colima", ["version"], { cwd })) {
71
+ runLocalCommand("colima", ["start"], { cwd });
73
72
  }
74
73
  if (!localCommandSucceeds("docker", ["info"], { cwd })) {
75
74
  throw new Error(
@@ -118,8 +117,9 @@ export const startLocalSupabase = ({
118
117
  exclude = [],
119
118
  environment = {},
120
119
  applyMigrations = true,
120
+ autoStartColima = true,
121
121
  } = {}) => {
122
- ensureLocalContainerRuntime({ cwd });
122
+ ensureLocalContainerRuntime({ cwd, autoStartColima });
123
123
  const startArguments = withWorkdir(
124
124
  ["start", ...(exclude.length ? ["--exclude", exclude.join(",")] : [])],
125
125
  workdir,
@@ -478,7 +478,7 @@ export const listIncompleteBaselineBuilds = async ({ artifactRoot }) => {
478
478
  }
479
479
  };
480
480
 
481
- export const pruneBaselineGenerations = async ({
481
+ export const planBaselineGenerationPrune = async ({
482
482
  artifactRoot,
483
483
  retain = 2,
484
484
  }) => {
@@ -516,7 +516,36 @@ export const pruneBaselineGenerations = async ({
516
516
  const removed = entries
517
517
  .map((entry) => entry.name)
518
518
  .filter((name) => !retained.has(name));
519
- for (const name of removed) {
519
+ return { retained: [...retained], removed };
520
+ };
521
+
522
+ export const pruneBaselineGenerations = async ({
523
+ artifactRoot,
524
+ retain = 2,
525
+ expectedRemoved,
526
+ }) => {
527
+ const root = assertArtifactRoot(artifactRoot);
528
+ const plan = await planBaselineGenerationPrune({
529
+ artifactRoot: root,
530
+ retain,
531
+ });
532
+ const generationsRoot = join(root, generationsDirectoryName);
533
+ if (
534
+ expectedRemoved &&
535
+ (expectedRemoved.length !== plan.removed.length ||
536
+ expectedRemoved.some((name, index) => name !== plan.removed[index]))
537
+ ) {
538
+ throw new Error(
539
+ "Rehearsal baseline generations changed after the cleanup preview.",
540
+ );
541
+ }
542
+ for (const name of plan.removed) {
543
+ const active = await resolveActiveBaselinePaths({ artifactRoot: root });
544
+ if (basename(active.generationDirectory) === name) {
545
+ throw new Error(
546
+ "Refusing to prune the active Rehearsal baseline generation.",
547
+ );
548
+ }
520
549
  const target = assertInsideRoot(
521
550
  generationsRoot,
522
551
  join(generationsRoot, name),
@@ -525,7 +554,7 @@ export const pruneBaselineGenerations = async ({
525
554
  await makeArtifactTreeWritable(target);
526
555
  await rm(target, { recursive: true, force: true });
527
556
  }
528
- return { retained: [...retained], removed };
557
+ return plan;
529
558
  };
530
559
 
531
560
  export const removeBaselineArtifactRoot = async ({ artifactRoot }) => {