@gallop.software/studio 0.1.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/README.md ADDED
@@ -0,0 +1,158 @@
1
+ # @gallop.software/studio
2
+
3
+ Media manager for Gallop templates. Upload, process, and sync images to Cloudflare R2 CDN.
4
+
5
+ ## Features
6
+
7
+ - **Floating button** in dev mode opens a full-screen media manager
8
+ - **Upload images** with automatic thumbnail generation
9
+ - **Browse folders** with grid and list views
10
+ - **Multi-select** for batch operations
11
+ - **Sync to CDN** (Cloudflare R2) with automatic local cleanup
12
+ - **Blurhash** and dominant color extraction
13
+ - **Meta file** with full TypeScript types
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ npm install @gallop.software/studio
19
+ ```
20
+
21
+ ## Quick Start
22
+
23
+ ### 1. Add StudioProvider to your layout
24
+
25
+ ```tsx
26
+ // src/app/layout.tsx
27
+ import { StudioProvider } from '@gallop.software/studio'
28
+
29
+ export default function RootLayout({ children }) {
30
+ return (
31
+ <html>
32
+ <body>
33
+ {children}
34
+ <StudioProvider />
35
+ </body>
36
+ </html>
37
+ )
38
+ }
39
+ ```
40
+
41
+ ### 2. Create API routes
42
+
43
+ Create these files in your project:
44
+
45
+ ```ts
46
+ // src/app/api/studio/list/route.ts
47
+ export { GET } from '@gallop.software/studio/api/list'
48
+
49
+ // src/app/api/studio/upload/route.ts
50
+ export { POST } from '@gallop.software/studio/api/upload'
51
+
52
+ // src/app/api/studio/delete/route.ts
53
+ export { POST } from '@gallop.software/studio/api/delete'
54
+
55
+ // src/app/api/studio/scan/route.ts
56
+ export { GET } from '@gallop.software/studio/api/scan'
57
+
58
+ // src/app/api/studio/sync/route.ts
59
+ export { POST } from '@gallop.software/studio/api/sync'
60
+
61
+ // src/app/api/studio/reprocess/route.ts
62
+ export { POST } from '@gallop.software/studio/api/reprocess'
63
+ ```
64
+
65
+ ### 3. Configure Cloudflare R2 (optional)
66
+
67
+ Add to your `.env.local`:
68
+
69
+ ```bash
70
+ CLOUDFLARE_R2_ACCOUNT_ID=your_account_id
71
+ CLOUDFLARE_R2_ACCESS_KEY_ID=your_access_key
72
+ CLOUDFLARE_R2_SECRET_ACCESS_KEY=your_secret_key
73
+ CLOUDFLARE_R2_BUCKET_NAME=your_bucket
74
+
75
+ # Default R2 URL or custom CDN domain
76
+ CLOUDFLARE_R2_PUBLIC_URL=https://your-bucket.r2.dev
77
+ ```
78
+
79
+ ### 4. Run your dev server
80
+
81
+ ```bash
82
+ npm run dev
83
+ ```
84
+
85
+ A floating button appears in the bottom-right corner. Click to open Studio.
86
+
87
+ ## Using Images
88
+
89
+ ```tsx
90
+ import { meta, getImageUrl, type ImageSize } from '@gallop.software/studio'
91
+
92
+ // Get image metadata
93
+ const hero = meta.images['hero.jpg']
94
+ console.log(hero.sizes.medium.width) // 700
95
+ console.log(hero.blurhash) // "LEHV6nWB..."
96
+
97
+ // Get resolved URL (handles CDN vs local)
98
+ const url = getImageUrl('hero.jpg', 'medium')
99
+ // → "/images/hero-700.jpg" or "https://cdn.example.com/images/hero-700.jpg"
100
+ ```
101
+
102
+ ## Folder Structure
103
+
104
+ Studio manages these folders:
105
+
106
+ ```
107
+ public/
108
+ ├── originals/ # Source images (uploaded here)
109
+ │ └── hero.jpg
110
+ └── images/ # Generated thumbnails
111
+ ├── hero.jpg # Full size (optimized)
112
+ ├── hero-1400.jpg # Large
113
+ ├── hero-700.jpg # Medium
114
+ └── hero-300.jpg # Small
115
+
116
+ _data/
117
+ └── _meta.json # Image metadata
118
+ ```
119
+
120
+ ## Meta Schema
121
+
122
+ ```json
123
+ {
124
+ "$schema": "https://gallop.software/schemas/studio-meta.json",
125
+ "version": 1,
126
+ "generatedAt": "2026-01-24T12:00:00Z",
127
+ "images": {
128
+ "hero.jpg": {
129
+ "original": {
130
+ "path": "/originals/hero.jpg",
131
+ "width": 2400,
132
+ "height": 1600,
133
+ "fileSize": 1245000
134
+ },
135
+ "sizes": {
136
+ "full": { "path": "/images/hero.jpg", "width": 2400, "height": 1600 },
137
+ "large": { "path": "/images/hero-1400.jpg", "width": 1400, "height": 934 },
138
+ "medium": { "path": "/images/hero-700.jpg", "width": 700, "height": 467 },
139
+ "small": { "path": "/images/hero-300.jpg", "width": 300, "height": 200 }
140
+ },
141
+ "blurhash": "LEHV6nWB2yk8pyo0adR*.7kCMdnj",
142
+ "dominantColor": "#a85c32",
143
+ "cdn": null
144
+ }
145
+ }
146
+ }
147
+ ```
148
+
149
+ ## CDN Workflow
150
+
151
+ 1. Upload image → saves to `originals/`, generates thumbnails
152
+ 2. Click "Sync CDN" → uploads to R2, deletes local files
153
+ 3. `meta.images[key].cdn.synced` becomes `true`
154
+ 4. Image component uses CDN URL automatically
155
+
156
+ ## License
157
+
158
+ MIT