create-murasaki 0.0.2 → 0.0.4

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/index.mjs CHANGED
@@ -7,6 +7,7 @@ import { existsSync } from 'node:fs'
7
7
  import { dirname, join, resolve } from 'node:path'
8
8
  import { fileURLToPath } from 'node:url'
9
9
  import { createInterface } from 'node:readline/promises'
10
+ import { spawnSync } from 'node:child_process'
10
11
 
11
12
  // ── ANSI truecolor (Oomurasaki palette) ────────────────────────────────
12
13
  const BRIGHT = '\x1b[38;2;168;85;247m'
@@ -106,6 +107,31 @@ function isValidPackageName(name) {
106
107
  return /^[a-z0-9][a-z0-9._-]*$/.test(name)
107
108
  }
108
109
 
110
+ // ── Package manager detection ─────────────────────────────────────────
111
+ function detectPackageManager() {
112
+ const ua = process.env.npm_config_user_agent || ''
113
+ if (ua.startsWith('pnpm')) return 'pnpm'
114
+ if (ua.startsWith('yarn')) return 'yarn'
115
+ if (ua.startsWith('bun')) return 'bun'
116
+ return 'npm'
117
+ }
118
+
119
+ function installArgs(pm) {
120
+ // pnpm respects parent workspace by default; --ignore-workspace makes the
121
+ // new app's install self-contained even when scaffolded inside a workspace.
122
+ if (pm === 'pnpm') return ['install', '--ignore-workspace']
123
+ return ['install']
124
+ }
125
+
126
+ function runInstall(targetDir, pm) {
127
+ const result = spawnSync(pm, installArgs(pm), {
128
+ cwd: targetDir,
129
+ stdio: 'inherit',
130
+ shell: process.platform === 'win32',
131
+ })
132
+ return result.status === 0
133
+ }
134
+
109
135
  async function promptForName() {
110
136
  const rl = createInterface({ input: process.stdin, output: process.stdout })
111
137
  const answer = await rl.question(` ${c(DEEP)}?${c(RESET)} ${c(BOLD)}Project name${c(RESET)} ${c(DIM)}(my-app):${c(RESET)} `)
@@ -143,12 +169,28 @@ async function scaffold(projectName) {
143
169
 
144
170
  log(` ${c(GREEN)}${c(BOLD)}✓${c(RESET)} Created ${c(BOLD)}${projectName}/${c(RESET)}`)
145
171
 
172
+ // Install dependencies (Next.js-like behavior)
173
+ const pm = detectPackageManager()
174
+ const skip = process.argv.includes('--skip-install')
175
+
176
+ if (!skip) {
177
+ log(` ${c(DIM)}○${c(RESET)} Installing dependencies with ${c(BOLD)}${pm}${c(RESET)}...\n`)
178
+ const installStart = Date.now()
179
+ const ok = runInstall(targetDir, pm)
180
+ const elapsed = ((Date.now() - installStart) / 1000).toFixed(1)
181
+ if (ok) {
182
+ log(`\n ${c(GREEN)}${c(BOLD)}✓${c(RESET)} Dependencies installed ${c(DIM)}(${elapsed}s)${c(RESET)}`)
183
+ } else {
184
+ log(`\n ${c(RED)}✗${c(RESET)} ${pm} install failed; run ${c(BOLD)}${pm} install${c(RESET)} manually inside ${c(BOLD)}${projectName}/${c(RESET)}`)
185
+ }
186
+ }
187
+
146
188
  // Next steps
189
+ const runner = pm === 'npm' ? 'npm run dev' : `${pm} dev`
147
190
  log(`
148
191
  ${c(DIM)}Next:${c(RESET)}
149
192
  ${c(BRIGHT)}cd${c(RESET)} ${projectName}
150
- ${c(BRIGHT)}npm install${c(RESET)} ${c(DIM)}# or pnpm install${c(RESET)}
151
- ${c(BRIGHT)}npm run dev${c(RESET)} ${c(DIM)}# starts the desktop window with HMR${c(RESET)}
193
+ ${c(BRIGHT)}${runner}${c(RESET)} ${c(DIM)}# starts the desktop window with HMR${c(RESET)}
152
194
 
153
195
  ${c(DIM)}docs${c(RESET)} ${c(DIM)}https://github.com/murasakijs/murasaki${c(RESET)}
154
196
  `)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-murasaki",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "description": "Scaffolder for Murasaki apps. Run with `npm create murasaki@latest`.",
5
5
  "keywords": [
6
6
  "murasaki",
@@ -7,7 +7,7 @@
7
7
  "dev": "murasaki dev"
8
8
  },
9
9
  "dependencies": {
10
- "murasaki": "^0.0.1",
10
+ "murasaki": "^0.0.2",
11
11
  "react": "^19.2.7",
12
12
  "react-dom": "^19.2.7"
13
13
  },