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.
Files changed (98) hide show
  1. package/.changeset/2026-02-11-test-patch-bump.md +5 -0
  2. package/.changeset/README.md +10 -0
  3. package/.changeset/config.json +16 -0
  4. package/.cursor/rules/README.md +184 -0
  5. package/.cursor/rules/architecture.mdc +437 -0
  6. package/.cursor/rules/components.mdc +436 -0
  7. package/.cursor/rules/integrations.mdc +447 -0
  8. package/.cursor/rules/main.mdc +278 -0
  9. package/.cursor/rules/styling.mdc +433 -0
  10. package/.github/PULL_REQUEST_TEMPLATE.md +14 -0
  11. package/.github/workflows/.gitkeep +0 -0
  12. package/.github/workflows/ci.yml +37 -0
  13. package/.github/workflows/release.yml +54 -0
  14. package/.tldr/cache/call_graph.json +7 -0
  15. package/.tldr/languages.json +6 -0
  16. package/.tldr/status +1 -0
  17. package/.tldrignore +84 -0
  18. package/.vscode/extensions.json +20 -0
  19. package/.vscode/settings.json +98 -0
  20. package/CHANGELOG.md +13 -0
  21. package/CLAUDE.md +138 -0
  22. package/README.md +176 -0
  23. package/bin/index.js +262 -0
  24. package/biome.json +44 -0
  25. package/bun.lock +496 -0
  26. package/changelog/04-02-26.md +86 -0
  27. package/changelog/05-02-26.md +101 -0
  28. package/changelog/09-02-26.md +83 -0
  29. package/docs/fix-studio-hydration.md +46 -0
  30. package/docs/plans/2026-01-29-sanity-smart-merge-design.md +196 -0
  31. package/docs/plans/2026-01-29-sanity-smart-merge-implementation.md +695 -0
  32. package/docs/sanity-setup-steps.md +199 -0
  33. package/integrations/basehub/README.md +3 -0
  34. package/integrations/sanity/app/api/draft-mode/disable/route.ts +7 -0
  35. package/integrations/sanity/app/api/draft-mode/enable/route.ts +21 -0
  36. package/integrations/sanity/app/api/revalidate/route.ts +37 -0
  37. package/integrations/sanity/app/layout.tsx +111 -0
  38. package/integrations/sanity/app/sitemap.ts +80 -0
  39. package/integrations/sanity/app/studio/[[...tool]]/page.tsx +8 -0
  40. package/integrations/sanity/app/studio/layout.tsx +7 -0
  41. package/integrations/sanity/components/ui/sanity-image/index.tsx +37 -0
  42. package/integrations/sanity/lib/integrations/README.md +58 -0
  43. package/integrations/sanity/lib/integrations/check-integration.ts +62 -0
  44. package/integrations/sanity/lib/integrations/sanity/README.md +144 -0
  45. package/integrations/sanity/lib/integrations/sanity/client.ts +30 -0
  46. package/integrations/sanity/lib/integrations/sanity/components/disable-draft-mode.tsx +29 -0
  47. package/integrations/sanity/lib/integrations/sanity/components/rich-text.tsx +73 -0
  48. package/integrations/sanity/lib/integrations/sanity/env.ts +38 -0
  49. package/integrations/sanity/lib/integrations/sanity/live/index.tsx +34 -0
  50. package/integrations/sanity/lib/integrations/sanity/queries.ts +99 -0
  51. package/integrations/sanity/lib/integrations/sanity/sanity.cli.ts +20 -0
  52. package/integrations/sanity/lib/integrations/sanity/sanity.config.ts +94 -0
  53. package/integrations/sanity/lib/integrations/sanity/sanity.types.ts +337 -0
  54. package/integrations/sanity/lib/integrations/sanity/schema.json +1850 -0
  55. package/integrations/sanity/lib/integrations/sanity/schemas/article.ts +132 -0
  56. package/integrations/sanity/lib/integrations/sanity/schemas/example.ts +203 -0
  57. package/integrations/sanity/lib/integrations/sanity/schemas/index.ts +37 -0
  58. package/integrations/sanity/lib/integrations/sanity/schemas/link.ts +127 -0
  59. package/integrations/sanity/lib/integrations/sanity/schemas/metadata.ts +68 -0
  60. package/integrations/sanity/lib/integrations/sanity/schemas/navigation.ts +39 -0
  61. package/integrations/sanity/lib/integrations/sanity/schemas/page.ts +77 -0
  62. package/integrations/sanity/lib/integrations/sanity/schemas/richText.ts +59 -0
  63. package/integrations/sanity/lib/integrations/sanity/structure.ts +5 -0
  64. package/integrations/sanity/lib/integrations/sanity/utils/image.ts +11 -0
  65. package/integrations/sanity/lib/integrations/sanity/utils/link.ts +61 -0
  66. package/integrations/sanity/lib/scripts/copy-sanity-mcp.ts +23 -0
  67. package/integrations/sanity/lib/scripts/generate-page.ts +310 -0
  68. package/integrations/sanity/lib/utils/metadata.ts +190 -0
  69. package/layers/experiment/components/layout/header/index.tsx +58 -0
  70. package/layers/experiment/components/layout/navigation-menu.tsx +127 -0
  71. package/layers/experiment/lib/constants.ts +12 -0
  72. package/layers/webgl/app/page.tsx +10 -0
  73. package/layers/webgl/components/webgl/canvas/dynamic.tsx +34 -0
  74. package/layers/webgl/components/webgl/canvas/index.tsx +43 -0
  75. package/layers/webgl/components/webgl/components/scene/index.tsx +21 -0
  76. package/layers/webgpu/.gitkeep +0 -0
  77. package/package.json +44 -0
  78. package/plugins/README.md +21 -0
  79. package/plugins/no-anchor-element.grit +11 -0
  80. package/plugins/no-relative-parent-imports.grit +6 -0
  81. package/plugins/no-unnecessary-forwardref.grit +5 -0
  82. package/src/commands/add-integration.js +325 -0
  83. package/src/commands/create.js +415 -0
  84. package/src/commands/setup-sanity.js +426 -0
  85. package/src/commands/worktree.js +805 -0
  86. package/src/mergers/check-integration-merger.js +105 -0
  87. package/src/mergers/config.js +137 -0
  88. package/src/mergers/index.js +355 -0
  89. package/src/mergers/layout-merger.js +223 -0
  90. package/src/mergers/next-config-merger.js +63 -0
  91. package/src/mergers/sitemap-merger.js +121 -0
  92. package/tasks/prd-next-starter-dynamic-layers.md +184 -0
  93. package/tasks/prd.json +153 -0
  94. package/tasks/progress.txt +115 -0
  95. package/template-hooks/use-battery.ts +126 -0
  96. package/template-hooks/use-device-perf.ts +184 -0
  97. package/template-hooks/use-intersection-observer.ts +32 -0
  98. 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)