Skip to content
This repository was archived by the owner on May 9, 2026. It is now read-only.
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
cc2b65c
docs(adr): v1 architecture session — ADRs 0021–0028
slavasolutions May 6, 2026
04e3f87
merge: bring in #21 release-script fix from main
slavasolutions May 6, 2026
96c0f39
docs(state): clarify v0.3 → v0.4 publish strategy (fat train)
slavasolutions May 6, 2026
1eee607
merge: v0.4 publish wave + dependabot + mcp repo-url fix from main
slavasolutions May 6, 2026
ab3f195
docs(state): v0.4.0 publish wave shipped
slavasolutions May 6, 2026
4a3e5d0
merge: dependabot bumps + dnd-kit/sortable 10 from main into release/…
slavasolutions May 7, 2026
d16df8f
merge: CI release/** trigger fix from main (#79)
slavasolutions May 7, 2026
f3ae8d9
fix(admin): Windows SQLite teardown EBUSY in tests (closes #56) (#78)
slavasolutions May 7, 2026
430fdab
merge: v0.4.1 fixes from main into release/v1.0 (Windows astro spawn …
slavasolutions May 7, 2026
79e33c2
merge: v0.4.2 fixes from main into release/v1.0 (scaffold + admin tar…
slavasolutions May 7, 2026
81e7866
feat(spec): v1 Phase 3 spec foundation (ADRs 0021/0022/0024/0025/0027…
slavasolutions May 7, 2026
c13e6ac
feat(storage): write-time schemaVersion stamp (ADR-0022) (#72)
slavasolutions May 7, 2026
0292882
feat(spec,admin): migration runner (ADR-0022) (#76)
slavasolutions May 7, 2026
18adc6e
feat(renderer): library scaffold (ADR-0024) (#74)
slavasolutions May 7, 2026
ba044f7
feat(admin): doctor checks for v1 site-mode + schemaVersion (ADRs 002…
slavasolutions May 7, 2026
63e8dea
docs(protocol): CONTENT-PROTOCOL.md v1 rewrite (site mode) (#73)
slavasolutions May 7, 2026
979fa9b
chore: lock v1 coordination protocol — PLAN.md + BATON.md (#104)
slavasolutions May 7, 2026
5f8d773
docs(state): v0.5 conceptual milestone shipped — Phase 3 + aux stream…
slavasolutions May 7, 2026
3ca9152
chore: tick T-3.7 + T-3.8 + flip BATON to S1
May 7, 2026
3eeb3f6
chore: flip BATON to S2 + insert T-3.8.5 spec/migrate barrel unblocker
slavasolutions May 7, 2026
04788c7
fix(spec,core,storage,design,admin): publish hygiene + admin enum nar…
slavasolutions May 7, 2026
84ad615
chore: tick T-3.8.5 + T-3.8.6 + flip BATON to S1
May 7, 2026
9b2fa3a
feat(admin): clear-admin migrate-bucket-to-r2 (closes #14) (#101)
slavasolutions May 7, 2026
8859801
chore: tick T-3.9 + T-3.10 + flip BATON to S2
slavasolutions May 7, 2026
0c361eb
feat(blocks-marketing): @clearcms/blocks-marketing v1 — 10 blocks (#103)
slavasolutions May 7, 2026
a3df7d7
chore: tick T-3.11 + T-3.12 + flip BATON to S1
May 7, 2026
9a41b80
feat(admin): editor surface registry (Phase 4, closes #52) (#119)
slavasolutions May 7, 2026
0b86688
chore: tick T-4.1 → T-4.8 + flip BATON to S2 (Phase 4 done)
slavasolutions May 7, 2026
6105357
feat(admin): plumb project mode at boot (T-5A.1, ADR-0021) (#120)
slavasolutions May 7, 2026
f32a2a9
chore: tick T-5A.1 + T-5A.2 (parallel-merge bookkeeping)
slavasolutions May 7, 2026
8866022
feat(create): template-site-marketing scaffold + --theme=marketing fl…
slavasolutions May 7, 2026
cc00328
chore: tick T-5F.1 + T-5F.2 + flip BATON to S1
May 7, 2026
76c2e0f
feat(admin): theme tokens UI (T-5B.1, site-mode only) (#131)
slavasolutions May 7, 2026
34c8054
chore: tick T-5B.1 + T-5B.2 + flip BATON to S2 (Stream 5B done)
slavasolutions May 7, 2026
880bcdd
feat(migrate): full migration runner + greedy-at-read + per-block + p…
slavasolutions May 7, 2026
e828909
chore: tick T-6.1 + T-6.2 + flip BATON to S1
May 7, 2026
69e6049
fix(admin): doctor surfaces typo'd mode values (closes #128) (#139)
slavasolutions May 7, 2026
12b3ac8
feat(admin): block-schema designer extension (T-5C.1, ADR-0024) (#140)
slavasolutions May 7, 2026
abd8353
chore: tick T-5C.1 + T-5C.2 + flip BATON to S2 (Stream 5C done)
slavasolutions May 7, 2026
3f399d2
feat(admin): sections surface MVP (T-5D.1-4, ADR-0021/0024) (#142)
slavasolutions May 7, 2026
e1bca0c
chore: tick T-5D.1-4 + T-5D.9-11 (sections MVP done; T-5D.5/6/7/8 def…
slavasolutions May 7, 2026
f06c18c
docs(adr,protocol): v1 status sweep + block-library author guide (#145)
slavasolutions May 7, 2026
9c96466
chore: tick T-7.1 + T-7.2 + flip BATON to S1
May 7, 2026
4cdd8c2
docs(v1): site-mode README section + migration guide + STATE refresh …
slavasolutions May 7, 2026
4b8eac9
chore: tick T-7.3 + T-7.4 + T-7.5 (Phase 7 done; baton stays S1 for s…
slavasolutions May 7, 2026
b46a7bc
test(sdk): coverage audit (priority 7) (#137)
slavasolutions May 7, 2026
7ec5bdb
test(renderer): coverage audit (priority 7) (#138)
slavasolutions May 7, 2026
005793e
chore: retire PLAN.md + BATON.md coordination protocol — planning mov…
slavasolutions May 8, 2026
2c89f2f
feat(spec): permissions vocabulary — actions + matrix dialect (SLICE-…
slavasolutions May 8, 2026
abd5fec
fix(admin): handlePublish reads return value, not stale React state (…
slavasolutions May 8, 2026
49d22c2
fix(admin): wrap setLocales three-row write in a transaction (SLICE-0…
slavasolutions May 8, 2026
0bca555
fix(admin): log FTS index failures instead of swallowing them (SLICE-…
slavasolutions May 8, 2026
11d9d30
fix(admin): invalidate collection-schema cache after fields.* mutatio…
slavasolutions May 8, 2026
a4012be
fix(admin): cast astro:actions mocks through unknown for vi.fn typecheck
slavasolutions May 8, 2026
9f1efaa
feat(admin): add markdown widget for the form surface (SLICE-0011)
slavasolutions May 8, 2026
7b06585
fix(spec): drop duplicate markdown entry in DEFAULT_WIDTH_BY_WIDGET (…
slavasolutions May 8, 2026
82723bc
docs(plan): restore PLAN.md as a stub pointing at clearcms/plan repo
slavasolutions May 8, 2026
90bce43
docs(adr): consolidate to single public index + bump STATE for Phase 8
slavasolutions May 8, 2026
0e13928
fix(admin): drop duplicate markdown entries in AddFieldModal (cherry-…
slavasolutions May 8, 2026
4c21a53
chore: untrack dist/ across the workspace; rely on .gitignore + pnpm …
slavasolutions May 8, 2026
ee3a1a5
chore(deps): clear 3 medium dependabot CVEs via pnpm overrides
slavasolutions May 8, 2026
6a743ee
docs: align root surface with OSS standard; drop STATE/ROADMAP/PLAN/C…
slavasolutions May 8, 2026
87b8f0f
docs(claude): add canonical-structure directive locking the 2026-05-0…
slavasolutions May 8, 2026
5866bd0
docs: fix 30 broken references from the 2026-05-08 OSS-cleanup
slavasolutions May 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion .changeset/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,4 @@ npm view @clearcms/spec --json | jq '.dist.attestations'

The `predicate.buildDefinition.externalParameters.workflow` field points at the exact `release.yml` invocation that produced the tarball.

Per [ADR-0014](../docs/adr/0014-two-physical-repos-end-mirroring.md).
Per [ADR-0014](../docs/adr/README.md#adr-0014--two-physical-repos--end-mirroring-public-is-source-of-truth).
36 changes: 36 additions & 0 deletions .changeset/admin-backfill-schema-versions-stub.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
'@clearcms/admin': minor
---

Add `clear-admin backfill-schema-versions` CLI surface (STUB).

Per ADR-0022 §backfill, this command walks the bucket and stamps every
record missing a `schemaVersion` field. The full bucket walk + stamp
implementation lands in Phase 6 closeout; today's commit ships the
CLI surface so adopters and tests can target the command name now.

Argv shape (locked):

clear-admin backfill-schema-versions [--dry-run] [--collection <slug>]

--dry-run scan + count only; no writes.
--collection <slug> scope to a single collection (default: every
record type — items, pages, page-data, block
instances, globals, theme tokens).
-h, --help show help.

Exits 0 on the not-yet-implemented happy path (with a clear message
naming ADR-0022 §backfill); exits 2 on argv error. Pattern matches
`migrate-records` (Stream-Migrate, PR #76).

The full implementation will use `@clearcms/storage`'s
`writeStampedJson` primitive (PR #72 commit 1) so the stamp behaviour
matches every other named writer.

11 new unit tests cover the argv parser (defaults, `--dry-run`,
`--collection` both forms, missing values, unknown flags, help
sentinel) and the stub's exit code surface.

Eng B Phase 5/6 storage track, commit 6 of N on PR #72 (final commit
on this PR — closes the named-writer + path-helper + backfill-CLI
sweep). Independent of PR #57; lands when storage track ships.
35 changes: 35 additions & 0 deletions .changeset/admin-doctor-checks-v1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
'@clearcms/admin': minor
---

Add 4 new `clear-admin doctor` checks for the v1 site-mode + ADR-0022
schema-version contract:

- **`checkModeConsistency`** (ADR-0021) — `clear.config.json`'s `mode`
vs the bucket's site-mode artifacts. Headless + `theme/blocks/` files
present → warning ("site-mode artifacts in a headless project; flip
the mode or run `clean-mode-artifacts`"). Site + no `theme/blocks/`
→ info.
- **`checkDanglingBlockTypes`** (ADR-0021) — page `data.json` block
manifests reference unknown block types (no
`theme/blocks/<type>.schema.json`). Each hit → warning.
- **`checkStaleSchemaVersions`** (ADR-0022) — record `schemaVersion`
vs schema's current `version`, per-collection counts. Suggests
`clear-admin migrate-records` for each stale collection.
- **`checkDanglingTokenRefs`** (ADR-0025) — block-instance fields with
`widget: "select" + optionsFromTokens: <category>` reference token
names not declared in `theme/tokens.json[<category>]`. Each hit →
warning.

Each check is a pure async function returning `DoctorIssue[]`; all four
return zero issues on a healthy v0/v1 bucket. Fixtures are fs-only
(`mkdtemp` + JSON file writes) — none of the checks require the SQLite
DB harness, so the Windows EBUSY pre-existing failure mode (issue #56)
doesn't apply.

Includes a tiny local `assumeSchemaVersion` shim in
`doctor-stale-schema-versions.ts` until PR #57 (Phase 3 spec) merges
and the helper becomes consumable from `@clearcms/spec` directly.

Eng B Phase 6 doctor track. 18 new tests; existing doctor tests
unchanged.
24 changes: 24 additions & 0 deletions .changeset/admin-migrate-records-stub.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
'@clearcms/admin': minor
---

`clear-admin migrate-records` — bulk record migration runner (ADR-0022, Phase 5 stub).

Adds the CLI surface that adopters will run to apply pending migrations
across a bucket. Argv shape:

```
clear-admin migrate-records --collection=<slug> [--dry-run]
clear-admin migrate-records --all [--dry-run]
clear-admin migrate-records --help
```

Stub-only: argv parsing + help + scope validation are wired today so
adopter scripts can gate on `--help`. The actual bucket walk lands in
Phase 6 closeout once the storage-side `schemaVersion` write-stamp from
the v1 storage track has propagated. Imports the runtime from
`@clearcms/spec/migrate` (this release's spec bump) so the package edge
is locked from day one.

The bin help block lists the new subcommand so `clear-admin help` shows
the path to migration tooling without further ceremony.
17 changes: 17 additions & 0 deletions .changeset/adr-sweep-docs-polish.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
---

docs(adr,protocol): v1 status sweep + block-library author guide

Sweeps ADR statuses for v1.0:
- 0007 reframed by 0021 (page block storage shifted to v1 dialect)
- 0008 superseded by 0024 (Workers renderer dropped for self-hosted Astro)
- 0021–0028 accepted with implementation status notes

Adds new author guide at docs/guides/block-library-authoring.md covering
the block-library publishing rhythm (ADR-0028) and widget dialect (ADR-0027).

CONTENT-PROTOCOL v1 polish: bucket-layout examples now match the
template-site-marketing scaffold output; cross-links to the author guide.

Closes T-7.1.
46 changes: 46 additions & 0 deletions .changeset/blocks-marketing-init.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
---
'@clearcms/blocks-marketing': minor
---

Initial scaffold of `@clearcms/blocks-marketing` — the v1 site-mode
marketing block library per ADRs 0024 / 0025 / 0028.

This commit ships:

- Package skeleton (`package.json`, `tsconfig.json`,
`tsconfig.build.json`) mirroring `@clearcms/astro`'s shape — main /
types at `dist/`, files=["blocks","examples","migrations","src","dist"],
`astro` declared as peer (`^6.0.0`) and devDep, `@clearcms/spec`
workspace dep for block-schema validation.
- `src/index.ts` — the block-name registry (`MARKETING_BLOCK_NAMES`,
starting with `Hero`) plus `marketingBlockSchemas` (per-block JSON
re-exports) and `getMarketingBlockSchema(name)`. Astro components
are NOT re-exported via `src/index.ts`; adopters import them
directly from `@clearcms/blocks-marketing/blocks/<Name>.astro`.
- First block — **Hero**:
- `blocks/Hero.astro` — typed Astro component. Tokens-driven via
ADR-0025 CSS custom properties (`--clear-color-<name>`,
`--clear-space-<name>`); fallback values keep markup styled
when a token isn't declared. Class names follow
`clearcms-block-hero__<element>` BEM-ish convention.
- `blocks/Hero.schema.json` — block-schema at version `1.0.0`
(`{ name, version, fields }` per ADR-0028). 6 fields:
`headline`, `subheadline`, `background` (optionsFromTokens
color), `padding` (optionsFromTokens space), `ctaLabel`,
`ctaHref`.
- `examples/Hero.json` — example block-instance fixture
(BlockInstanceSchema-shaped) for tests + scaffolder seed.
- `src/blocks-marketing.test.ts` — 5 tests. Validates every name in
the registry has a schema, the resolver returns the right schema /
undefined for unknowns, every block-schema parses against
`BlockSchemaSchema`, every example parses against
`BlockInstanceSchema`.

The remaining 9 blocks (Features / CTA / FAQ / Footer / Testimonials
/ Pricing / Logos / Contact / RichText) ship in subsequent commits on
this branch — same shape as Hero (component + schema + example +
registry entry + test row added by the `describe.each` already in
place).

Eng B Phase 5, commit 1 of N. New package; not yet published —
queues for the next publish train.
12 changes: 12 additions & 0 deletions .changeset/doctor-mode-consistency-resolver.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
'@clearcms/admin': patch
---

`clear-admin doctor`'s mode-consistency check now consumes
`loadProjectConfig().mode` (T-5A.1) instead of re-parsing the config
file. New WARN: when the raw `mode` value in env (`CLEAR_MODE`) or
`clear.config.json` is not in the closed enum, the resolver silently
falls back to `headless` — doctor surfaces the typo'd value loudly so
the operator sees it instead of debugging a silently-headless install.

Closes #128.
27 changes: 27 additions & 0 deletions .changeset/migrate-bucket-to-r2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
'@clearcms/admin': minor
---

feat(admin): `clear-admin migrate-bucket-to-r2 <slug>` — one-shot fs → R2
data migration for an existing project. Reads the platform R2 token from
`R2_*` env vars (source `~/.r2-platform.env`), creates the bucket
(idempotent, default name `clear-<slug>`, override via
`--bucket-name=<name>`), uploads every file under the local `bucket/` to
R2 at the same key, atomically rewrites `~/clear/registry.json` with
`bucketProvider: 'r2'` + the new `r2` block, and renames the local
bucket dir to `bucket.archived-<ISO>/` so the operator can verify
parity before deleting.

v1 happy-path only. Implements ADR-0017 steps 1, 2, 3, 5, 6, 7, 8.
Deferred (in-progress follow-ups):

- Step 4 / per-project scoped R2 token mint per ADR-0016. Today the
command inherits the platform token at runtime; a future PR adds the
`R2 → CreateToken` call and writes the per-project token into the
registry entry.
- Resume-on-failure via `.migration-progress.json` (ADR-0017 "Risks"
section). v1 fails fast on partial uploads; rerun end-to-end after
fixing the underlying issue.
- Streaming PUTs for large media. v1 reads each file fully into memory
before uploading — fine for text-shaped sites, fails on multi-GB
media libraries.
59 changes: 59 additions & 0 deletions .changeset/migrate-runner-admin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
---
'@clearcms/admin': minor
---

`clear-admin migrate-records` + `clear-admin backfill-schema-versions`
— full implementations replacing the Phase 5 stubs (T-6.1 / ADR-0022 /
ADR-0028 / ADR-0015).

`clear-admin migrate-records`:

```
clear-admin migrate-records --collection=<slug> [--dry-run] [--type=<kind>] [--bucket=<path>] [--verbose]
clear-admin migrate-records --all [--dry-run] [--type=<kind>] [--bucket=<path>] [--verbose]
```

The Phase 5 stub's argv contract (`--collection=<slug>` / `--all` /
`--dry-run` / `--help`) is preserved; `--bucket=<path>`,
`--type=<items|pages|all>`, and `--verbose` are additive.

Behaviour, end-to-end:

1. Resolves the bucket root from `--bucket` > env `CLEAR_STORAGE_ROOT`
> `clear.config.json#bucket` > default `./data/storage`.
2. Discovers migrations via `discoverMigrations` (per-collection
adopter migrations under `<bucket>/schemas/<coll>/migrations/`),
`discoverPerBucketMigrations` (per-bucket cross-cutting adopter
migrations under `<bucket>/migrations/<scope>/`, ADR-0015), and
`loadBlockMigrations` (every installed `@clearcms/blocks-*`
library, ADR-0028).
3. Walks items (published + drafts), pages, page-data, and
per-instance block files in scope.
4. For each record below the schema's current version, builds the
chain via `migrate-bridge.migrateRecord` and writes the migrated
record back via the existing `writeX` storage helpers (which stamp
`schemaVersion` on save). `--dry-run` skips writes.
5. Per-record reporter prints `OK`, `MIGRATED v→v`, `SKIPPED <reason>`,
`FAILED <error>`. Exit 0 on success or any `--dry-run`; exit 1 on
any record-level failure.

`clear-admin backfill-schema-versions`:

```
clear-admin backfill-schema-versions [--dry-run] [--collection <slug>] [--bucket <path>] [--verbose]
```

The Phase 5 stub's argv contract (`--dry-run`, `--collection`, `--help`)
is preserved; `--bucket` and `--verbose` are additive.

Walks every record kind (items, pages, page-data, block instances,
identity, nav, theme tokens). For records missing or carrying a
malformed `schemaVersion`, stamps the record with the matching schema
file's `version` (or `DEFAULT_SCHEMA_VERSION` `"1.0.0"` when the
schema's version is also absent, per `assumeSchemaVersion`). Writes go
through the existing named writers (`writeItem`, `writePage`,
`writePageData`, `writeBlock`, `writeIdentity`, `writeNav`,
`writeTokens`) so the on-disk encoding policy stays uniform.

Both CLIs are wired into the existing `bin/clear-admin.js` dispatch —
no new bin wrappers needed.
37 changes: 37 additions & 0 deletions .changeset/migrate-runner-blocks-marketing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
'@clearcms/blocks-marketing': major
---

Hero v1 → v2 — schema bump + migration (T-6.1 / ADR-0028 demo).

The first sample per-block migration shipped from a `@clearcms/blocks-*`
library. Demonstrates the end-to-end greedy-at-read + lazy-on-save
loop adopters get for free once `clear-admin migrate-records` lands:

- `blocks/Hero.schema.json` — `version` bumps `1.0.0` → `2.0.0`.
Renames the `subheadline` field to `subhead` and adds two optional
fields, `secondaryCtaLabel` and `secondaryCtaHref`, for hero layouts
with a primary + secondary action pair.
- `migrations/Hero/1.0.0-to-2.0.0.json` — declarative migration that
renames the persisted `props.subheadline` field to `props.subhead`
on existing block instances. Discovered by
`loadBlockMigrations({ projectRoot })` from
`@clearcms/spec/migrate/runtime` per ADR-0028's library convention
(`<pkg>/migrations/<BlockType>/<from>-to-<to>.{json|ts}`).
- `blocks/Hero.astro` — props interface updated to the v2 shape;
template renders the optional secondary CTA when both label + href
are present. Subhead class renamed in CSS to match the new field
name.
- `examples/Hero.json` — fixture bumped to `schemaVersion: "2.0.0"` to
exercise the v2 shape end-to-end.

**Breaking** for adopters who pinned `@clearcms/blocks-marketing@^0.1`:
the `Hero` Astro component's `subheadline` prop no longer exists. Any
adopter `<Hero subheadline=... />` call site needs to flip to
`subhead`. Bucket records for `Hero` block instances are migrated
automatically by `clear-admin migrate-records` (or transparently at
read time via the storage `migrate-bridge`); no manual JSON-rewriting
required.

Other nine v1 blocks stay at `version: "1.0.0"` until they need
their own schema bump.
52 changes: 52 additions & 0 deletions .changeset/migrate-runner-spec.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
---
'@clearcms/spec': minor
---

Migration runner — Phase 6 closeout for T-6.1 (ADR-0022 + ADR-0028 + ADR-0015).

Extends `@clearcms/spec/migrate` (pure runner) and
`@clearcms/spec/migrate/runtime` (Node-only fs discovery) with the
exports the bulk runner / storage bridge / per-block libraries need to
chain end-to-end:

`./migrate` (pure, browser-safe — additive):

- `applyChain(record, chain)` — apply a pre-resolved migration chain to
a record. Skips the `buildMigrationChain` BFS when the caller already
has the chain (e.g. cached per-blockType in a request-scope read
helper). Same return contract as `migrate`: stamps the chain's tail
`schemaVersion` and appends `_migration_warnings` for cross-format
ops. Empty chain is a no-op identity returning a shallow clone.
- `inferTargetVersion(record, blockType, registry)` — returns the
registered current version for a block type, or `null` when the type
is unknown. Used by greedy-at-read paths that need to know what
version to migrate _to_ before they call `migrate`.
- `BlockTypeRegistryEntry` type — the `{ type, currentVersion }` shape
`inferTargetVersion`'s registry takes.

`./migrate/runtime` (Node-only — additive):

- `discoverPerBucketMigrations({ bucketRoot, scope? })` — walks
`<bucketRoot>/migrations/<scope>/<from>-to-<to>.{json|ts}` for
cross-cutting adopter-defined migrations (ADR-0015 adapter-aware).
When `scope` is omitted, every immediate subdirectory of
`<bucketRoot>/migrations/` is treated as a scope and walked. Returns
`DiscoveredPerBucketMigration[]` — same `Migration` payload as
`discoverMigrations` but with a `'per-bucket'` source kind.
- `loadBlockMigrations({ projectRoot? })` — walks every installed
`@clearcms/blocks-*` package for per-block migrations across every
block type the package ships. Mirrors
`discoverMigrations({ blockType })` but iterates every block type
found under each package's `migrations/` root in one pass — used by
the bulk command to bootstrap its per-blockType chain cache without N
round-trips.

No existing exports change shape. The `@clearcms/spec/migrate` barrel
stays free of `node:*` imports — discovery exports remain gated behind
the `node`-conditional `./migrate/runtime` sub-path so admin's Astro
client bundle stays clean (the bug PR #106 fixed; this changeset
preserves it).

Sample migration shipped in `@clearcms/blocks-marketing` (separate
changeset) — Hero v1→v2 demonstrates a one-step rename + additive
fields end-to-end.
Loading
Loading