@gallop.software/studio 1.6.5 → 1.6.6

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 (2) hide show
  1. package/bin/studio.mjs +143 -5
  2. package/package.json +7 -2
package/bin/studio.mjs CHANGED
@@ -1,7 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { resolve } from 'path'
4
- import { existsSync } from 'fs'
3
+ import { spawn } from 'child_process'
4
+ import { resolve, dirname, join } from 'path'
5
+ import { fileURLToPath } from 'url'
6
+ import { existsSync, mkdirSync, cpSync, symlinkSync, rmSync, writeFileSync } from 'fs'
7
+ import { tmpdir } from 'os'
8
+
9
+ const __filename = fileURLToPath(import.meta.url)
10
+ const __dirname = dirname(__filename)
5
11
 
6
12
  // Parse command line arguments
7
13
  const args = process.argv.slice(2)
@@ -58,6 +64,138 @@ console.log(`
58
64
  └─────────────────────────────────────┘
59
65
  `)
60
66
 
61
- // Placeholder for Stage 6 - will launch Next.js dev server
62
- console.log('Server launching will be implemented in Stage 6.')
63
- console.log('For now, run the embedded version with npm run dev.')
67
+ // Set up paths
68
+ const studioRoot = resolve(__dirname, '..')
69
+ const tempDir = join(tmpdir(), 'gallop-studio-' + Date.now())
70
+
71
+ // Clean up any old temp directories
72
+ const tempBase = join(tmpdir(), 'gallop-studio-')
73
+ // Note: We don't clean up old dirs here to avoid race conditions with other instances
74
+
75
+ // Create temp directory
76
+ mkdirSync(tempDir, { recursive: true })
77
+
78
+ console.log('Setting up Studio...')
79
+
80
+ // Copy app files to temp directory
81
+ cpSync(join(studioRoot, 'app'), join(tempDir, 'app'), { recursive: true })
82
+
83
+ // Move next.config.mjs from app/ to root of temp dir
84
+ const nextConfigSrc = join(tempDir, 'app', 'next.config.mjs')
85
+ const nextConfigDest = join(tempDir, 'next.config.mjs')
86
+ if (existsSync(nextConfigSrc)) {
87
+ cpSync(nextConfigSrc, nextConfigDest)
88
+ rmSync(nextConfigSrc)
89
+ }
90
+
91
+ // Create package.json for the temp app
92
+ const packageJson = {
93
+ name: 'studio-standalone',
94
+ private: true,
95
+ type: 'module',
96
+ }
97
+ writeFileSync(join(tempDir, 'package.json'), JSON.stringify(packageJson, null, 2))
98
+
99
+ // Create tsconfig.json for TypeScript support
100
+ const tsconfig = {
101
+ compilerOptions: {
102
+ target: 'ES2020',
103
+ lib: ['ES2020', 'DOM', 'DOM.Iterable'],
104
+ module: 'ESNext',
105
+ moduleResolution: 'bundler',
106
+ jsx: 'preserve',
107
+ jsxImportSource: '@emotion/react',
108
+ strict: true,
109
+ noEmit: true,
110
+ esModuleInterop: true,
111
+ skipLibCheck: true,
112
+ forceConsistentCasingInFileNames: true,
113
+ resolveJsonModule: true,
114
+ isolatedModules: true,
115
+ allowJs: true,
116
+ },
117
+ include: ['app/**/*'],
118
+ exclude: ['node_modules'],
119
+ }
120
+ writeFileSync(join(tempDir, 'tsconfig.json'), JSON.stringify(tsconfig, null, 2))
121
+
122
+ // Symlink node_modules from studioRoot
123
+ const nodeModulesSource = join(studioRoot, 'node_modules')
124
+ const nodeModulesTarget = join(tempDir, 'node_modules')
125
+
126
+ try {
127
+ symlinkSync(nodeModulesSource, nodeModulesTarget, 'junction')
128
+ } catch (e) {
129
+ // If symlink fails (e.g., on some Windows configs), fall back to copying
130
+ console.log('Creating node_modules link...')
131
+ cpSync(nodeModulesSource, nodeModulesTarget, { recursive: true })
132
+ }
133
+
134
+ // Find the next binary
135
+ const nextBin = join(nodeModulesTarget, '.bin', 'next')
136
+
137
+ if (!existsSync(nextBin)) {
138
+ console.error('Error: Next.js not found in Studio package.')
139
+ console.error('This is likely a package installation issue.')
140
+ rmSync(tempDir, { recursive: true, force: true })
141
+ process.exit(1)
142
+ }
143
+
144
+ // Set up environment
145
+ const env = {
146
+ ...process.env,
147
+ STUDIO_WORKSPACE: workspace,
148
+ NODE_ENV: 'development',
149
+ }
150
+
151
+ // Start Next.js dev server from temp directory
152
+ const child = spawn(nextBin, ['dev', '-p', '3001'], {
153
+ stdio: 'inherit',
154
+ cwd: tempDir,
155
+ env,
156
+ })
157
+
158
+ // Open browser if requested
159
+ if (shouldOpen) {
160
+ setTimeout(async () => {
161
+ try {
162
+ const open = (await import('open')).default
163
+ open('http://localhost:3001')
164
+ } catch {
165
+ // open package might not be available
166
+ }
167
+ }, 3000)
168
+ }
169
+
170
+ // Handle process termination
171
+ const cleanup = () => {
172
+ child.kill('SIGINT')
173
+ // Clean up temp directory
174
+ setTimeout(() => {
175
+ try {
176
+ rmSync(tempDir, { recursive: true, force: true })
177
+ } catch {
178
+ // Ignore cleanup errors
179
+ }
180
+ }, 1000)
181
+ }
182
+
183
+ process.on('SIGINT', () => {
184
+ cleanup()
185
+ process.exit(0)
186
+ })
187
+
188
+ process.on('SIGTERM', () => {
189
+ cleanup()
190
+ process.exit(0)
191
+ })
192
+
193
+ child.on('close', (code) => {
194
+ // Clean up temp directory
195
+ try {
196
+ rmSync(tempDir, { recursive: true, force: true })
197
+ } catch {
198
+ // Ignore cleanup errors
199
+ }
200
+ process.exit(code || 0)
201
+ })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gallop.software/studio",
3
- "version": "1.6.5",
3
+ "version": "1.6.6",
4
4
  "description": "Media manager for Gallop templates - upload, process, and sync images to CDN",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -61,8 +61,13 @@
61
61
  "@emotion/react": "^11.14.0",
62
62
  "blurhash": "^2.0.5",
63
63
  "clsx": "^2.1.1",
64
+ "next": "^15.1.0",
65
+ "open": "^10.1.0",
66
+ "react": "^19.0.0",
67
+ "react-dom": "^19.0.0",
64
68
  "react-dropzone": "^14.3.5",
65
- "sharp": "^0.33.5"
69
+ "sharp": "^0.33.5",
70
+ "typescript": "^5.7.2"
66
71
  },
67
72
  "devDependencies": {
68
73
  "@types/node": "^22.10.5",