bsmnt 0.1.2 → 0.1.3
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/package.json +7 -2
- package/.changeset/README.md +0 -10
- package/.changeset/config.json +0 -16
- package/.cursor/rules/README.md +0 -184
- package/.cursor/rules/architecture.mdc +0 -437
- package/.cursor/rules/components.mdc +0 -436
- package/.cursor/rules/integrations.mdc +0 -447
- package/.cursor/rules/main.mdc +0 -278
- package/.cursor/rules/styling.mdc +0 -433
- package/.github/PULL_REQUEST_TEMPLATE.md +0 -14
- package/.github/workflows/.gitkeep +0 -0
- package/.github/workflows/ci.yml +0 -37
- package/.github/workflows/release.yml +0 -56
- package/.tldr/cache/call_graph.json +0 -7
- package/.tldr/languages.json +0 -6
- package/.tldr/status +0 -1
- package/.tldrignore +0 -84
- package/.vscode/extensions.json +0 -20
- package/.vscode/settings.json +0 -98
- package/CHANGELOG.md +0 -68
- package/CLAUDE.md +0 -156
- package/biome.json +0 -45
- package/bun.lock +0 -496
- package/changelog/04-02-26.md +0 -86
- package/changelog/05-02-26.md +0 -101
- package/changelog/09-02-26.md +0 -83
- package/docs/architecture.drawio +0 -250
- package/docs/architecture.mermaid +0 -85
- package/docs/fix-studio-hydration.md +0 -46
- package/docs/plans/2026-01-29-sanity-smart-merge-design.md +0 -196
- package/docs/plans/2026-01-29-sanity-smart-merge-implementation.md +0 -695
- package/docs/sanity-setup-steps.md +0 -199
- package/packages/cli/package.json +0 -16
- package/tasks/.last-branch +0 -1
- package/tasks/CLAUDE.md +0 -104
- package/tasks/archive/2026-02-09-next-starter-dynamic-layers/prd.json +0 -153
- package/tasks/archive/2026-02-09-next-starter-dynamic-layers/progress.txt +0 -115
- package/tasks/prd-next-starter-dynamic-layers.md +0 -184
- package/tasks/prd-project-restructure.md +0 -375
- package/tasks/prd.json +0 -289
- package/tasks/progress.txt +0 -309
- package/tasks/ralph.sh +0 -113
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
# PRD: Replace Static Templates with next-starter + Dynamic Layers
|
|
2
|
-
|
|
3
|
-
## Introduction
|
|
4
|
-
|
|
5
|
-
The CLI currently maintains 4 complete, nearly-identical template copies (default, webgl, webgpu, experiment). Every bug fix, dependency bump, or structural change must be applied 4 times. The `default` template is essentially a stale snapshot of the `basementstudio/next-starter` repo.
|
|
6
|
-
|
|
7
|
-
This feature replaces the static templates with a single `next-starter` clone as the base, then dynamically overlays technology-specific files and dependencies using a "layers" system — reusing the same smart-merge pattern already proven by the CMS integration system.
|
|
8
|
-
|
|
9
|
-
## Goals
|
|
10
|
-
|
|
11
|
-
- Eliminate template duplication by using `basementstudio/next-starter` as the single source of truth
|
|
12
|
-
- Maintain the same user-facing CLI experience (same 4 template choices, same prompt flow)
|
|
13
|
-
- Create a `layers/` system for technology-specific additions (WebGL, WebGPU, Experiment)
|
|
14
|
-
- Reuse the existing merger infrastructure (`src/mergers/`) for layer injection
|
|
15
|
-
- Delete the entire `template/` directory from the repo
|
|
16
|
-
|
|
17
|
-
## User Stories
|
|
18
|
-
|
|
19
|
-
### US-001: Clone next-starter as base template
|
|
20
|
-
**Description:** As a developer using the CLI, I want my project to be scaffolded from the latest `next-starter` repo so that I always get the most up-to-date base configuration.
|
|
21
|
-
|
|
22
|
-
**Acceptance Criteria:**
|
|
23
|
-
- [ ] `create.js` clones from `github:basementstudio/next-starter#main` instead of `github:basementstudio/basement/template/{type}#main`
|
|
24
|
-
- [ ] Selecting "Default" template produces a project identical to cloning next-starter directly
|
|
25
|
-
- [ ] `bun.lock` is deleted after clone (since dependencies will be modified)
|
|
26
|
-
- [ ] Download spinner text updated to reflect new source
|
|
27
|
-
- [ ] Error/troubleshooting messages updated to reference `basementstudio/next-starter`
|
|
28
|
-
- [ ] Typecheck passes
|
|
29
|
-
|
|
30
|
-
### US-002: Create layer configuration system
|
|
31
|
-
**Description:** As a CLI maintainer, I want technology layers defined in a config file so that adding or modifying layers only requires changing one file.
|
|
32
|
-
|
|
33
|
-
**Acceptance Criteria:**
|
|
34
|
-
- [ ] `LAYER_CONFIG` export added to `src/mergers/config.js` alongside existing `CMS_CONFIG`
|
|
35
|
-
- [ ] Each layer config defines: `replaceFiles`, `additivePaths`, `dependencies`, `devDependencies`
|
|
36
|
-
- [ ] `getLayerConfig(layer)` helper function exported
|
|
37
|
-
- [ ] Config contains entries for `webgl`, `webgpu`, and `experiment`
|
|
38
|
-
- [ ] `webgpu` is a deps-only layer (empty `replaceFiles` and `additivePaths`)
|
|
39
|
-
- [ ] Dependencies match what's currently in each template's `package.template.json`
|
|
40
|
-
|
|
41
|
-
### US-003: Implement layer injection function
|
|
42
|
-
**Description:** As the CLI system, I need to overlay layer-specific files on top of the next-starter base so that WebGL/WebGPU/Experiment projects get their unique components.
|
|
43
|
-
|
|
44
|
-
**Acceptance Criteria:**
|
|
45
|
-
- [ ] `injectLayer(targetDir, layer, spinner)` function added to `src/mergers/index.js`
|
|
46
|
-
- [ ] Function copies additive files from local `layers/{type}/` directory (no tiged needed)
|
|
47
|
-
- [ ] Function replaces files listed in `replaceFiles` (overwrites base version)
|
|
48
|
-
- [ ] Function uses existing `detectPathPrefix()` and `transformPath()` for `src/` directory support
|
|
49
|
-
- [ ] Function returns results object with `replaced`, `copied`, `skipped`, `failed` arrays
|
|
50
|
-
- [ ] `formatMergeResults()` extended to handle `replaced` entries
|
|
51
|
-
- [ ] Skipped layers (type === 'default') produce no errors
|
|
52
|
-
|
|
53
|
-
### US-004: Extract layer files from templates
|
|
54
|
-
**Description:** As a CLI maintainer, I need the unique files from each template extracted into a `layers/` directory so they can be overlaid on next-starter.
|
|
55
|
-
|
|
56
|
-
**Acceptance Criteria:**
|
|
57
|
-
- [ ] `layers/webgl/app/page.tsx` contains the WebGL-specific page (DynamicCanvas import)
|
|
58
|
-
- [ ] `layers/webgl/components/webgl/canvas/dynamic.tsx` exists (from template/webgl)
|
|
59
|
-
- [ ] `layers/webgl/components/webgl/canvas/index.tsx` exists (from template/webgl)
|
|
60
|
-
- [ ] `layers/webgl/components/webgl/components/scene/index.tsx` exists (from template/webgl)
|
|
61
|
-
- [ ] `layers/experiment/components/layout/header/index.tsx` exists (custom header with NavigationMenu)
|
|
62
|
-
- [ ] `layers/experiment/components/layout/navigation-menu.tsx` exists
|
|
63
|
-
- [ ] `layers/experiment/lib/constats.ts` exists
|
|
64
|
-
- [ ] `layers/experiment/lib/utils/cn.ts` exists
|
|
65
|
-
- [ ] `layers/webgpu/` directory exists (empty, deps-only layer)
|
|
66
|
-
- [ ] Files are byte-for-byte identical to their template counterparts
|
|
67
|
-
|
|
68
|
-
### US-005: Integrate layer injection into create flow
|
|
69
|
-
**Description:** As the CLI system, I need the layer injection step wired into the project creation flow so it runs between template download and CMS integration.
|
|
70
|
-
|
|
71
|
-
**Acceptance Criteria:**
|
|
72
|
-
- [ ] Layer injection runs after next-starter clone, before CMS integration
|
|
73
|
-
- [ ] Layer injection only runs when `type !== 'default'`
|
|
74
|
-
- [ ] Progress spinner shows layer name during injection
|
|
75
|
-
- [ ] Injection results displayed to user (files added/replaced)
|
|
76
|
-
- [ ] Failures produce warnings, not hard errors
|
|
77
|
-
- [ ] CMS integration (Sanity) still works correctly after layer injection
|
|
78
|
-
- [ ] Typecheck passes
|
|
79
|
-
|
|
80
|
-
### US-006: Config-driven dependency injection
|
|
81
|
-
**Description:** As the CLI system, I need package.json hydration to read layer dependencies from config instead of being hardcoded in create.js.
|
|
82
|
-
|
|
83
|
-
**Acceptance Criteria:**
|
|
84
|
-
- [ ] Layer dependencies read from `LAYER_CONFIG` and merged into `package.json`
|
|
85
|
-
- [ ] CMS dependencies still injected as before (unchanged)
|
|
86
|
-
- [ ] Animation library dependencies still injected as before (unchanged)
|
|
87
|
-
- [ ] `package.template.json` rename logic simplified (next-starter uses `package.json` directly)
|
|
88
|
-
- [ ] Project name and version still set correctly
|
|
89
|
-
- [ ] Typecheck passes
|
|
90
|
-
|
|
91
|
-
### US-007: Delete template directory
|
|
92
|
-
**Description:** As a CLI maintainer, I want the `template/` directory removed so there's no duplicated code to maintain.
|
|
93
|
-
|
|
94
|
-
**Acceptance Criteria:**
|
|
95
|
-
- [ ] `template/default/` deleted
|
|
96
|
-
- [ ] `template/webgl/` deleted
|
|
97
|
-
- [ ] `template/webgpu/` deleted
|
|
98
|
-
- [ ] `template/experiment/` deleted
|
|
99
|
-
- [ ] No remaining references to `template/` paths in source code
|
|
100
|
-
- [ ] No remaining references to `basementstudio/basement/template/` in source code
|
|
101
|
-
|
|
102
|
-
### US-008: End-to-end verification
|
|
103
|
-
**Description:** As a CLI maintainer, I need to verify all template + CMS + animation combinations work correctly.
|
|
104
|
-
|
|
105
|
-
**Acceptance Criteria:**
|
|
106
|
-
- [ ] `basement -c test-default -d -no-cms -no-animation -claude -no-hooks` produces a working project
|
|
107
|
-
- [ ] `basement -c test-webgl -webgl -no-cms -no-animation -claude -no-hooks` produces a working project with R3F components
|
|
108
|
-
- [ ] `basement -c test-webgpu -webgpu -no-cms -no-animation -claude -no-hooks` produces a working project with WebGPU deps
|
|
109
|
-
- [ ] `basement -c test-experiment -exp -no-cms -no-animation -claude -no-hooks` produces a working project with experiment header
|
|
110
|
-
- [ ] `basement -c test-sanity -webgl -sanity -gsap -claude -no-hooks` produces a working project with CMS + animation + layer
|
|
111
|
-
- [ ] All generated projects pass `bun install && bun dev` (dev server starts)
|
|
112
|
-
|
|
113
|
-
## Functional Requirements
|
|
114
|
-
|
|
115
|
-
- FR-1: The CLI must clone `basementstudio/next-starter#main` as the base for all template types
|
|
116
|
-
- FR-2: When `type !== 'default'`, the CLI must apply the corresponding layer from the local `layers/` directory
|
|
117
|
-
- FR-3: Layer injection must copy additive files without overwriting existing files
|
|
118
|
-
- FR-4: Layer injection must replace files listed in `replaceFiles`, overwriting the base version
|
|
119
|
-
- FR-5: Layer injection must respect `src/` directory structure (using existing `detectPathPrefix`)
|
|
120
|
-
- FR-6: Layer dependencies must be merged into `package.json` from `LAYER_CONFIG`
|
|
121
|
-
- FR-7: CMS integration must continue to work identically after layer injection
|
|
122
|
-
- FR-8: The `bun.lock` file must be deleted after cloning next-starter
|
|
123
|
-
- FR-9: The user-facing prompt flow must remain unchanged (same 4 template choices)
|
|
124
|
-
- FR-10: The `template/` directory must be deleted from the repository
|
|
125
|
-
|
|
126
|
-
## Non-Goals
|
|
127
|
-
|
|
128
|
-
- No multi-layer support (combining WebGL + Experiment) — one layer per project
|
|
129
|
-
- No `add-layer` command for existing projects (only `create` flow)
|
|
130
|
-
- No version pinning UI — always clones latest `main`
|
|
131
|
-
- No changes to the CMS integration system (`src/mergers/` for Sanity/BaseHub)
|
|
132
|
-
- No changes to the hooks, plugins, or agent skills systems
|
|
133
|
-
- No new merger functions for layers (layers use simple copy/replace, not smart merge)
|
|
134
|
-
|
|
135
|
-
## Technical Considerations
|
|
136
|
-
|
|
137
|
-
- **Reuse existing infrastructure:** `detectPathPrefix()`, `transformPath()`, and `formatMergeResults()` from `src/mergers/index.js` are already built for this pattern
|
|
138
|
-
- **Layer files are local:** Unlike CMS integrations (cloned via tiged from a remote branch), layer files live in the CLI repo's `layers/` directory. No network request needed.
|
|
139
|
-
- **Application order matters:** Layers run before CMS integration. Layers do NOT modify `layout.tsx`, so the Sanity layout merger continues to work on the unmodified base layout.
|
|
140
|
-
- **Package.json format:** `next-starter` uses `package.json` (not `package.template.json`), simplifying hydration logic.
|
|
141
|
-
|
|
142
|
-
### Files to Modify
|
|
143
|
-
|
|
144
|
-
| File | Change Type |
|
|
145
|
-
|------|-------------|
|
|
146
|
-
| `src/mergers/config.js` | Add `LAYER_CONFIG`, `getLayerConfig()` |
|
|
147
|
-
| `src/mergers/index.js` | Add `injectLayer()`, extend `formatMergeResults()` |
|
|
148
|
-
| `src/commands/create.js` | Change tiged source, add layer step, config-driven deps |
|
|
149
|
-
|
|
150
|
-
### Files to Create
|
|
151
|
-
|
|
152
|
-
| File | Source |
|
|
153
|
-
|------|--------|
|
|
154
|
-
| `layers/webgl/app/page.tsx` | `template/webgl/app/page.tsx` |
|
|
155
|
-
| `layers/webgl/components/webgl/canvas/dynamic.tsx` | `template/webgl/components/webgl/canvas/dynamic.tsx` |
|
|
156
|
-
| `layers/webgl/components/webgl/canvas/index.tsx` | `template/webgl/components/webgl/canvas/index.tsx` |
|
|
157
|
-
| `layers/webgl/components/webgl/components/scene/index.tsx` | `template/webgl/components/webgl/components/scene/index.tsx` |
|
|
158
|
-
| `layers/experiment/components/layout/header/index.tsx` | `template/experiment/components/layout/header/index.tsx` |
|
|
159
|
-
| `layers/experiment/components/layout/navigation-menu.tsx` | `template/experiment/components/layout/navigation-menu.tsx` |
|
|
160
|
-
| `layers/experiment/lib/constats.ts` | `template/experiment/lib/constats.ts` |
|
|
161
|
-
| `layers/experiment/lib/utils/cn.ts` | `template/experiment/lib/utils/cn.ts` |
|
|
162
|
-
|
|
163
|
-
### Files/Directories to Delete
|
|
164
|
-
|
|
165
|
-
| Path | Reason |
|
|
166
|
-
|------|--------|
|
|
167
|
-
| `template/default/` | Replaced by next-starter clone |
|
|
168
|
-
| `template/webgl/` | Replaced by `layers/webgl/` |
|
|
169
|
-
| `template/webgpu/` | Replaced by `layers/webgpu/` |
|
|
170
|
-
| `template/experiment/` | Replaced by `layers/experiment/` |
|
|
171
|
-
|
|
172
|
-
## Success Metrics
|
|
173
|
-
|
|
174
|
-
- Template directory eliminated (0 duplicated files to maintain)
|
|
175
|
-
- All 4 template types produce working projects with `bun dev`
|
|
176
|
-
- CMS + layer combinations work correctly
|
|
177
|
-
- CLI prompt flow unchanged (invisible to users)
|
|
178
|
-
- Layer addition requires only: adding files to `layers/`, adding config to `LAYER_CONFIG`
|
|
179
|
-
|
|
180
|
-
## Open Questions
|
|
181
|
-
|
|
182
|
-
- Should we add a `--starter-ref` CLI flag in a future iteration for version pinning?
|
|
183
|
-
- If next-starter changes its directory structure significantly, should the CLI validate expected paths before applying layers?
|
|
184
|
-
- Should the `experiment` template's `constats.ts` typo be fixed to `constants.ts`?
|
|
@@ -1,375 +0,0 @@
|
|
|
1
|
-
# PRD: Project Restructure — Separation of CLI and Templates
|
|
2
|
-
|
|
3
|
-
## Introduction
|
|
4
|
-
|
|
5
|
-
The `@basementstudio/cli` project has grown organically into a monolithic structure where CLI logic, templates, integrations, mergers, and hooks are tangled together in a flat directory with fragmented configuration. This restructure separates the project into a clean monorepo with two primary packages: the CLI tool (`packages/cli`) and the template scaffolder (`packages/create-basement-app`), following the pattern established by [basementstudio/xmcp](https://github.com/basementstudio/xmcp).
|
|
6
|
-
|
|
7
|
-
### Problem
|
|
8
|
-
|
|
9
|
-
1. **No separation of concerns** — CLI routing, prompting, template downloading, file merging, package hydration, agent setup, and hook copying all live in a single 415-line function (`create.js`)
|
|
10
|
-
2. **Fragmented configuration** — Layer deps live in `config.js`, CMS deps are hardcoded in `create.js`, animation deps are hardcoded elsewhere. No single source of truth.
|
|
11
|
-
3. **Templates are not standalone** — You can't preview, test, or lint a template in isolation. They're partial overlays that only make sense after being merged onto `next-starter` at runtime.
|
|
12
|
-
4. **Hardcoded paths everywhere** — `../../layers`, `../../template-hooks`, `../../.env` — brittle references that break when you move files.
|
|
13
|
-
5. **Duplicate/dead code** — Both `chalk` and `picocolors`, unused `inquirer` dependency, orphaned `next-config-merger.js`.
|
|
14
|
-
6. **Hard to contribute** — A designer or dev who wants to update a template must understand the merger system, config files, and the full CLI pipeline.
|
|
15
|
-
|
|
16
|
-
### Solution
|
|
17
|
-
|
|
18
|
-
Move to a **bun workspaces monorepo** with full standalone templates. Each template is a complete, working Next.js project. The CLI simply copies the right template and applies optional integrations on top.
|
|
19
|
-
|
|
20
|
-
## Goals
|
|
21
|
-
|
|
22
|
-
- Each folder has a single responsibility and a clear owner
|
|
23
|
-
- Templates are complete, standalone Next.js projects that can be previewed and tested independently
|
|
24
|
-
- CLI code is isolated from template content — modifying one doesn't require understanding the other
|
|
25
|
-
- All dependency/script declarations for each integration type live in one config file (single source of truth)
|
|
26
|
-
- Contributors can update templates by editing familiar Next.js files, no knowledge of merger internals needed
|
|
27
|
-
- Dead code, duplicate libraries, and orphaned files are eliminated
|
|
28
|
-
- The merger system is refactored with proper validation and error handling
|
|
29
|
-
|
|
30
|
-
## User Stories
|
|
31
|
-
|
|
32
|
-
### US-001: Set up bun workspaces monorepo structure
|
|
33
|
-
**Description:** As a maintainer, I want the project organized as a bun workspaces monorepo so that packages are properly isolated with clear boundaries.
|
|
34
|
-
|
|
35
|
-
**Acceptance Criteria:**
|
|
36
|
-
- [ ] Root `package.json` with `"workspaces": ["packages/*"]` configuration
|
|
37
|
-
- [ ] Root `biome.json` shared across all packages
|
|
38
|
-
- [ ] `packages/cli/` — CLI entry point and command routing
|
|
39
|
-
- [ ] `packages/create-basement-app/` — Templates, integrations, hooks, and scaffolding logic
|
|
40
|
-
- [ ] Each package has its own `package.json` with correct name, version, bin, and dependencies
|
|
41
|
-
- [ ] `bun install` at root installs all workspace dependencies
|
|
42
|
-
- [ ] Existing `.changeset/`, `.github/workflows/`, and release infrastructure updated for workspaces
|
|
43
|
-
- [ ] Typecheck passes
|
|
44
|
-
|
|
45
|
-
### US-002: Create standalone templates in create-basement-app
|
|
46
|
-
**Description:** As a contributor, I want each template (default, webgl, webgpu, experiment) to be a complete, self-contained Next.js project so I can preview, lint, and test it without running the full CLI.
|
|
47
|
-
|
|
48
|
-
**Acceptance Criteria:**
|
|
49
|
-
- [ ] `packages/create-basement-app/templates/default/` — Full Next.js project (cloned from next-starter baseline)
|
|
50
|
-
- [ ] `packages/create-basement-app/templates/webgl/` — Full Next.js project with R3F canvas, scene components, and all WebGL deps in its `package.json`
|
|
51
|
-
- [ ] `packages/create-basement-app/templates/webgpu/` — Full Next.js project with WebGPU setup and alpha R3F deps
|
|
52
|
-
- [ ] `packages/create-basement-app/templates/experiment/` — Full Next.js project with experiment navigation, header, and constants
|
|
53
|
-
- [ ] Each template has a valid `package.json` with all its dependencies (no external hydration needed)
|
|
54
|
-
- [ ] Each template can be installed and run independently (`cd templates/webgl && bun install && bun dev`)
|
|
55
|
-
- [ ] The old `layers/` directory and overlay-based injection for templates is removed
|
|
56
|
-
- [ ] `_gitignore` convention used (renamed to `.gitignore` during scaffolding, since npm strips dotfiles)
|
|
57
|
-
|
|
58
|
-
### US-003: Move integrations into create-basement-app
|
|
59
|
-
**Description:** As a maintainer, I want CMS integrations co-located with templates inside `create-basement-app` so the scaffolding package is self-contained.
|
|
60
|
-
|
|
61
|
-
**Acceptance Criteria:**
|
|
62
|
-
- [ ] `packages/create-basement-app/integrations/sanity/` — All Sanity integration files (currently downloaded from remote branch)
|
|
63
|
-
- [ ] `packages/create-basement-app/integrations/basehub/` — All BaseHub integration files
|
|
64
|
-
- [ ] Integration config (file paths, merge rules, dependencies, scripts) lives in a single `integrations/{cms}/config.js` manifest
|
|
65
|
-
- [ ] No more runtime downloading from remote GitHub branches via tiged for integrations
|
|
66
|
-
- [ ] Merger functions co-located with their integration: `integrations/sanity/mergers/`
|
|
67
|
-
- [ ] CMS dependencies and scripts declared in the integration config, not hardcoded in the create command
|
|
68
|
-
- [ ] Typecheck passes
|
|
69
|
-
|
|
70
|
-
### US-004: Move template-hooks into create-basement-app
|
|
71
|
-
**Description:** As a maintainer, I want optional hooks co-located with the scaffolding package as copyable files.
|
|
72
|
-
|
|
73
|
-
**Acceptance Criteria:**
|
|
74
|
-
- [ ] `packages/create-basement-app/template-hooks/` contains all four hooks
|
|
75
|
-
- [ ] Hook discovery (for the interactive prompt) reads from this co-located directory
|
|
76
|
-
- [ ] Hook copying uses the co-located path, no `../../` navigation
|
|
77
|
-
- [ ] Hooks with external dependencies (`use-battery.ts` -> `lodash-es`, `use-device-perf.ts` -> `detect-gpu`, `react-device-detect`, `zustand`) have their deps declared in a manifest or config so the scaffolder can inject them into the generated project's `package.json`
|
|
78
|
-
- [ ] Typecheck passes
|
|
79
|
-
|
|
80
|
-
### US-005: Extract CLI package with clean command routing
|
|
81
|
-
**Description:** As a developer, I want the CLI package to only handle argument parsing and command routing, delegating all scaffolding logic to `create-basement-app`.
|
|
82
|
-
|
|
83
|
-
**Acceptance Criteria:**
|
|
84
|
-
- [ ] `packages/cli/bin/index.js` — Entry point with `"basement"` bin command
|
|
85
|
-
- [ ] `packages/cli/src/commands/` — Command modules that import from `create-basement-app`
|
|
86
|
-
- [ ] `packages/cli/` has `create-basement-app` as a workspace dependency
|
|
87
|
-
- [ ] Argument parsing is decoupled from hardcoded template/CMS/animation names — reads available options from `create-basement-app` exports
|
|
88
|
-
- [ ] Single color library (`picocolors`) — remove `chalk`
|
|
89
|
-
- [ ] Remove unused `inquirer` dependency
|
|
90
|
-
- [ ] The `worktree` command stays in the CLI package (it's a dev tool, not scaffolding)
|
|
91
|
-
- [ ] Typecheck passes
|
|
92
|
-
|
|
93
|
-
### US-006: Refactor the create pipeline into composable steps
|
|
94
|
-
**Description:** As a maintainer, I want the project creation pipeline broken into small, testable, single-purpose functions instead of one 415-line monolith.
|
|
95
|
-
|
|
96
|
-
**Acceptance Criteria:**
|
|
97
|
-
- [ ] Scaffolding logic lives in `packages/create-basement-app/src/` with separate modules:
|
|
98
|
-
- `copy-template.ts` — Copy the selected template to target directory
|
|
99
|
-
- `apply-integration.ts` — Apply CMS integration (merge + additive files)
|
|
100
|
-
- `hydrate-package.ts` — Inject dependencies, scripts, and metadata into package.json
|
|
101
|
-
- `setup-agent.ts` — Agent skills installation and MCP setup
|
|
102
|
-
- `copy-hooks.ts` — Copy selected hooks and inject their dependencies
|
|
103
|
-
- `setup-sanity.ts` — Automated Sanity project creation (moved from CLI)
|
|
104
|
-
- [ ] Each module is independently importable and testable
|
|
105
|
-
- [ ] The CLI's `create` command orchestrates these modules in sequence
|
|
106
|
-
- [ ] The `add-integration` command reuses `apply-integration.ts` instead of duplicating logic
|
|
107
|
-
- [ ] Typecheck passes
|
|
108
|
-
|
|
109
|
-
### US-007: Centralize all dependency and script declarations
|
|
110
|
-
**Description:** As a maintainer, I want a single source of truth for each integration's dependencies and scripts so I never have to update multiple files when a version changes.
|
|
111
|
-
|
|
112
|
-
**Acceptance Criteria:**
|
|
113
|
-
- [ ] Each integration (sanity, basehub) has a `config.js` manifest declaring: `dependencies`, `devDependencies`, `scripts`, `mergeFiles`, `additivePaths`
|
|
114
|
-
- [ ] Animation library configs (`gsap`, `motion`) declared in a `packages/create-basement-app/src/configs/animations.js` manifest
|
|
115
|
-
- [ ] Template configs (if any template needs runtime dep injection beyond what's in its own `package.json`) live alongside the template
|
|
116
|
-
- [ ] `create.js` reads ALL dependency info from config manifests — zero hardcoded version strings in the pipeline
|
|
117
|
-
- [ ] Typecheck passes
|
|
118
|
-
|
|
119
|
-
### US-008: Clean up dead code and duplicate dependencies
|
|
120
|
-
**Description:** As a maintainer, I want all unused code, duplicate libraries, and orphaned files removed.
|
|
121
|
-
|
|
122
|
-
**Acceptance Criteria:**
|
|
123
|
-
- [ ] Remove `inquirer` from dependencies (unused — `prompts` is used instead)
|
|
124
|
-
- [ ] Remove `chalk` — standardize on `picocolors` everywhere
|
|
125
|
-
- [ ] Remove or integrate orphaned `next-config-merger.js` (defined but never registered in CMS_MERGERS)
|
|
126
|
-
- [ ] Remove `dotenv` if only used for CLI development (move to devDependencies or remove entirely)
|
|
127
|
-
- [ ] Remove empty `layers/webgpu/.gitkeep` and the entire old `layers/` directory
|
|
128
|
-
- [ ] Remove the old `integrations/` reference directory from root (files now live in create-basement-app)
|
|
129
|
-
- [ ] Remove old `template-hooks/` from root
|
|
130
|
-
- [ ] Verify no dead imports or unreachable code paths remain
|
|
131
|
-
- [ ] Typecheck passes
|
|
132
|
-
|
|
133
|
-
### US-009: Migrate to TypeScript for CLI and scaffolder
|
|
134
|
-
**Description:** As a developer, I want the CLI and scaffolding code in TypeScript so we get type safety, better IDE support, and catch errors at build time.
|
|
135
|
-
|
|
136
|
-
**Acceptance Criteria:**
|
|
137
|
-
- [ ] `packages/cli/src/` — All files in TypeScript with `strict: true`
|
|
138
|
-
- [ ] `packages/create-basement-app/src/` — All files in TypeScript with `strict: true`
|
|
139
|
-
- [ ] `tsconfig.json` in each package with proper `paths`, `outDir`, `rootDir`
|
|
140
|
-
- [ ] Config files typed with proper interfaces (`LayerConfig`, `CmsConfig`, `AnimationConfig`)
|
|
141
|
-
- [ ] No `any` types — use `unknown` and narrow
|
|
142
|
-
- [ ] Build step compiles TS to JS for the published package
|
|
143
|
-
- [ ] Typecheck passes with zero errors
|
|
144
|
-
|
|
145
|
-
### US-010: Add validation for config-filesystem consistency
|
|
146
|
-
**Description:** As a maintainer, I want the scaffolder to validate that config manifests match the actual filesystem so mismatches are caught early instead of failing silently at runtime.
|
|
147
|
-
|
|
148
|
-
**Acceptance Criteria:**
|
|
149
|
-
- [ ] On startup (or as a test), validate that every path in `additivePaths` and `mergeFiles` exists in the corresponding template/integration directory
|
|
150
|
-
- [ ] Validate that every merger function referenced in config has a corresponding implementation
|
|
151
|
-
- [ ] Clear error messages when validation fails: "Integration sanity references file X but it doesn't exist in integrations/sanity/"
|
|
152
|
-
- [ ] Validation runs as part of CI
|
|
153
|
-
- [ ] Typecheck passes
|
|
154
|
-
|
|
155
|
-
## Functional Requirements
|
|
156
|
-
|
|
157
|
-
- FR-1: The project MUST be a bun workspaces monorepo with `packages/cli` and `packages/create-basement-app`
|
|
158
|
-
- FR-2: The `basement` CLI command MUST work identically to the current version after restructuring (same flags, same prompts, same output)
|
|
159
|
-
- FR-3: Templates MUST be full standalone Next.js projects that can be independently installed and run
|
|
160
|
-
- FR-4: CMS integrations MUST be local files in `create-basement-app/integrations/`, not downloaded from remote branches at runtime
|
|
161
|
-
- FR-5: All dependency version declarations MUST live in config manifests, not hardcoded in pipeline code
|
|
162
|
-
- FR-6: The `add-integration` command MUST share implementation with the `create` command's integration step (no duplication)
|
|
163
|
-
- FR-7: The CLI package MUST depend on `create-basement-app` as a workspace dependency for all scaffolding operations
|
|
164
|
-
- FR-8: Template file paths MUST NOT use relative `../../` navigation — use proper package resolution or `__dirname`-based paths relative to the package root
|
|
165
|
-
- FR-9: The `worktree` command MUST remain in the CLI package (not in create-basement-app)
|
|
166
|
-
- FR-10: The changeset/release pipeline MUST be updated to publish both packages independently
|
|
167
|
-
- FR-11: All source code MUST be TypeScript with `strict: true`
|
|
168
|
-
|
|
169
|
-
## Non-Goals (Out of Scope)
|
|
170
|
-
|
|
171
|
-
- Changing the generated project's structure or conventions (output remains identical)
|
|
172
|
-
- Adding new templates, integrations, or hooks (only restructuring existing ones)
|
|
173
|
-
- Migrating from `prompts` to another prompt library
|
|
174
|
-
- Adding a test suite (beyond config validation — full test coverage is a separate effort)
|
|
175
|
-
- Changing the CLI command name from `basement`
|
|
176
|
-
- Moving to a different monorepo tool (no Turborepo, just bun workspaces)
|
|
177
|
-
- Rewriting mergers to use proper AST parsing (regex-based mergers stay, just reorganized)
|
|
178
|
-
- Publishing templates as separate npm packages
|
|
179
|
-
|
|
180
|
-
## Target Directory Structure
|
|
181
|
-
|
|
182
|
-
```
|
|
183
|
-
basement-starter-cli/
|
|
184
|
-
├── package.json # Root: workspaces config, shared scripts
|
|
185
|
-
├── biome.json # Shared linting/formatting
|
|
186
|
-
├── bun.lock
|
|
187
|
-
├── .changeset/ # Changeset config (updated for workspaces)
|
|
188
|
-
├── .github/workflows/release.yml # Updated for multi-package publish
|
|
189
|
-
│
|
|
190
|
-
├── packages/
|
|
191
|
-
│ ├── cli/ # @basementstudio/cli
|
|
192
|
-
│ │ ├── package.json # bin: "basement", depends on create-basement-app
|
|
193
|
-
│ │ ├── tsconfig.json
|
|
194
|
-
│ │ ├── bin/
|
|
195
|
-
│ │ │ └── index.js # CLI entry point (thin loader → dist/)
|
|
196
|
-
│ │ └── src/
|
|
197
|
-
│ │ ├── index.ts # Arg parsing + command routing
|
|
198
|
-
│ │ ├── commands/
|
|
199
|
-
│ │ │ ├── create.ts # Orchestrates create-basement-app modules
|
|
200
|
-
│ │ │ ├── add-integration.ts # Reuses apply-integration from create-basement-app
|
|
201
|
-
│ │ │ └── worktree.ts # Git worktree management (stays here)
|
|
202
|
-
│ │ └── utils/
|
|
203
|
-
│ │ └── display.ts # Banner, help text, success messages
|
|
204
|
-
│ │
|
|
205
|
-
│ └── create-basement-app/ # @basementstudio/create-basement-app
|
|
206
|
-
│ ├── package.json # Standalone scaffolding package
|
|
207
|
-
│ ├── tsconfig.json
|
|
208
|
-
│ ├── src/
|
|
209
|
-
│ │ ├── index.ts # Public API: exports all scaffolding functions
|
|
210
|
-
│ │ ├── copy-template.ts # Copy selected template to target dir
|
|
211
|
-
│ │ ├── apply-integration.ts # Apply CMS integration (merge + copy)
|
|
212
|
-
│ │ ├── hydrate-package.ts # Inject deps, scripts, metadata into package.json
|
|
213
|
-
│ │ ├── setup-agent.ts # Agent skills + MCP registration
|
|
214
|
-
│ │ ├── setup-sanity.ts # Automated Sanity project/token creation
|
|
215
|
-
│ │ ├── copy-hooks.ts # Copy selected hooks + inject their deps
|
|
216
|
-
│ │ ├── utils/
|
|
217
|
-
│ │ │ ├── paths.ts # Path resolution, src/ prefix detection
|
|
218
|
-
│ │ │ └── merge-utils.ts # Shared merge utilities
|
|
219
|
-
│ │ └── configs/
|
|
220
|
-
│ │ ├── animations.ts # GSAP and Motion dep declarations
|
|
221
|
-
│ │ └── agents.ts # Agent skill repos per template type
|
|
222
|
-
│ │
|
|
223
|
-
│ ├── templates/ # Full standalone Next.js projects
|
|
224
|
-
│ │ ├── default/ # Base next-starter
|
|
225
|
-
│ │ │ ├── package.json
|
|
226
|
-
│ │ │ ├── _gitignore
|
|
227
|
-
│ │ │ ├── app/
|
|
228
|
-
│ │ │ ├── components/
|
|
229
|
-
│ │ │ ├── lib/
|
|
230
|
-
│ │ │ └── ...
|
|
231
|
-
│ │ ├── webgl/ # next-starter + R3F canvas/scene
|
|
232
|
-
│ │ │ ├── package.json # Includes @react-three/fiber, three, etc.
|
|
233
|
-
│ │ │ ├── _gitignore
|
|
234
|
-
│ │ │ ├── app/page.tsx # WebGL page (not an overlay — the actual file)
|
|
235
|
-
│ │ │ ├── components/webgl/ # Canvas + scene components
|
|
236
|
-
│ │ │ └── ...
|
|
237
|
-
│ │ ├── webgpu/ # next-starter + WebGPU setup
|
|
238
|
-
│ │ │ ├── package.json # Includes alpha R3F, WebGPU deps
|
|
239
|
-
│ │ │ └── ...
|
|
240
|
-
│ │ └── experiment/ # next-starter + experiment nav
|
|
241
|
-
│ │ ├── package.json # Includes experiment deps
|
|
242
|
-
│ │ ├── components/layout/ # Experiment header + nav menu
|
|
243
|
-
│ │ ├── lib/constants.ts
|
|
244
|
-
│ │ └── ...
|
|
245
|
-
│ │
|
|
246
|
-
│ ├── integrations/ # CMS integrations (applied on top of any template)
|
|
247
|
-
│ │ ├── sanity/
|
|
248
|
-
│ │ │ ├── config.ts # Single source of truth: deps, scripts, paths, mergeFiles
|
|
249
|
-
│ │ │ ├── files/ # All Sanity files to copy/merge
|
|
250
|
-
│ │ │ │ ├── app/
|
|
251
|
-
│ │ │ │ │ ├── layout.tsx # Integration version (for merging)
|
|
252
|
-
│ │ │ │ │ ├── sitemap.ts
|
|
253
|
-
│ │ │ │ │ ├── api/
|
|
254
|
-
│ │ │ │ │ └── studio/
|
|
255
|
-
│ │ │ │ ├── components/ui/sanity-image/
|
|
256
|
-
│ │ │ │ └── lib/integrations/sanity/
|
|
257
|
-
│ │ │ └── mergers/ # Sanity-specific merge logic
|
|
258
|
-
│ │ │ ├── layout-merger.ts
|
|
259
|
-
│ │ │ ├── sitemap-merger.ts
|
|
260
|
-
│ │ │ └── check-integration-merger.ts
|
|
261
|
-
│ │ └── basehub/
|
|
262
|
-
│ │ ├── config.ts
|
|
263
|
-
│ │ └── files/
|
|
264
|
-
│ │ └── lib/integrations/basehub/
|
|
265
|
-
│ │
|
|
266
|
-
│ ├── template-hooks/ # Optional hooks (copied during scaffolding)
|
|
267
|
-
│ │ ├── config.ts # Hook metadata: name, file, external deps
|
|
268
|
-
│ │ ├── use-battery.ts
|
|
269
|
-
│ │ ├── use-device-perf.ts
|
|
270
|
-
│ │ ├── use-intersection-observer.ts
|
|
271
|
-
│ │ └── use-media.ts
|
|
272
|
-
│ │
|
|
273
|
-
│ └── plugins/ # Biome Grit lint rules
|
|
274
|
-
│ ├── no-anchor-element.grit
|
|
275
|
-
│ ├── no-relative-parent-imports.grit
|
|
276
|
-
│ └── no-unnecessary-forwardref.grit
|
|
277
|
-
```
|
|
278
|
-
|
|
279
|
-
## Technical Considerations
|
|
280
|
-
|
|
281
|
-
### Bun Workspaces Setup
|
|
282
|
-
|
|
283
|
-
Root `package.json`:
|
|
284
|
-
```json
|
|
285
|
-
{
|
|
286
|
-
"name": "basement-starter-cli",
|
|
287
|
-
"private": true,
|
|
288
|
-
"workspaces": ["packages/*"],
|
|
289
|
-
"scripts": {
|
|
290
|
-
"build": "bun run --filter '*' build",
|
|
291
|
-
"typecheck": "bun run --filter '*' typecheck",
|
|
292
|
-
"lint": "biome check .",
|
|
293
|
-
"lint:fix": "biome check --write ."
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
```
|
|
297
|
-
|
|
298
|
-
### Package Dependencies
|
|
299
|
-
|
|
300
|
-
- `packages/cli` depends on `packages/create-basement-app` via workspace protocol: `"@basementstudio/create-basement-app": "workspace:*"`
|
|
301
|
-
- `packages/create-basement-app` is independently usable: `npx @basementstudio/create-basement-app`
|
|
302
|
-
- Shared dev dependencies (biome, changesets) live at the root
|
|
303
|
-
|
|
304
|
-
### Template Creation Strategy
|
|
305
|
-
|
|
306
|
-
To create the four standalone templates:
|
|
307
|
-
|
|
308
|
-
1. Clone `basementstudio/next-starter#main` as the `default` template
|
|
309
|
-
2. For `webgl`: clone default, apply the current WebGL layer files, add R3F deps to its `package.json`
|
|
310
|
-
3. For `webgpu`: clone default, add WebGPU/alpha deps to its `package.json`, add any WebGPU-specific files
|
|
311
|
-
4. For `experiment`: clone default, apply experiment layer files, add experiment deps
|
|
312
|
-
|
|
313
|
-
After initial creation, each template is maintained independently — no more runtime overlay system for templates.
|
|
314
|
-
|
|
315
|
-
### Integration Application (Preserved)
|
|
316
|
-
|
|
317
|
-
CMS integrations still use the merge approach because they cross-cut all four templates. The difference:
|
|
318
|
-
- **Before:** Downloaded from remote GitHub branches at runtime via tiged
|
|
319
|
-
- **After:** Local files in `create-basement-app/integrations/{cms}/files/`, with merger functions co-located in `integrations/{cms}/mergers/`
|
|
320
|
-
|
|
321
|
-
### Migration Path
|
|
322
|
-
|
|
323
|
-
This is a breaking change for the internal structure but NOT for end users. The `basement` CLI command, its flags, prompts, and generated output must remain identical. The migration should:
|
|
324
|
-
|
|
325
|
-
1. Create the new structure alongside the old one
|
|
326
|
-
2. Move files incrementally
|
|
327
|
-
3. Verify the CLI produces identical output before removing old files
|
|
328
|
-
4. Update changeset config for workspace-aware publishing
|
|
329
|
-
|
|
330
|
-
### Config Manifest Format
|
|
331
|
-
|
|
332
|
-
Each integration config (`integrations/{cms}/config.ts`) should follow this shape:
|
|
333
|
-
|
|
334
|
-
```typescript
|
|
335
|
-
interface IntegrationConfig {
|
|
336
|
-
name: string
|
|
337
|
-
dependencies: Record<string, string>
|
|
338
|
-
devDependencies: Record<string, string>
|
|
339
|
-
scripts: Record<string, string>
|
|
340
|
-
additivePaths: string[] // Files to copy directly
|
|
341
|
-
mergeFiles: { // Files requiring smart merge
|
|
342
|
-
path: string
|
|
343
|
-
merger: () => Promise<MergerFn>
|
|
344
|
-
}[]
|
|
345
|
-
}
|
|
346
|
-
```
|
|
347
|
-
|
|
348
|
-
Similarly, `template-hooks/config.ts`:
|
|
349
|
-
|
|
350
|
-
```typescript
|
|
351
|
-
interface HookConfig {
|
|
352
|
-
name: string // Display name for the prompt
|
|
353
|
-
file: string // Filename
|
|
354
|
-
dependencies: Record<string, string>
|
|
355
|
-
devDependencies?: Record<string, string>
|
|
356
|
-
}
|
|
357
|
-
```
|
|
358
|
-
|
|
359
|
-
## Success Metrics
|
|
360
|
-
|
|
361
|
-
- The `basement` CLI produces byte-identical project output before and after the restructure (verified by diffing generated projects)
|
|
362
|
-
- Each template can be independently installed and run (`cd templates/webgl && bun install && bun dev`)
|
|
363
|
-
- Adding a new template requires creating ONE new directory in `templates/` — no config files, no merger code, no CLI changes
|
|
364
|
-
- Adding a new CMS integration requires creating ONE new directory in `integrations/` with a `config.ts` and `files/` — no changes to CLI or pipeline code
|
|
365
|
-
- Zero hardcoded dependency versions in pipeline code (all from config manifests)
|
|
366
|
-
- Config-filesystem validation catches 100% of mismatches in CI
|
|
367
|
-
- TypeScript strict mode with zero errors across both packages
|
|
368
|
-
|
|
369
|
-
## Open Questions
|
|
370
|
-
|
|
371
|
-
1. **Should `create-basement-app` also be directly invocable via `npx @basementstudio/create-basement-app`?** (Like `create-xmcp-app` is.) This would mean it needs its own interactive prompts, not just exported functions. The xmcp pattern supports this.
|
|
372
|
-
2. **How should templates be kept in sync with upstream `next-starter` changes?** With standalone templates, each one needs to be individually updated when the base starter evolves. Should there be a script or CI job that diffs templates against `next-starter` and flags drift?
|
|
373
|
-
3. **Should the `next-config-merger.js` be integrated or removed?** It's currently orphaned (defined but never called). If Sanity's `next.config.ts` changes are needed, the merger should be registered. If not, it should be deleted.
|
|
374
|
-
4. **Should plugins (Biome Grit rules) live in `create-basement-app` or at the root?** They're copied into generated projects but also used to lint this repo itself.
|
|
375
|
-
5. **Version strategy for workspaces** — Should both packages share a version number or be independently versioned? Independent versioning is more flexible but harder to coordinate.
|