bsmnt 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.changeset/2026-02-11-test-patch-bump.md +5 -0
- package/.changeset/README.md +10 -0
- package/.changeset/config.json +16 -0
- package/.cursor/rules/README.md +184 -0
- package/.cursor/rules/architecture.mdc +437 -0
- package/.cursor/rules/components.mdc +436 -0
- package/.cursor/rules/integrations.mdc +447 -0
- package/.cursor/rules/main.mdc +278 -0
- package/.cursor/rules/styling.mdc +433 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +14 -0
- package/.github/workflows/.gitkeep +0 -0
- package/.github/workflows/ci.yml +37 -0
- package/.github/workflows/release.yml +54 -0
- package/.tldr/cache/call_graph.json +7 -0
- package/.tldr/languages.json +6 -0
- package/.tldr/status +1 -0
- package/.tldrignore +84 -0
- package/.vscode/extensions.json +20 -0
- package/.vscode/settings.json +98 -0
- package/CHANGELOG.md +13 -0
- package/CLAUDE.md +138 -0
- package/README.md +176 -0
- package/bin/index.js +262 -0
- package/biome.json +44 -0
- package/bun.lock +496 -0
- package/changelog/04-02-26.md +86 -0
- package/changelog/05-02-26.md +101 -0
- package/changelog/09-02-26.md +83 -0
- package/docs/fix-studio-hydration.md +46 -0
- package/docs/plans/2026-01-29-sanity-smart-merge-design.md +196 -0
- package/docs/plans/2026-01-29-sanity-smart-merge-implementation.md +695 -0
- package/docs/sanity-setup-steps.md +199 -0
- package/integrations/basehub/README.md +3 -0
- package/integrations/sanity/app/api/draft-mode/disable/route.ts +7 -0
- package/integrations/sanity/app/api/draft-mode/enable/route.ts +21 -0
- package/integrations/sanity/app/api/revalidate/route.ts +37 -0
- package/integrations/sanity/app/layout.tsx +111 -0
- package/integrations/sanity/app/sitemap.ts +80 -0
- package/integrations/sanity/app/studio/[[...tool]]/page.tsx +8 -0
- package/integrations/sanity/app/studio/layout.tsx +7 -0
- package/integrations/sanity/components/ui/sanity-image/index.tsx +37 -0
- package/integrations/sanity/lib/integrations/README.md +58 -0
- package/integrations/sanity/lib/integrations/check-integration.ts +62 -0
- package/integrations/sanity/lib/integrations/sanity/README.md +144 -0
- package/integrations/sanity/lib/integrations/sanity/client.ts +30 -0
- package/integrations/sanity/lib/integrations/sanity/components/disable-draft-mode.tsx +29 -0
- package/integrations/sanity/lib/integrations/sanity/components/rich-text.tsx +73 -0
- package/integrations/sanity/lib/integrations/sanity/env.ts +38 -0
- package/integrations/sanity/lib/integrations/sanity/live/index.tsx +34 -0
- package/integrations/sanity/lib/integrations/sanity/queries.ts +99 -0
- package/integrations/sanity/lib/integrations/sanity/sanity.cli.ts +20 -0
- package/integrations/sanity/lib/integrations/sanity/sanity.config.ts +94 -0
- package/integrations/sanity/lib/integrations/sanity/sanity.types.ts +337 -0
- package/integrations/sanity/lib/integrations/sanity/schema.json +1850 -0
- package/integrations/sanity/lib/integrations/sanity/schemas/article.ts +132 -0
- package/integrations/sanity/lib/integrations/sanity/schemas/example.ts +203 -0
- package/integrations/sanity/lib/integrations/sanity/schemas/index.ts +37 -0
- package/integrations/sanity/lib/integrations/sanity/schemas/link.ts +127 -0
- package/integrations/sanity/lib/integrations/sanity/schemas/metadata.ts +68 -0
- package/integrations/sanity/lib/integrations/sanity/schemas/navigation.ts +39 -0
- package/integrations/sanity/lib/integrations/sanity/schemas/page.ts +77 -0
- package/integrations/sanity/lib/integrations/sanity/schemas/richText.ts +59 -0
- package/integrations/sanity/lib/integrations/sanity/structure.ts +5 -0
- package/integrations/sanity/lib/integrations/sanity/utils/image.ts +11 -0
- package/integrations/sanity/lib/integrations/sanity/utils/link.ts +61 -0
- package/integrations/sanity/lib/scripts/copy-sanity-mcp.ts +23 -0
- package/integrations/sanity/lib/scripts/generate-page.ts +310 -0
- package/integrations/sanity/lib/utils/metadata.ts +190 -0
- package/layers/experiment/components/layout/header/index.tsx +58 -0
- package/layers/experiment/components/layout/navigation-menu.tsx +127 -0
- package/layers/experiment/lib/constants.ts +12 -0
- package/layers/webgl/app/page.tsx +10 -0
- package/layers/webgl/components/webgl/canvas/dynamic.tsx +34 -0
- package/layers/webgl/components/webgl/canvas/index.tsx +43 -0
- package/layers/webgl/components/webgl/components/scene/index.tsx +21 -0
- package/layers/webgpu/.gitkeep +0 -0
- package/package.json +44 -0
- package/plugins/README.md +21 -0
- package/plugins/no-anchor-element.grit +11 -0
- package/plugins/no-relative-parent-imports.grit +6 -0
- package/plugins/no-unnecessary-forwardref.grit +5 -0
- package/src/commands/add-integration.js +325 -0
- package/src/commands/create.js +415 -0
- package/src/commands/setup-sanity.js +426 -0
- package/src/commands/worktree.js +805 -0
- package/src/mergers/check-integration-merger.js +105 -0
- package/src/mergers/config.js +137 -0
- package/src/mergers/index.js +355 -0
- package/src/mergers/layout-merger.js +223 -0
- package/src/mergers/next-config-merger.js +63 -0
- package/src/mergers/sitemap-merger.js +121 -0
- package/tasks/prd-next-starter-dynamic-layers.md +184 -0
- package/tasks/prd.json +153 -0
- package/tasks/progress.txt +115 -0
- package/template-hooks/use-battery.ts +126 -0
- package/template-hooks/use-device-perf.ts +184 -0
- package/template-hooks/use-intersection-observer.ts +32 -0
- package/template-hooks/use-media.ts +33 -0
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [Unreleased] - Worktree Management
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
#### Git Worktree Management (`-w`, `--worktree`)
|
|
8
|
+
|
|
9
|
+
A new CLI mode for managing git worktrees, enabling isolated development environments for parallel feature work.
|
|
10
|
+
|
|
11
|
+
**New Commands:**
|
|
12
|
+
|
|
13
|
+
| Flag | Long Flag | Description |
|
|
14
|
+
|------|-----------|-------------|
|
|
15
|
+
| `-w` | `--worktree` | Interactive worktree menu |
|
|
16
|
+
| `-wc` | `--worktree-create` | Create new worktree(s) |
|
|
17
|
+
| `-wl` | `--worktree-list` | List all worktrees for current project |
|
|
18
|
+
| `-ws` | `--worktree-switch` | Get cd command to switch to a worktree |
|
|
19
|
+
| `-wr` | `--worktree-remove` | Remove a worktree |
|
|
20
|
+
| `-wp` | `--worktree-prune` | Clean up stale worktrees |
|
|
21
|
+
|
|
22
|
+
**Options:**
|
|
23
|
+
|
|
24
|
+
| Flag | Description |
|
|
25
|
+
|------|-------------|
|
|
26
|
+
| `-b=<name>` | Specify branch name (supports comma-separated for multiple) |
|
|
27
|
+
| `-db`, `--delete-branch` | Delete branch when removing worktree |
|
|
28
|
+
| `-f`, `--force` | Skip confirmation prompts |
|
|
29
|
+
|
|
30
|
+
**Features:**
|
|
31
|
+
|
|
32
|
+
- **Multiple worktree creation**: Create several worktrees at once via interactive prompts or comma-separated flag values
|
|
33
|
+
- **Auto-dependency installation**: Detects and installs dependencies based on lock files:
|
|
34
|
+
- `bun.lock` / `bun.lockb` → `bun install`
|
|
35
|
+
- `pnpm-lock.yaml` → `pnpm install`
|
|
36
|
+
- `yarn.lock` → `yarn install`
|
|
37
|
+
- `package.json` (no lock) → `npm install`
|
|
38
|
+
- `Cargo.toml` → `cargo build`
|
|
39
|
+
- `requirements.txt` → `pip install -r requirements.txt`
|
|
40
|
+
- `pyproject.toml` → `poetry install` or `pip install -e .`
|
|
41
|
+
- `go.mod` → `go mod download`
|
|
42
|
+
- **Smart directory structure**: Worktrees stored in `~/.claude/worktrees/<project>/<branch>`
|
|
43
|
+
- **Branch name sanitization**: Converts `feature/auth` to `feature-auth` for directory names
|
|
44
|
+
- **Prune command**: Cleans up stale git references and orphaned directories
|
|
45
|
+
|
|
46
|
+
**Examples:**
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
# Interactive worktree management
|
|
50
|
+
basement -w
|
|
51
|
+
|
|
52
|
+
# Create single worktree
|
|
53
|
+
basement -wc -b=feature/auth
|
|
54
|
+
|
|
55
|
+
# Create multiple worktrees at once
|
|
56
|
+
basement -wc -b=feature/auth,feature/dashboard,fix/bug-123
|
|
57
|
+
|
|
58
|
+
# List all worktrees
|
|
59
|
+
basement -wl
|
|
60
|
+
|
|
61
|
+
# Remove worktree and delete branch
|
|
62
|
+
basement -wr -b=feature/auth -db -f
|
|
63
|
+
|
|
64
|
+
# Clean up stale worktrees
|
|
65
|
+
basement -wp
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Files Added
|
|
69
|
+
|
|
70
|
+
- `src/commands/worktree.js` - Worktree command implementation
|
|
71
|
+
|
|
72
|
+
### Files Modified
|
|
73
|
+
|
|
74
|
+
- `bin/index.js` - Added worktree mode, flags, routing, and help text
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## Previous Releases
|
|
79
|
+
|
|
80
|
+
### Sanity Integration Branch
|
|
81
|
+
|
|
82
|
+
- Added `add-integration` command (`-a`, `--add`)
|
|
83
|
+
- Sanity CMS integration with revalidate API
|
|
84
|
+
- Support for Next.js projects with `src/` directory structure
|
|
85
|
+
- Layout merging for Sanity integration
|
|
86
|
+
- Updated sitemap paths for Sanity content
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# Changelog — February 5, 2026
|
|
2
|
+
|
|
3
|
+
## Sanity Integration Overhaul
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
#### Automated Sanity Project Setup (`setup-sanity.js`)
|
|
8
|
+
|
|
9
|
+
A new 8-step automated setup flow that provisions a Sanity project without leaving the CLI.
|
|
10
|
+
|
|
11
|
+
**Steps performed automatically:**
|
|
12
|
+
1. Verify Sanity CLI is available
|
|
13
|
+
2. Check user authentication (prompts `sanity login` if needed)
|
|
14
|
+
3. Create Sanity project via `sanity projects create`
|
|
15
|
+
4. Create an API read token via the Sanity Management API
|
|
16
|
+
5. Write credentials to `.env.local`
|
|
17
|
+
6. Deploy a CORS origin for `localhost:3000`
|
|
18
|
+
7. Create an initial dataset (`production`)
|
|
19
|
+
8. Display a summary with project ID, dataset, and Studio URL
|
|
20
|
+
|
|
21
|
+
Wired into both `create.js` (step 5.5) and `add-integration.js` (step 7) — if auto-setup is skipped or fails, the CLI falls back to manual credential instructions.
|
|
22
|
+
|
|
23
|
+
#### `add-integration` Command (`-a`, `--add`)
|
|
24
|
+
|
|
25
|
+
Post-scaffold command to inject a CMS integration into an existing Next.js project.
|
|
26
|
+
|
|
27
|
+
- Validates the target is a Next.js App Router project
|
|
28
|
+
- Supports Sanity and BaseHub integrations
|
|
29
|
+
- Automatically injects dependencies, scripts, and CMS files
|
|
30
|
+
- Registers the Sanity MCP server (`claude mcp add`) when Claude Code is detected
|
|
31
|
+
- Installs `sanity-io/agent-toolkit` skills for AI-assisted workflows
|
|
32
|
+
- Conditional next-steps messaging based on whether auto-setup succeeded
|
|
33
|
+
|
|
34
|
+
#### Smart Merge System (`src/mergers/`)
|
|
35
|
+
|
|
36
|
+
CMS-specific file mergers that intelligently inject integration code into existing project files instead of blindly overwriting them.
|
|
37
|
+
|
|
38
|
+
| Merger | File | What it does |
|
|
39
|
+
|--------|------|--------------|
|
|
40
|
+
| `layout-merger.js` | `app/layout.tsx` | Injects Sanity providers, draft-mode components, and imports |
|
|
41
|
+
| `sitemap-merger.js` | `app/sitemap.ts` | Adds Sanity content routes to the sitemap generator |
|
|
42
|
+
| `check-integration-merger.js` | `lib/integrations/check-integration.ts` | Registers Sanity in the integration check map |
|
|
43
|
+
| `config.js` | — | File classification config (merge vs. copy vs. skip) |
|
|
44
|
+
| `index.js` | — | Orchestrator: detects `src/` prefix, resolves mergers, handles fallbacks |
|
|
45
|
+
|
|
46
|
+
**Key features:**
|
|
47
|
+
- Auto-detects `src/` directory structure and adjusts all paths accordingly
|
|
48
|
+
- Downloads integration files from a dedicated branch (`#sanity-integration`)
|
|
49
|
+
- Falls back to direct copy when no merger is defined for a file
|
|
50
|
+
|
|
51
|
+
#### Sanity MCP Server & Agent Toolkit
|
|
52
|
+
|
|
53
|
+
- Registers `https://mcp.sanity.io` as an MCP server during setup (Claude Code projects)
|
|
54
|
+
- Installs `sanity-io/agent-toolkit` skills via `bunx skills add`
|
|
55
|
+
|
|
56
|
+
#### Integration Files (moved to `integrations/sanity/`)
|
|
57
|
+
|
|
58
|
+
Sanity CMS files are now centralized under `integrations/sanity/` instead of being duplicated across all four templates:
|
|
59
|
+
|
|
60
|
+
- `app/studio/[[...tool]]/page.tsx` — Embedded Sanity Studio route
|
|
61
|
+
- `app/studio/layout.tsx` — Studio layout (passthrough, no nested `<html>`)
|
|
62
|
+
- `app/api/revalidate/route.ts` — On-demand ISR revalidation webhook
|
|
63
|
+
- `app/api/draft-mode/{enable,disable}/route.ts` — Draft mode toggle
|
|
64
|
+
- `app/layout.tsx` — Layout with Sanity providers
|
|
65
|
+
- `app/sitemap.ts` — Sitemap with Sanity content routes
|
|
66
|
+
- `lib/integrations/sanity/` — Client, schemas, queries, types, structure
|
|
67
|
+
- `lib/integrations/check-integration.ts` — Integration checker
|
|
68
|
+
- `lib/scripts/generate-page.ts` — Page scaffolding with Sanity schema support
|
|
69
|
+
- `lib/utils/metadata.ts` — Sanity-aware metadata helpers
|
|
70
|
+
- `components/ui/sanity-image/` — Sanity image component
|
|
71
|
+
|
|
72
|
+
### Fixed
|
|
73
|
+
|
|
74
|
+
#### Studio Hydration Errors
|
|
75
|
+
|
|
76
|
+
`app/studio/layout.tsx` previously rendered its own `<html>` and `<body>` tags, causing React hydration mismatches when nested inside the root layout. The layout now passes `children` through directly.
|
|
77
|
+
|
|
78
|
+
### Changed
|
|
79
|
+
|
|
80
|
+
- **Templates cleaned up** — Removed duplicated Sanity files from `template/{default,webgl,webgpu,experiment}/`. Sanity is now injected at build time via the merger system.
|
|
81
|
+
- **Removed `sanity:mcp` script** — The `copy-sanity-mcp.ts` script and its `package.json` entry were removed in favor of direct MCP registration via `claude mcp add`.
|
|
82
|
+
- **`create.js` updated** — Sanity auto-setup (step 5.5), MCP registration (step 5.6), and conditional next-steps messaging added.
|
|
83
|
+
- **`CLAUDE.md` updated** — Added guidance that nested layouts must not render `<html>` or `<body>` tags.
|
|
84
|
+
|
|
85
|
+
### Files Added
|
|
86
|
+
|
|
87
|
+
- `src/commands/setup-sanity.js`
|
|
88
|
+
- `src/commands/add-integration.js`
|
|
89
|
+
- `src/mergers/index.js`
|
|
90
|
+
- `src/mergers/config.js`
|
|
91
|
+
- `src/mergers/layout-merger.js`
|
|
92
|
+
- `src/mergers/sitemap-merger.js`
|
|
93
|
+
- `src/mergers/check-integration-merger.js`
|
|
94
|
+
- `integrations/sanity/` (all CMS files)
|
|
95
|
+
|
|
96
|
+
### Files Modified
|
|
97
|
+
|
|
98
|
+
- `bin/index.js` — Added `--add` / `-a` flag routing
|
|
99
|
+
- `src/commands/create.js` — Sanity auto-setup, MCP registration, agent toolkit
|
|
100
|
+
- `CLAUDE.md` — Nested layout guidance
|
|
101
|
+
- `package.json` — Updated dependencies
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Changelog — February 9, 2026
|
|
2
|
+
|
|
3
|
+
## Dynamic Layer Architecture (next-starter migration)
|
|
4
|
+
|
|
5
|
+
Replaced the duplicated full-template system with a layer-based architecture. The CLI now clones `basementstudio/next-starter` as the base for all project types and overlays technology-specific layers on top, eliminating ~27,000 lines of duplicated code.
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
#### Layer Configuration System (`src/mergers/config.js`)
|
|
10
|
+
|
|
11
|
+
Centralized configuration that defines per-layer dependencies, scripts, and dev dependencies.
|
|
12
|
+
|
|
13
|
+
**Supported layers:**
|
|
14
|
+
|
|
15
|
+
| Layer | Key Dependencies |
|
|
16
|
+
|-------|-----------------|
|
|
17
|
+
| `default` | (base next-starter, no extra deps) |
|
|
18
|
+
| `webgl` | `@react-three/fiber`, `@react-three/drei`, `three`, `@types/three` |
|
|
19
|
+
| `webgpu` | `three` (WebGPU renderer) |
|
|
20
|
+
| `experiment` | (navigation/header components, no extra deps) |
|
|
21
|
+
|
|
22
|
+
Each layer config specifies `dependencies`, `devDependencies`, and `scripts` that get injected into `package.json` during project hydration.
|
|
23
|
+
|
|
24
|
+
#### Layer Files (`layers/`)
|
|
25
|
+
|
|
26
|
+
Technology-specific files extracted from the old full templates into minimal overlay directories:
|
|
27
|
+
|
|
28
|
+
- `layers/webgl/` — Custom `app/page.tsx`, WebGL canvas, and scene components
|
|
29
|
+
- `layers/webgpu/` — `.gitkeep` placeholder (deps-only layer)
|
|
30
|
+
- `layers/experiment/` — Header component, navigation menu, and constants
|
|
31
|
+
|
|
32
|
+
#### Layer Injection Function (`src/mergers/index.js`)
|
|
33
|
+
|
|
34
|
+
New `injectLayer()` function that copies layer-specific files on top of the cloned next-starter base. Handles file overlay with proper path resolution.
|
|
35
|
+
|
|
36
|
+
#### Config-Driven Package Hydration
|
|
37
|
+
|
|
38
|
+
`package.json` hydration now reads dependencies from `LAYER_CONFIG` instead of hardcoding them per template. The `hydratePackageJson()` function in `create.js` merges layer-specific deps, scripts, and devDeps into the base `package.json`.
|
|
39
|
+
|
|
40
|
+
### Changed
|
|
41
|
+
|
|
42
|
+
- **`create.js` — Clone source changed**: All template types now clone from `basementstudio/next-starter#main` instead of per-type template directories. Layer injection happens as a post-clone step.
|
|
43
|
+
- **`create.js` — Template directory deleted after injection**: The CLI cleans up the local `layers/` artifacts from the generated project after overlay.
|
|
44
|
+
- **`bin/index.js` — Command renamed**: Updated CLI command name.
|
|
45
|
+
- **`src/commands/worktree.js`** — Minor update.
|
|
46
|
+
- **`src/mergers/config.js`** — Added `LAYER_CONFIG` export with per-layer dependency maps.
|
|
47
|
+
- **`src/mergers/index.js`** — Added `injectLayer()` alongside existing merger functions.
|
|
48
|
+
|
|
49
|
+
### Removed
|
|
50
|
+
|
|
51
|
+
- **`template/` directory** — Deleted all four full template directories (`default/`, `webgl/`, `webgpu/`, `experiment/`), removing ~27,000 lines of duplicated boilerplate. Each template previously contained a full copy of the next-starter codebase.
|
|
52
|
+
|
|
53
|
+
### Files Added
|
|
54
|
+
|
|
55
|
+
- `layers/webgl/app/page.tsx`
|
|
56
|
+
- `layers/webgl/components/webgl/canvas/dynamic.tsx`
|
|
57
|
+
- `layers/webgl/components/webgl/canvas/index.tsx`
|
|
58
|
+
- `layers/webgl/components/webgl/components/scene/index.tsx`
|
|
59
|
+
- `layers/webgpu/.gitkeep`
|
|
60
|
+
- `layers/experiment/components/layout/header/index.tsx`
|
|
61
|
+
- `layers/experiment/components/layout/navigation-menu.tsx`
|
|
62
|
+
- `layers/experiment/lib/constants.ts`
|
|
63
|
+
- `tasks/prd-next-starter-dynamic-layers.md`
|
|
64
|
+
- `tasks/prd.json`
|
|
65
|
+
- `tasks/progress.txt`
|
|
66
|
+
|
|
67
|
+
### Files Modified
|
|
68
|
+
|
|
69
|
+
- `bin/index.js`
|
|
70
|
+
- `src/commands/create.js`
|
|
71
|
+
- `src/commands/worktree.js`
|
|
72
|
+
- `src/mergers/config.js`
|
|
73
|
+
- `src/mergers/index.js`
|
|
74
|
+
- `CLAUDE.md`
|
|
75
|
+
- `README.md`
|
|
76
|
+
- `package.json`
|
|
77
|
+
|
|
78
|
+
### Files Deleted
|
|
79
|
+
|
|
80
|
+
- `template/default/` (all files)
|
|
81
|
+
- `template/webgl/` (all files)
|
|
82
|
+
- `template/webgpu/` (all files)
|
|
83
|
+
- `template/experiment/` (all files)
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Fix: Studio Hydration Errors
|
|
2
|
+
|
|
3
|
+
## Problem
|
|
4
|
+
|
|
5
|
+
`/studio` route produces two critical React hydration mismatch errors:
|
|
6
|
+
|
|
7
|
+
1. **`<body>` style attribute mismatch** — Server renders inline `style={{margin: 0}}` on a nested `<body>` tag that conflicts with the root layout's `<body>`.
|
|
8
|
+
2. **`<html>` tag attribute mismatch** — `dir`, `className` attributes differ between server and client because a second `<html>` tag is rendered inside the root layout's `<html>`.
|
|
9
|
+
|
|
10
|
+
### Root Cause
|
|
11
|
+
|
|
12
|
+
`app/studio/layout.tsx` renders its own `<html>` and `<body>` tags. In Next.js App Router, nested layouts do **not** replace the root layout — they render **inside** it. This creates duplicate `<html>` and `<body>` elements, causing hydration mismatches.
|
|
13
|
+
|
|
14
|
+
## Fix
|
|
15
|
+
|
|
16
|
+
### File: `app/studio/layout.tsx`
|
|
17
|
+
|
|
18
|
+
**Before:**
|
|
19
|
+
```tsx
|
|
20
|
+
export default function StudioLayout({
|
|
21
|
+
children,
|
|
22
|
+
}: {
|
|
23
|
+
children: React.ReactNode;
|
|
24
|
+
}) {
|
|
25
|
+
return (
|
|
26
|
+
<html lang="en">
|
|
27
|
+
<body style={{ margin: 0 }}>{children}</body>
|
|
28
|
+
</html>
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
**After:**
|
|
34
|
+
```tsx
|
|
35
|
+
export default function StudioLayout({
|
|
36
|
+
children,
|
|
37
|
+
}: {
|
|
38
|
+
children: React.ReactNode;
|
|
39
|
+
}) {
|
|
40
|
+
return children;
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Notes
|
|
45
|
+
|
|
46
|
+
- There is also a `motion() is deprecated. Use motion.create() instead.` warning — this is upstream in the `sanity` package's internal use of framer-motion. No action needed on our end.
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
# Sanity Smart Merge Integration Design
|
|
2
|
+
|
|
3
|
+
> Date: 2026-01-29
|
|
4
|
+
> Status: Approved for implementation
|
|
5
|
+
|
|
6
|
+
## Problem
|
|
7
|
+
|
|
8
|
+
The current Sanity integration uses `tiged` to overlay files directly onto the selected template. This causes template-specific code to be completely overwritten, losing:
|
|
9
|
+
- Template-specific providers and imports in `app/layout.tsx`
|
|
10
|
+
- Template-specific sitemap entries in `app/sitemap.ts`
|
|
11
|
+
- Other integration checks in `lib/integrations/check-integration.ts`
|
|
12
|
+
|
|
13
|
+
## Solution
|
|
14
|
+
|
|
15
|
+
Replace the blind file overlay with a **smart merge system** that:
|
|
16
|
+
1. Copies additive files directly (new directories/files)
|
|
17
|
+
2. Intelligently merges files that exist in both template and integration
|
|
18
|
+
|
|
19
|
+
## Architecture
|
|
20
|
+
|
|
21
|
+
### Current Flow (Broken)
|
|
22
|
+
```
|
|
23
|
+
1. Clone template via tiged
|
|
24
|
+
2. Overlay integration via tiged (OVERWRITES files)
|
|
25
|
+
3. Hydrate package.json
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### New Flow (Smart Merge)
|
|
29
|
+
```
|
|
30
|
+
1. Clone template via tiged → targetDir
|
|
31
|
+
2. Clone integration to TEMP directory (not targetDir)
|
|
32
|
+
3. Process integration files:
|
|
33
|
+
a. ADDITIVE files → copy directly to targetDir
|
|
34
|
+
b. MERGE files → read both versions, merge, write result
|
|
35
|
+
4. Clean up temp directory
|
|
36
|
+
5. Hydrate package.json
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## File Classification
|
|
40
|
+
|
|
41
|
+
### Files Requiring Smart Merge
|
|
42
|
+
| File | Merge Strategy |
|
|
43
|
+
|------|----------------|
|
|
44
|
+
| `app/layout.tsx` | Add imports, variables, and Sanity components after `{children}` |
|
|
45
|
+
| `app/sitemap.ts` | Add imports and Sanity page/article fetching to return array |
|
|
46
|
+
| `lib/integrations/check-integration.ts` | Append `isSanityConfigured()` function |
|
|
47
|
+
|
|
48
|
+
### Additive Files (Direct Copy)
|
|
49
|
+
- `lib/integrations/sanity/` — entire directory
|
|
50
|
+
- `components/ui/sanity-image/` — new component
|
|
51
|
+
- `app/api/draft-mode/` — new API routes
|
|
52
|
+
- `lib/utils/metadata.ts` — new utility
|
|
53
|
+
- `lib/scripts/generate-page.ts` — new script
|
|
54
|
+
|
|
55
|
+
## New File Structure
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
src/
|
|
59
|
+
├── commands/create.js # Updated to use new merge logic
|
|
60
|
+
├── mergers/ # NEW: Smart merge functions
|
|
61
|
+
│ ├── index.js # Orchestrates merging
|
|
62
|
+
│ ├── config.js # File classification config
|
|
63
|
+
│ ├── layout-merger.js # Merges app/layout.tsx
|
|
64
|
+
│ ├── sitemap-merger.js # Merges app/sitemap.ts
|
|
65
|
+
│ └── check-integration-merger.js # Merges check-integration.ts
|
|
66
|
+
└── utils/
|
|
67
|
+
└── file-utils.js # Helper for reading/writing files
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Merge Strategies
|
|
71
|
+
|
|
72
|
+
### Layout Merger (`app/layout.tsx`)
|
|
73
|
+
|
|
74
|
+
**Injected imports:**
|
|
75
|
+
```tsx
|
|
76
|
+
import { draftMode } from 'next/headers'
|
|
77
|
+
import { Suspense } from 'react'
|
|
78
|
+
import { VisualEditing } from 'next-sanity'
|
|
79
|
+
import { SanityLive } from '@/lib/integrations/sanity/live'
|
|
80
|
+
import { isSanityConfigured } from '@/lib/integrations/check-integration'
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
**Injected variables (before return):**
|
|
84
|
+
```tsx
|
|
85
|
+
const isDraftMode = (await draftMode()).isEnabled
|
|
86
|
+
const sanityConfigured = isSanityConfigured()
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
**Injected components (after {children}):**
|
|
90
|
+
```tsx
|
|
91
|
+
{sanityConfigured && isDraftMode && (
|
|
92
|
+
<Suspense fallback={null}>
|
|
93
|
+
<VisualEditing />
|
|
94
|
+
<SanityLive />
|
|
95
|
+
</Suspense>
|
|
96
|
+
)}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Sitemap Merger (`app/sitemap.ts`)
|
|
100
|
+
|
|
101
|
+
**Injected imports:**
|
|
102
|
+
```ts
|
|
103
|
+
import { isSanityConfigured } from '@/lib/integrations/check-integration'
|
|
104
|
+
import { client } from '@/lib/integrations/sanity/client'
|
|
105
|
+
import { ALL_PAGES_SLUGS_QUERY, ALL_ARTICLES_SLUGS_QUERY } from '@/lib/integrations/sanity/queries'
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
**Injected fetch logic (before return):**
|
|
109
|
+
```ts
|
|
110
|
+
let sanityPages: MetadataRoute.Sitemap = []
|
|
111
|
+
|
|
112
|
+
if (isSanityConfigured() && client) {
|
|
113
|
+
const [pages, articles] = await Promise.all([
|
|
114
|
+
client.fetch(ALL_PAGES_SLUGS_QUERY),
|
|
115
|
+
client.fetch(ALL_ARTICLES_SLUGS_QUERY),
|
|
116
|
+
])
|
|
117
|
+
|
|
118
|
+
sanityPages = [
|
|
119
|
+
...pages.map((page) => ({
|
|
120
|
+
url: `${baseUrl}/${page.slug}`,
|
|
121
|
+
lastModified: new Date(page._updatedAt),
|
|
122
|
+
})),
|
|
123
|
+
...articles.map((article) => ({
|
|
124
|
+
url: `${baseUrl}/blog/${article.slug}`,
|
|
125
|
+
lastModified: new Date(article._updatedAt),
|
|
126
|
+
})),
|
|
127
|
+
]
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
**Modified return:**
|
|
132
|
+
```ts
|
|
133
|
+
return [
|
|
134
|
+
...existingEntries,
|
|
135
|
+
...sanityPages,
|
|
136
|
+
]
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Check-Integration Merger
|
|
140
|
+
|
|
141
|
+
**Appended function:**
|
|
142
|
+
```ts
|
|
143
|
+
export function isSanityConfigured(): boolean {
|
|
144
|
+
return Boolean(
|
|
145
|
+
process.env.NEXT_PUBLIC_SANITY_PROJECT_ID &&
|
|
146
|
+
process.env.NEXT_PUBLIC_SANITY_DATASET
|
|
147
|
+
)
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## Error Handling
|
|
152
|
+
|
|
153
|
+
| Scenario | Handling |
|
|
154
|
+
|----------|----------|
|
|
155
|
+
| Template file doesn't exist | Copy from integration instead |
|
|
156
|
+
| Integration file doesn't exist | Skip merge, continue |
|
|
157
|
+
| `{children}` not found in layout | Fallback: append to end of body |
|
|
158
|
+
| No `return` in sitemap | Create new sitemap structure |
|
|
159
|
+
| `isSanityConfigured` already exists | Skip adding function |
|
|
160
|
+
| Template uses different layout function name | Search for default export function |
|
|
161
|
+
|
|
162
|
+
## Dependencies
|
|
163
|
+
|
|
164
|
+
Add to CLI's `package.json`:
|
|
165
|
+
```json
|
|
166
|
+
{
|
|
167
|
+
"dependencies": {
|
|
168
|
+
"ts-morph": "^24.0.0"
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## User Feedback
|
|
174
|
+
|
|
175
|
+
After merging, display:
|
|
176
|
+
```
|
|
177
|
+
✓ Sanity integration added:
|
|
178
|
+
✓ Merged: app/layout.tsx
|
|
179
|
+
✓ Merged: app/sitemap.ts
|
|
180
|
+
✓ Merged: lib/integrations/check-integration.ts
|
|
181
|
+
✓ Added: lib/integrations/sanity/ (14 files)
|
|
182
|
+
✓ Added: components/ui/sanity-image/
|
|
183
|
+
✓ Added: app/api/draft-mode/
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## Implementation Tasks
|
|
187
|
+
|
|
188
|
+
1. Create `src/mergers/` directory structure
|
|
189
|
+
2. Implement `config.js` with file classifications
|
|
190
|
+
3. Implement `layout-merger.js`
|
|
191
|
+
4. Implement `sitemap-merger.js`
|
|
192
|
+
5. Implement `check-integration-merger.js`
|
|
193
|
+
6. Implement `index.js` orchestrator with error handling
|
|
194
|
+
7. Update `src/commands/create.js` to use new merge system
|
|
195
|
+
8. Add `ts-morph` dependency
|
|
196
|
+
9. Test with all 4 templates (default, webgl, webgpu, experiment)
|