Initial Commit
This commit is contained in:
224
openspec/archive/2026-04-25-folder-reorg-by-domain/proposal.md
Normal file
224
openspec/archive/2026-04-25-folder-reorg-by-domain/proposal.md
Normal file
@@ -0,0 +1,224 @@
|
||||
# OpenSpec Change: folder-reorg-by-domain
|
||||
|
||||
- **Change ID**: folder-reorg-by-domain
|
||||
- **Scope**: Monorepo-wide structural change
|
||||
- **Status**: PROPOSED
|
||||
- **Date**: 2026-04-25
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
Replace the runtime-tier folder split (`universal/`, `browser/`, `react/`, `api/`, `r3f/`, `server/`, `finance/`, `mcp/`, `python/`, `gaming/`) with a **domain-first** layout where every folder corresponds 1:1 to a plugin in the upcoming `suaveplan-skills` marketplace. Tier becomes a per-package property (declared via `package.json` deps, `exports`, and the `"browser"` field) rather than a directory boundary.
|
||||
|
||||
Concurrently:
|
||||
|
||||
1. Retire `@suaveplan/overview` (manifest browser library) and replace with a generated `MANIFEST.md` at the repo root.
|
||||
2. Retire `FOLDERS.yml` (replaced by the new layout itself + `MANIFEST.md`'s tier-overlay view).
|
||||
3. Update every `CLAUDE.md` and `openspec/AGENTS.md` path reference from `universal/<domain>/<pkg>` / `packages/<tier>/<pkg>` to `packages/<plugin>/<pkg>`.
|
||||
4. Add a `monorepo-structure` capability spec codifying the rules.
|
||||
|
||||
Genesis currently has only ~21 packages on disk, so the migration cost is at its lowest. Every package shipped under the legacy layout is one more `git mv` later.
|
||||
|
||||
---
|
||||
|
||||
## Motivation
|
||||
|
||||
The tier-first layout was a quick first cut that has not held up:
|
||||
|
||||
- **Cross-tier domains are scattered.** `drive` lives in `universal/storage/`, `drive-webrtc` in `browser/network/`, `react-drive-sharing` in `react/platform/`, and a future `api-plugin-file-upload` would land in `api/data/` — four directories for one feature surface.
|
||||
- **The same redundancy exists for booking, dmx, audio, video, geo, and almost every gaming feature** (universal core + r3f renderer + react UI + api plugin live in 3–4 folders).
|
||||
- **`r3f/` is a deprecated category by `FOLDERS.yml`'s own admission** — gaming r3f packages were already relocated into `gaming/`. The remaining three (`r3f-earth`, `r3f-booking`, `r3f-dmx`) are stranded.
|
||||
- **Tier signal is redundant.** Whether a package is browser-only is determined by `package.json` (`"browser"` field, browser-only deps); the directory adds nothing.
|
||||
- **Plugin marketplace coupling.** The forthcoming `suaveplan-skills` marketplace ships ~50 plugins, each a vertical slice across tiers. If folders mirror plugins, generating the marketplace, scaffolding new packages, and onboarding contributors all collapse to one mental model.
|
||||
|
||||
---
|
||||
|
||||
## Design
|
||||
|
||||
### New folder layout
|
||||
|
||||
```text
|
||||
packages/
|
||||
<plugin-name>/
|
||||
<package-name>/
|
||||
package.json
|
||||
tsconfig.json
|
||||
vitest.config.ts
|
||||
src/
|
||||
tests/
|
||||
README.md
|
||||
```
|
||||
|
||||
Plugin names match the `suaveplan-<plugin>` keys without the `suaveplan-` prefix. Inside a plugin folder, package directory names match the package's npm name without the `@suaveplan/` prefix.
|
||||
|
||||
### Plugin → package assignment (51 plugins, all 356 current + 22 future packages)
|
||||
|
||||
#### Foundation
|
||||
|
||||
| Folder | Packages |
|
||||
|---|---|
|
||||
| `packages/foundation/` | error, types, typescript-config |
|
||||
| `packages/observability/` | logger, opentelemetry, profiler, audit-logging, network-observability, analytics-browser |
|
||||
| `packages/primitives/` | bytes, timing, datetime, mime, serialize, diff, templates, utils, json, bitpacker |
|
||||
| `packages/i18n/` | i18n, locale-data, react-translate |
|
||||
| `packages/validation/` | validation, schema-registry |
|
||||
| `packages/control-flow/` | retry, idempotency, fsm, undo |
|
||||
| `packages/config/` | env, config, feature-flags |
|
||||
| `packages/events/` | events, events-metrics, events-otel, events-schema, events-transport, event-sourcing, broadcast-channel |
|
||||
| `packages/streams/` | streams, streams-metadata, streams-chunk-queue, queue, queue-distribution |
|
||||
| `packages/random/` | pseudo-random, random, noise |
|
||||
|
||||
#### Crypto / Auth / Vault
|
||||
|
||||
| Folder | Packages |
|
||||
|---|---|
|
||||
| `packages/crypto/` | crypto, crypto-utils, crypto-hash, crypto-curve, crypto-cipher, crypto-sodium, crypto-browser, crypto-keys, crypto-vault, react-crypto, security-codes |
|
||||
| `packages/auth/` | auth, permissions, jwt-tenant, rate-limiter, oauth-client, slsa, password-formats, macos-keychain, react-auth, react-auth-whitelabel, react-permissions, react-consent-overlay, api-plugin-auth, api-plugin-user, api-plugin-tenant, api-plugin-admin, server-keys, sandbox |
|
||||
| `packages/vaulted/` *(MIGRATION.md future)* | keys, vault, vault-sync, srp, otp, cbor, webauthn, native-messaging, password-strength, form-detection, site-icons, hibp, biometrics, password-generator, api-plugin-vault |
|
||||
|
||||
#### Data / Storage
|
||||
|
||||
| Folder | Packages |
|
||||
|---|---|
|
||||
| `packages/database/` | db, db-sqlite, surrealdb, cache, cache-memory, cache-redis, cache-browser, migration, seed, api-plugin-database |
|
||||
| `packages/storage/` | storage, storage-s3, storage-file, storage-browser, storage-browser-opfs |
|
||||
| `packages/drive/` | drive, drive-sharing, drive-webrtc, react-drive-sharing, react-file-upload, api-plugin-file-upload, packer, packer-browser |
|
||||
| `packages/data/` | etl, crdt, dedup, domain-normalizer, pagination, data-masking, ab-testing, api-plugin-import, api-plugin-export, api-plugin-graphql, api-plugin-analytics |
|
||||
| `packages/search/` | search, api-plugin-search |
|
||||
|
||||
#### Network
|
||||
|
||||
| Folder | Packages |
|
||||
|---|---|
|
||||
| `packages/network-core/` | network, network-bootstrap, network-failover, network-governance, network-protocol, network-quality, network-registry, network-assignment, network-testing, network-websockets, network-standby-transport, service-discovery |
|
||||
| `packages/network-p2p/` | network-webrtc, network-libp2p, network-libp2p-server, network-hyperswarm, network-trystero-server, network-gundb-server, network-discovery-crdt, network-discovery-gundb, network-discovery-hybrid, network-discovery-peerjs, network-discovery-trystero, network-discovery-webtorrent |
|
||||
|
||||
#### API / Platform / UI / Workflow
|
||||
|
||||
| Folder | Packages |
|
||||
|---|---|
|
||||
| `packages/api/` | api, api-shared, api-gateway, websocket-gateway, api-docs, api-schemas, docs, sitemap, react-docs, api-plugin-rate-limit, api-plugin-audit, api-plugin-sse, api-plugin-webhook, api-plugin-vatdash-bridge, webhook-client, api-plugin-cms, api-plugin-site, api-plugin-events |
|
||||
| `packages/platform/` | cli, electrobun, readline, web-workers, pwa, clipboard, macos-contacts, react-iphone, linter, health-check, job-scheduler, caddy-imgproxy, iconz |
|
||||
| `packages/react-ui/` | react-ui, react-modal, react-dnd, react-hotkeys, react-error-boundary, react-notifications, react-loading, react-store, react-charts, react-timeline, react-color-picker, react-calendar, react-rich-text, react-command-palette, react-kanban, react-tour, react-skeleton, react-infinite-scroll, react-tree-view, react-data-table, react-virtual |
|
||||
| `packages/workflow/` | workflow, rules, form-builder, react-forms, react-admin-forms, react-rule-builder, react-wizard |
|
||||
|
||||
#### Communications
|
||||
|
||||
| Folder | Packages |
|
||||
|---|---|
|
||||
| `packages/email/` | email-processing, email-templates, campaigns, contacts, suppression, delivery-tracking, dmarc, audience-rules, emailer, react-campaigns, react-contacts, api-plugin-campaigns, api-plugin-contacts |
|
||||
| `packages/messaging/` | sms, sms-providers, notification-channel, api-plugin-messaging, api-plugin-notifications |
|
||||
| `packages/social/` | slack-client, discord-client, telegram-client, imessage-adapter, message-bridge, react-social, react-ui-social, api-plugin-social |
|
||||
|
||||
#### Commerce / Logistics
|
||||
|
||||
| Folder | Packages |
|
||||
|---|---|
|
||||
| `packages/payment/` | payment, payment-providers, license, api-plugin-payment, api-plugin-banking, api-plugin-subscription, api-plugin-store |
|
||||
| `packages/currency/` | currency, currency-providers, money, cryptocurrency |
|
||||
| `packages/booking/` | booking, r3f-booking |
|
||||
| `packages/logistics/` | ports, react-port-tracking, api-plugin-logistics, api-plugin-customs, api-plugin-procurement, api-plugin-warehouse-ops, api-plugin-asset-register, api-plugin-inventory, api-plugin-gtap, api-plugin-port-tracking |
|
||||
|
||||
#### Geo / Astronomy
|
||||
|
||||
| Folder | Packages |
|
||||
|---|---|
|
||||
| `packages/geo/` | geo, geo-earth, geo-planet, heightmap-tiles, osm-buildings, r3f-earth, react-map |
|
||||
| `packages/astronomy/` *(universe spec)* | universe, solar-system, stars, tides |
|
||||
|
||||
#### Media (per modality)
|
||||
|
||||
| Folder | Packages |
|
||||
|---|---|
|
||||
| `packages/media/` | media, metadata, exif |
|
||||
| `packages/image/` | image, image-quantisation, compress-image, react-image |
|
||||
| `packages/svg/` | compress-svg, emblem-solver |
|
||||
| `packages/fonts/` | font-compress, font-decompress, font-convert, font-subset, react-font-decompress |
|
||||
| `packages/video/` | video, video-thumbnails, react-video |
|
||||
| `packages/audio/` | audio-engine, audio-plugins-fx, audio-controllers, audio-sprite-packer, voice, voice-elevenlabs, react-audio, react-audio-player, react-audio-stream, react-audio-fingerprint, python-audio-fingerprint |
|
||||
| `packages/pdf/` | pdf, react-pdf |
|
||||
| `packages/dmx/` | dmx, r3f-dmx |
|
||||
| `packages/codes/` | barcode, qrcode, qrcode-scan |
|
||||
|
||||
#### Dev / MCP
|
||||
|
||||
| Folder | Packages |
|
||||
|---|---|
|
||||
| `packages/dev/` | testing, testing-dom, testing-e2e, testing-integration, testing-integration-surrealdb, testing-integration-redis, testing-integration-postgres, testing-integration-mailpit, testing-integration-typesense, testing-integration-garage-s3, test-vite, storybook-test-utils, wip |
|
||||
| `packages/mcp/` | mcp |
|
||||
|
||||
#### Gaming (per gaming subdomain)
|
||||
|
||||
| Folder | Packages |
|
||||
|---|---|
|
||||
| `packages/gaming-engine/` | ecs, game-loop, spatial-hash, game-persistence, game-server, game-state-schemas, controller, react-controller, api-plugin-game-server, api-plugin-game-persistence |
|
||||
| `packages/gaming-rigs/` | character-physics, vehicle-physics, mixamo, bone-mapping, ik-solver, animation-events, character-vehicle-picker, r3f-character, r3f-character-vehicle, r3f-character-vehicle-picker, r3f-animation, r3f-vehicle, r3f-controller |
|
||||
| `packages/gaming-combat/` | combat, weapons, hitbox, destructibles, r3f-combat |
|
||||
| `packages/gaming-ai/` | behavior-tree, npc, fauna, r3f-npc, r3f-pathfinding |
|
||||
| `packages/gaming-narrative/` | dialogue, quest, crafting, progression, economy, react-dialogue, react-crafting |
|
||||
| `packages/gaming-world/` | building, day-night *(deprecated)*, weather, fruit-machine, r3f-building, r3f-buildings, r3f-environment, r3f-vegetation, r3f-water, r3f-weather, r3f-terrain, r3f-world, gaming-universe, gaming-environment-lighting |
|
||||
| `packages/gaming-multiplayer/` | lobby, party, chat, emotes, leaderboard, r3f-networking, api-plugin-matchmaking, api-plugin-anticheat, react-social-game, api-plugin-bank, api-plugin-virtual-currency, react-bank |
|
||||
| `packages/gaming-ui/` | react-game-hud, react-game-map, react-game-settings, r3f-ui, r3f-minimap, r3f-inventory |
|
||||
| `packages/gaming-effects/` | r3f-particles, r3f-shaders, r3f-parallax, r3f-audio, r3f-lod, r3f-performance, r3f-camera, r3f-number-plate, r3f-emulator, r3f-xr |
|
||||
| `packages/gaming-physics/` | r3f-physics-core, r3f-physics-rapier, r3f-physics-cascade |
|
||||
|
||||
---
|
||||
|
||||
## MANIFEST.md (replaces @suaveplan/overview)
|
||||
|
||||
A repo-root `MANIFEST.md` is generated by `scripts/generate-manifest.ts` from on-disk truth (each package's `package.json`). It provides:
|
||||
|
||||
1. **Plugin × package table** — every plugin folder, every package within, dependency count, coverage status, npm version.
|
||||
2. **Tier-overlay view** — packages grouped by inferred tier (universal / browser / react / r3f / server / python) for the rare case someone wants the old listing. Tier is inferred from `engines`, `"browser"` field, peer deps (`react`, `@react-three/fiber`), and `bin` entries.
|
||||
3. **Dependency graph** — DOT-format adjacency list embedded in a fenced code block; can be piped to Graphviz.
|
||||
4. **Stale-manifest CI check** — a CI job runs `bun scripts/generate-manifest.ts --check` and fails if the committed `MANIFEST.md` differs from the regenerated output.
|
||||
|
||||
`@suaveplan/overview` is deleted from `packages/` (it is currently published at `0.1.0` to Verdaccio; per genesis convention pre-1.0.0 deletion is a `bun scripts/unpublish.ts --package @suaveplan/overview` operation).
|
||||
|
||||
---
|
||||
|
||||
## Migration approach
|
||||
|
||||
**Single bulk migration in one PR.** A long-running rename branch is the worst of both worlds; everything in `packages/` moves at once, in one mechanical commit, followed by a configuration-update commit.
|
||||
|
||||
1. **`scripts/migrate-folders.ts`** — reads the assignment table from this proposal (or a sibling `assignment.yml`), runs `git mv packages/<old>/<pkg>/ packages/<plugin>/<pkg>/` for every package, and updates root `package.json` `workspaces` glob (`packages/*/*` covers every plugin/package pair).
|
||||
2. **Path updates in configs:**
|
||||
- `turbo.json` — no changes needed (uses workspace globs).
|
||||
- Every `vitest.config.ts` referencing `path.resolve(__dirname, '../../testing/...')` — paths are auto-correct because they're relative to each package and the new layout still has `packages/<plugin>/<pkg>/` as the same depth.
|
||||
- `tsconfig.json` `paths` mapping — regenerate.
|
||||
- Per-package `package.json` exports — unchanged (relative to package root).
|
||||
3. **Doc updates:**
|
||||
- `CLAUDE.md` package list paths.
|
||||
- `openspec/AGENTS.md` — every `universal/<domain>/<pkg>` reference becomes `packages/<plugin>/<pkg>`.
|
||||
- Existing OpenSpec changes' proposals — leave historic; only update `tasks.md` for in-flight changes.
|
||||
4. **Delete `FOLDERS.yml`.**
|
||||
5. **Generate `MANIFEST.md`** for the first time, commit it.
|
||||
6. **Add CI check** `bun scripts/generate-manifest.ts --check`.
|
||||
|
||||
---
|
||||
|
||||
## Out of scope
|
||||
|
||||
- **Renaming any package.** Only directories move; npm names stay identical.
|
||||
- **Changing exports or APIs.** Pure structural change.
|
||||
- **Migrating off Verdaccio for republish.** Republishes happen as part of normal pre-publish gates after the move.
|
||||
|
||||
---
|
||||
|
||||
## Impact
|
||||
|
||||
- **Every package on genesis** (~21 currently shipped + ~5 in flight) gets a `git mv`. No code change required inside packages.
|
||||
- **All in-flight OpenSpec changes** that reference target paths (`enterprise-booking`, `enterprise-testing-*`, etc.) need their `Target path:` line updated. This is mechanical.
|
||||
- **Existing `@suaveplan/overview` consumers** (none in genesis source — it was a leaf manifest reader) lose the package; the replacement is reading `MANIFEST.md` directly or running `scripts/generate-manifest.ts`.
|
||||
- **Future `suaveplan-skills` marketplace** can be generated directly from the folder layout: each `packages/<plugin>/` becomes one plugin manifest.
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- `FOLDERS.yml` (current layout, to be deleted)
|
||||
- `MIGRATION.md` (Vaulted future packages — assigned to `packages/vaulted/`)
|
||||
- `docs/superpowers/specs/2026-04-25-universe-family-design.md` (universe family — assigned to `packages/geo/` + `packages/astronomy/` + `packages/gaming-world/`)
|
||||
- `../suaveplan/README.md` (full 356-package inventory, source for assignment table above)
|
||||
- `CLAUDE.md` § "Packages" — every path reference will be updated.
|
||||
@@ -0,0 +1,86 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Domain-first folder layout
|
||||
|
||||
The monorepo SHALL organise packages into domain folders that map 1:1 to plugins in the `suaveplan-skills` marketplace. The layout is `packages/<plugin>/<package>/` where `<plugin>` is the marketplace plugin name without the `suaveplan-` prefix and `<package>` is the npm name without the `@suaveplan/` prefix. Tier (universal / browser / react / r3f / server / python) is NOT a directory — it is determined per-package by `package.json` deps, the `"browser"` field, peer deps, and `engines`.
|
||||
|
||||
#### Scenario: Every package lives under a plugin folder
|
||||
|
||||
- **WHEN** any package directory is inspected
|
||||
- **THEN** its path is `packages/<plugin>/<package>/` AND `<plugin>` matches a plugin defined in the marketplace assignment manifest
|
||||
|
||||
#### Scenario: No tier-named top-level folders
|
||||
|
||||
- **WHEN** the repository root is listed
|
||||
- **THEN** there are no `universal/`, `browser/`, `react/`, `r3f/`, `api/`, `server/`, `finance/`, `mcp/`, `python/`, or `gaming/` directories
|
||||
|
||||
#### Scenario: Cross-tier domain co-location
|
||||
|
||||
- **WHEN** a domain has packages spanning multiple tiers (e.g. `drive` with universal core, browser P2P plugin, react UI, and api plugin)
|
||||
- **THEN** all of those packages live under the same plugin folder (`packages/drive/`)
|
||||
|
||||
### Requirement: Plugin → package assignment uniqueness
|
||||
|
||||
Every package SHALL appear in exactly one plugin folder. No package may be present in two plugins.
|
||||
|
||||
#### Scenario: Assignment manifest has unique entries
|
||||
|
||||
- **WHEN** `scripts/folder-reorg/assignment.yml` is parsed
|
||||
- **THEN** the union of all packages across all plugins contains no duplicates
|
||||
|
||||
### Requirement: Generated MANIFEST.md replaces @suaveplan/overview
|
||||
|
||||
The repository SHALL contain a generated `MANIFEST.md` at the root that lists every plugin, every package, the inferred tier per package, the dependency graph, and a tier-overlay view. The manifest is regenerated by `bun scripts/generate-manifest.ts` and a `--check` mode validates that the committed file is up-to-date.
|
||||
|
||||
#### Scenario: MANIFEST.md is up to date
|
||||
|
||||
- **WHEN** `bun scripts/generate-manifest.ts --check` is run
|
||||
- **THEN** it exits with status 0 AND the committed `MANIFEST.md` matches the regenerated output byte-for-byte
|
||||
|
||||
#### Scenario: @suaveplan/overview is absent
|
||||
|
||||
- **WHEN** the repository is searched for `@suaveplan/overview`
|
||||
- **THEN** no `package.json` declares it as a dep AND no source file imports it AND no folder named `overview/` exists under `packages/`
|
||||
|
||||
### Requirement: FOLDERS.yml is removed
|
||||
|
||||
`FOLDERS.yml` SHALL NOT exist at the repository root. The folder layout is self-describing via the `packages/` tree and the per-tier overlay lives in `MANIFEST.md`.
|
||||
|
||||
#### Scenario: FOLDERS.yml absent
|
||||
|
||||
- **WHEN** the repository root is listed
|
||||
- **THEN** no file named `FOLDERS.yml` is present
|
||||
|
||||
### Requirement: Tier inference from package.json
|
||||
|
||||
`scripts/generate-manifest.ts` SHALL infer each package's tier deterministically from its `package.json` and source layout, in this priority order: python → r3f → react → browser → server → universal.
|
||||
|
||||
- **python**: package directory name has prefix `python-` OR `package.json` has a top-level `"python"` field.
|
||||
- **r3f**: `peerDependencies` includes `@react-three/fiber` OR `three`.
|
||||
- **react**: `peerDependencies` includes `react` (and tier is not r3f).
|
||||
- **browser**: `package.json` has a `"browser"` field OR `engines` lacks `node`.
|
||||
- **server**: `bin` field is set OR direct dependencies include `bun:sqlite`, `node:fs`, `node:net`, `node:cluster`, `pg`, `ioredis`, or similar Node-only modules.
|
||||
- **universal**: none of the above match.
|
||||
|
||||
#### Scenario: Tier inference is deterministic
|
||||
|
||||
- **WHEN** `scripts/generate-manifest.ts --check` is run twice without source changes
|
||||
- **THEN** both runs produce identical tier classifications for every package
|
||||
|
||||
### Requirement: Path references in CLAUDE.md and openspec/AGENTS.md updated
|
||||
|
||||
`CLAUDE.md` and `openspec/AGENTS.md` SHALL reference packages via `packages/<plugin>/<pkg>/` paths. References to legacy `universal/<domain>/<pkg>/` or `packages/<tier>/<pkg>/` paths SHALL NOT exist in either file.
|
||||
|
||||
#### Scenario: No legacy path references
|
||||
|
||||
- **WHEN** `CLAUDE.md` and `openspec/AGENTS.md` are searched for the regex `(^|[^a-z])(universal|browser|react|r3f|server|finance|mcp|python|gaming)/[a-z]`
|
||||
- **THEN** zero matches are found in either file
|
||||
|
||||
### Requirement: Migration is reversible until merged
|
||||
|
||||
The folder migration SHALL execute via `git mv` (preserving file history) in a single commit, allowing `git revert` to restore the legacy layout if a regression is found before merge.
|
||||
|
||||
#### Scenario: File history preserved
|
||||
|
||||
- **WHEN** `git log --follow packages/<any-plugin>/<any-existing-pkg>/src/<any-file>.ts` is run after migration
|
||||
- **THEN** the log shows commits from before the migration (i.e. `git mv` preserved history, not `rm`+`add`)
|
||||
121
openspec/archive/2026-04-25-folder-reorg-by-domain/tasks.md
Normal file
121
openspec/archive/2026-04-25-folder-reorg-by-domain/tasks.md
Normal file
@@ -0,0 +1,121 @@
|
||||
# Tasks: folder-reorg-by-domain
|
||||
|
||||
**Change ID**: folder-reorg-by-domain
|
||||
**Scope**: Monorepo-wide structural change
|
||||
|
||||
---
|
||||
|
||||
## 1. Pre-flight
|
||||
|
||||
- [ ] Confirm clean working tree (`git status` reports nothing) and no in-flight worktrees with uncommitted work (`git worktree list` then `git status` in each).
|
||||
- [ ] Confirm all currently-published packages on Verdaccio have green pre-publish gates (snapshot the list — `bun scripts/list-published.ts` if available, otherwise grep `npmjs.fq.io`).
|
||||
- [ ] Tag the pre-migration state: `git tag pre-folder-reorg`.
|
||||
|
||||
---
|
||||
|
||||
## 2. Assignment manifest
|
||||
|
||||
- [ ] Create `scripts/folder-reorg/assignment.yml` — machine-readable copy of the plugin → package table from `proposal.md`. Format: `<plugin-name>: [<pkg1>, <pkg2>, ...]`.
|
||||
- [ ] Add a sanity check: every package referenced in `assignment.yml` exists either on disk in genesis OR in `MIGRATION.md` (future) OR in the universe spec (future). Fail fast if any package is unaccounted for.
|
||||
- [ ] Add a uniqueness check: every package appears in exactly one plugin.
|
||||
|
||||
---
|
||||
|
||||
## 3. Migration script
|
||||
|
||||
- [ ] Write `scripts/folder-reorg/migrate-folders.ts`:
|
||||
- Reads `assignment.yml`.
|
||||
- For each package currently on disk under `universal/<domain>/<pkg>/`, runs `git mv universal/<domain>/<pkg>/ packages/<plugin>/<pkg>/`.
|
||||
- Skips packages listed in `assignment.yml` but not yet on disk (future packages from MIGRATION.md / universe spec).
|
||||
- Logs every move; outputs a summary.
|
||||
- [ ] Dry-run mode (`--dry-run`) prints planned moves without executing.
|
||||
|
||||
---
|
||||
|
||||
## 4. Execute migration
|
||||
|
||||
- [ ] Run `bun scripts/folder-reorg/migrate-folders.ts --dry-run`. Review output.
|
||||
- [ ] Run `bun scripts/folder-reorg/migrate-folders.ts`. Single commit: `chore(structure): move all packages to domain-first layout`.
|
||||
- [ ] Verify `packages/` contains exactly the plugin folders from `proposal.md`.
|
||||
- [ ] Verify legacy folders (`universal/`, etc.) are empty or removed.
|
||||
|
||||
---
|
||||
|
||||
## 5. Workspace + tooling updates
|
||||
|
||||
- [ ] Root `package.json` — `workspaces` glob: ensure `packages/*/*` covers the new layout. Remove any tier-specific globs.
|
||||
- [ ] Root `tsconfig.json` — regenerate `paths` mapping if it's not glob-based.
|
||||
- [ ] `turbo.json` — no change expected (uses workspace inheritance); verify by running `bunx turbo run build --dry-run`.
|
||||
- [ ] Run nuclear clean install: `rm -rf node_modules bun.lockb && find . -type d -name "node_modules" -exec rm -rf {} + && bun install --force`.
|
||||
- [ ] Run full lint+typecheck+test sweep: `bunx turbo lint typecheck test`. All packages must stay green — folder move should be transparent to package contents.
|
||||
|
||||
---
|
||||
|
||||
## 6. Documentation updates
|
||||
|
||||
- [ ] `CLAUDE.md` — replace every `universal/<domain>/<pkg>` path reference with `packages/<plugin>/<pkg>`. Update the Packages section to describe the new layout. Update Quick Commands examples.
|
||||
- [ ] `openspec/AGENTS.md` — replace every `universal/<domain>/<pkg>` and `packages/universal/<pkg>` path reference. Update file-size, banned-pattern, and missing-`.md` scan commands.
|
||||
- [ ] `openspec/project.md` — update if it references folder layout.
|
||||
- [ ] In-flight OpenSpec changes (`enterprise-*`) — update only the `Target path:` line in each `proposal.md` if the change is not yet archived. Already-archived changes stay frozen.
|
||||
|
||||
---
|
||||
|
||||
## 7. Delete FOLDERS.yml
|
||||
|
||||
- [ ] `git rm FOLDERS.yml`.
|
||||
- [ ] Add a one-line note to `CLAUDE.md` Packages section: "Folder layout is domain-first; see `MANIFEST.md` for the per-tier overlay view."
|
||||
|
||||
---
|
||||
|
||||
## 8. Retire @suaveplan/overview
|
||||
|
||||
- [ ] `git rm -r packages/data/overview/` (it has been reassigned to foundation but is being retired — confirm by re-reading `proposal.md` and removing it from the foundation row in `assignment.yml` before running the migration script).
|
||||
- [ ] Unpublish from Verdaccio: `bun scripts/unpublish.ts --package @suaveplan/overview` (or manual `npm unpublish @suaveplan/overview --registry https://npmjs.fq.io --force`).
|
||||
- [ ] Search the rest of genesis for any `import ... from '@suaveplan/overview'` or `"@suaveplan/overview"` dependency entries; remove them. Expected: zero matches (the package was a leaf with no in-repo consumers).
|
||||
- [ ] Remove the `enterprise-overview` OpenSpec archive line from any index if one exists.
|
||||
|
||||
---
|
||||
|
||||
## 9. MANIFEST.md generator
|
||||
|
||||
- [ ] Write `scripts/generate-manifest.ts`:
|
||||
- Walks `packages/<plugin>/<pkg>/package.json` for every package.
|
||||
- Emits `MANIFEST.md` at repo root with sections:
|
||||
1. **Plugins** — table of `plugin | package count | total deps`.
|
||||
2. **Packages** — table of `npm name | plugin | tier (inferred) | version | dep count`.
|
||||
3. **Tier overlay** — packages grouped by inferred tier (universal / browser / react / r3f / server / python). Inference rules:
|
||||
- `python` if `package.json` has `"python"` field or path contains `python-`.
|
||||
- `r3f` if `peerDependencies` contains `@react-three/fiber`.
|
||||
- `react` else if `peerDependencies` contains `react`.
|
||||
- `browser` else if `package.json` has `"browser"` field or `engines` excludes node.
|
||||
- `server` else if `bin` is set OR depends on `bun:sqlite` / `node:fs` / similar.
|
||||
- `universal` otherwise.
|
||||
4. **Dependency graph** — DOT block listing `<pkgA> -> <pkgB>` for every workspace dep edge.
|
||||
- `--check` mode regenerates in-memory and diffs against on-disk `MANIFEST.md`; exits non-zero on diff.
|
||||
- [ ] Co-locate `scripts/generate-manifest.md` documentation per genesis docs rules.
|
||||
- [ ] First-time generation: `bun scripts/generate-manifest.ts > MANIFEST.md`. Commit.
|
||||
|
||||
---
|
||||
|
||||
## 10. CI gate
|
||||
|
||||
- [ ] Add `bun scripts/generate-manifest.ts --check` as a CI step in the root pipeline.
|
||||
- [ ] Add the same as a `pre-commit` hook entry (optional — if hooks are configured).
|
||||
|
||||
---
|
||||
|
||||
## 11. Verify
|
||||
|
||||
- [ ] `bunx turbo lint typecheck test` — all green.
|
||||
- [ ] `bunx turbo test:coverage --filter=@suaveplan/*` — every package still at 100%.
|
||||
- [ ] `bunx turbo build` — every package still builds.
|
||||
- [ ] `bun scripts/generate-manifest.ts --check` — clean.
|
||||
- [ ] `git status` — only intentional changes (folder moves, doc updates, MANIFEST.md, removed FOLDERS.yml, removed overview package).
|
||||
- [ ] Spot-check three packages from different plugins (e.g. `packages/core/error/`, `packages/gaming-engine/ecs/`, `packages/drive/drive-webrtc/`) — `package.json` valid, `vitest.config.ts` resolves, tests pass.
|
||||
|
||||
---
|
||||
|
||||
## 12. OpenSpec archival
|
||||
|
||||
- [ ] Fold `specs/monorepo-structure/spec.md` (this change's spec delta) into `openspec/specs/monorepo-structure/spec.md`.
|
||||
- [ ] Move `openspec/changes/folder-reorg-by-domain/` → `openspec/archive/2026-04-25-folder-reorg-by-domain/`.
|
||||
Reference in New Issue
Block a user