@dwizi/create-dzx 0.1.9 → 0.1.11
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/bin/index.js +51 -162
- package/package.json +9 -2
package/bin/index.js
CHANGED
|
@@ -1,28 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
2
|
import fs from "node:fs";
|
|
4
3
|
import path from "node:path";
|
|
5
4
|
import { fileURLToPath } from "node:url";
|
|
6
5
|
import * as clack from "@clack/prompts";
|
|
7
|
-
|
|
8
6
|
const TEMPLATES = ["basic", "tools-only", "full"];
|
|
9
7
|
const RUNTIMES = ["node", "deno"];
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Normalize a string into a filesystem-safe slug.
|
|
13
|
-
*/
|
|
14
8
|
function slugify(value) {
|
|
15
|
-
return value
|
|
16
|
-
.toLowerCase()
|
|
17
|
-
.replace(/[^a-z0-9-_]/g, "-")
|
|
18
|
-
.replace(/--+/g, "-")
|
|
19
|
-
.replace(/^-+/, "")
|
|
20
|
-
.replace(/-+$/, "");
|
|
9
|
+
return value.toLowerCase().replace(/[^a-z0-9-_]/g, "-").replace(/--+/g, "-").replace(/^-+/, "").replace(/-+$/, "");
|
|
21
10
|
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Parse CLI argv into a simple key/value map.
|
|
25
|
-
*/
|
|
26
11
|
function parseArgs(argv) {
|
|
27
12
|
const args = { positional: [] };
|
|
28
13
|
for (let i = 0; i < argv.length; i += 1) {
|
|
@@ -42,23 +27,13 @@ function parseArgs(argv) {
|
|
|
42
27
|
}
|
|
43
28
|
return args;
|
|
44
29
|
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Return true when the directory is missing or empty.
|
|
48
|
-
*/
|
|
49
30
|
function isEmptyDir(dir) {
|
|
50
31
|
if (!fs.existsSync(dir)) return true;
|
|
51
32
|
return fs.readdirSync(dir).length === 0;
|
|
52
33
|
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Recursively list files relative to the base directory.
|
|
56
|
-
*/
|
|
57
34
|
function listFiles(dir, baseDir = dir) {
|
|
58
35
|
if (!fs.existsSync(dir)) return [];
|
|
59
|
-
const entries = fs
|
|
60
|
-
.readdirSync(dir, { withFileTypes: true })
|
|
61
|
-
.sort((a, b) => a.name.localeCompare(b.name));
|
|
36
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
|
|
62
37
|
const files = [];
|
|
63
38
|
for (const entry of entries) {
|
|
64
39
|
const entryPath = path.join(dir, entry.name);
|
|
@@ -70,10 +45,6 @@ function listFiles(dir, baseDir = dir) {
|
|
|
70
45
|
}
|
|
71
46
|
return files;
|
|
72
47
|
}
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Copy a directory recursively.
|
|
76
|
-
*/
|
|
77
48
|
function copyDir(src, dest) {
|
|
78
49
|
fs.mkdirSync(dest, { recursive: true });
|
|
79
50
|
const entries = fs.readdirSync(src, { withFileTypes: true });
|
|
@@ -87,25 +58,18 @@ function copyDir(src, dest) {
|
|
|
87
58
|
}
|
|
88
59
|
}
|
|
89
60
|
}
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Detect package manager from lockfiles or environment.
|
|
93
|
-
*/
|
|
94
61
|
function detectPackageManager(cwd) {
|
|
95
62
|
const lockfiles = {
|
|
96
63
|
"pnpm-lock.yaml": "pnpm",
|
|
97
64
|
"package-lock.json": "npm",
|
|
98
65
|
"yarn.lock": "yarn",
|
|
99
|
-
"bun.lockb": "bun"
|
|
66
|
+
"bun.lockb": "bun"
|
|
100
67
|
};
|
|
101
|
-
|
|
102
68
|
for (const [lockfile, pm] of Object.entries(lockfiles)) {
|
|
103
69
|
if (fs.existsSync(path.join(cwd, lockfile))) {
|
|
104
70
|
return pm;
|
|
105
71
|
}
|
|
106
72
|
}
|
|
107
|
-
|
|
108
|
-
// Check parent directories (monorepo context)
|
|
109
73
|
let current = cwd;
|
|
110
74
|
for (let i = 0; i < 5; i++) {
|
|
111
75
|
const parent = path.dirname(current);
|
|
@@ -117,21 +81,16 @@ function detectPackageManager(cwd) {
|
|
|
117
81
|
}
|
|
118
82
|
current = parent;
|
|
119
83
|
}
|
|
120
|
-
|
|
121
|
-
// Default to pnpm
|
|
122
84
|
return "pnpm";
|
|
123
85
|
}
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* Get install command for a package manager.
|
|
127
|
-
*/
|
|
128
86
|
function getInstallCommand(pm) {
|
|
129
87
|
return `${pm} install`;
|
|
130
88
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
89
|
+
function getRunCommand(pm, script) {
|
|
90
|
+
if (pm === "pnpm" || pm === "yarn") return `${pm} ${script}`;
|
|
91
|
+
if (pm === "bun") return `${pm} run ${script}`;
|
|
92
|
+
return `${pm} run ${script}`;
|
|
93
|
+
}
|
|
135
94
|
async function runCommand(command, cwd) {
|
|
136
95
|
const { spawn } = await import("node:child_process");
|
|
137
96
|
return new Promise((resolve, reject) => {
|
|
@@ -143,141 +102,101 @@ async function runCommand(command, cwd) {
|
|
|
143
102
|
});
|
|
144
103
|
});
|
|
145
104
|
}
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* Resolve the templates directory for create-dzx.
|
|
149
|
-
*/
|
|
150
105
|
function resolveTemplatesRoot() {
|
|
151
106
|
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
152
107
|
const localTemplatesRoot = path.resolve(here, "..", "templates");
|
|
153
108
|
if (fs.existsSync(localTemplatesRoot)) return localTemplatesRoot;
|
|
154
|
-
// Fallback for when installed as npm package
|
|
155
109
|
return path.resolve(process.cwd(), "node_modules", "create-dzx", "templates");
|
|
156
110
|
}
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
* Color utilities for terminal output.
|
|
160
|
-
*/
|
|
161
111
|
const useColor = Boolean(process.stdout.isTTY);
|
|
162
112
|
function color(code) {
|
|
163
|
-
return (text) =>
|
|
113
|
+
return (text) => useColor ? `\x1B[${code}m${text}\x1B[0m` : text;
|
|
164
114
|
}
|
|
165
|
-
|
|
166
115
|
const colorize = {
|
|
167
116
|
green: color("32"),
|
|
168
117
|
cyan: color("36"),
|
|
169
118
|
blue: color("34"),
|
|
170
119
|
gray: color("90"),
|
|
171
120
|
bold: color("1"),
|
|
172
|
-
dim: color("2")
|
|
121
|
+
dim: color("2")
|
|
173
122
|
};
|
|
174
|
-
|
|
175
123
|
const symbols = {
|
|
176
|
-
check: useColor ? "
|
|
177
|
-
step: useColor ? "
|
|
178
|
-
brand: useColor ? "
|
|
124
|
+
check: useColor ? "\u2714" : "OK",
|
|
125
|
+
step: useColor ? "\u25CF" : "*",
|
|
126
|
+
brand: useColor ? "\u25B2" : ">"
|
|
179
127
|
};
|
|
180
|
-
|
|
181
|
-
/**
|
|
182
|
-
* Create a terminal spinner controller.
|
|
183
|
-
*/
|
|
184
128
|
function createSpinner(enabled) {
|
|
185
|
-
const frames = ["
|
|
129
|
+
const frames = ["\u25D0", "\u25D3", "\u25D1", "\u25D2"];
|
|
186
130
|
let timer = null;
|
|
187
131
|
let message = "";
|
|
188
132
|
let frameIndex = 0;
|
|
189
|
-
|
|
190
133
|
const clearLine = () => {
|
|
191
134
|
if (!enabled) return;
|
|
192
|
-
process.stdout.write("\r\
|
|
135
|
+
process.stdout.write("\r\x1B[2K");
|
|
193
136
|
};
|
|
194
|
-
|
|
195
137
|
const render = () => {
|
|
196
138
|
if (!enabled) return;
|
|
197
139
|
const frame = frames[frameIndex % frames.length];
|
|
198
140
|
frameIndex += 1;
|
|
199
141
|
process.stdout.write(`\r${colorize.gray(frame)} ${message}`);
|
|
200
142
|
};
|
|
201
|
-
|
|
202
143
|
const start = (nextMessage) => {
|
|
203
144
|
message = nextMessage;
|
|
204
145
|
if (!enabled || timer) return;
|
|
205
146
|
render();
|
|
206
147
|
timer = setInterval(render, 80);
|
|
207
148
|
};
|
|
208
|
-
|
|
209
149
|
const update = (nextMessage) => {
|
|
210
150
|
message = nextMessage;
|
|
211
151
|
if (!enabled || !timer) return;
|
|
212
152
|
render();
|
|
213
153
|
};
|
|
214
|
-
|
|
215
154
|
const pause = () => {
|
|
216
155
|
if (!enabled || !timer) return;
|
|
217
156
|
clearInterval(timer);
|
|
218
157
|
timer = null;
|
|
219
158
|
clearLine();
|
|
220
159
|
};
|
|
221
|
-
|
|
222
160
|
const resume = () => {
|
|
223
161
|
if (!enabled || timer || !message) return;
|
|
224
162
|
render();
|
|
225
163
|
timer = setInterval(render, 80);
|
|
226
164
|
};
|
|
227
|
-
|
|
228
165
|
const stop = () => {
|
|
229
166
|
pause();
|
|
230
167
|
message = "";
|
|
231
168
|
};
|
|
232
|
-
|
|
233
169
|
return { start, update, pause, resume, stop, isEnabled: enabled };
|
|
234
170
|
}
|
|
235
|
-
|
|
236
|
-
/**
|
|
237
|
-
* Print a aligned key/value summary list.
|
|
238
|
-
*/
|
|
239
171
|
function printKeyValueList(items) {
|
|
240
172
|
if (items.length === 0) return;
|
|
241
173
|
const maxLabel = items.reduce((max, item) => Math.max(max, item.label.length), 0);
|
|
242
174
|
for (const item of items) {
|
|
243
175
|
const padded = item.label.padEnd(maxLabel);
|
|
244
|
-
// eslint-disable-next-line no-console
|
|
245
176
|
console.log(
|
|
246
|
-
`${colorize.gray(symbols.step)} ${colorize.gray(padded)} : ${colorize.cyan(item.value)}
|
|
177
|
+
`${colorize.gray(symbols.step)} ${colorize.gray(padded)} : ${colorize.cyan(item.value)}`
|
|
247
178
|
);
|
|
248
179
|
}
|
|
249
180
|
}
|
|
250
|
-
|
|
251
|
-
/**
|
|
252
|
-
* Get the latest version of @dwizi/dzx from npm registry.
|
|
253
|
-
*/
|
|
254
181
|
async function getDzxVersion() {
|
|
255
182
|
try {
|
|
256
|
-
const {
|
|
257
|
-
const
|
|
258
|
-
const
|
|
259
|
-
|
|
183
|
+
const { createRequire } = await import("node:module");
|
|
184
|
+
const require2 = createRequire(import.meta.url);
|
|
185
|
+
const dzxPkgJsonPath = require2.resolve("@dwizi/dzx/package.json", { paths: [process.cwd()] });
|
|
186
|
+
const dzxPkg = JSON.parse(fs.readFileSync(dzxPkgJsonPath, "utf8"));
|
|
187
|
+
if (dzxPkg && typeof dzxPkg.version === "string" && dzxPkg.version.trim()) {
|
|
188
|
+
return dzxPkg.version.trim();
|
|
189
|
+
}
|
|
260
190
|
} catch {
|
|
261
|
-
// Fallback version if npm query fails
|
|
262
|
-
return "latest";
|
|
263
191
|
}
|
|
192
|
+
return "*";
|
|
264
193
|
}
|
|
265
|
-
|
|
266
|
-
/**
|
|
267
|
-
* Main scaffolding function.
|
|
268
|
-
*/
|
|
269
194
|
async function main() {
|
|
270
195
|
const args = parseArgs(process.argv.slice(2));
|
|
271
|
-
const force =
|
|
272
|
-
const isYes =
|
|
273
|
-
const shouldInstall = args.install
|
|
274
|
-
|
|
275
|
-
: args["no-install"]
|
|
276
|
-
? false
|
|
277
|
-
: true; // Default to installing for scaffold mode
|
|
278
|
-
|
|
279
|
-
if (args.help || args.h) {
|
|
280
|
-
// eslint-disable-next-line no-console
|
|
196
|
+
const force = args.force === true;
|
|
197
|
+
const isYes = args.yes === true;
|
|
198
|
+
const shouldInstall = args.install === true ? true : args["no-install"] !== true;
|
|
199
|
+
if (args.help === true || args.h === true) {
|
|
281
200
|
console.log(`
|
|
282
201
|
${colorize.blue(symbols.brand)} ${colorize.bold("create-dzx")}
|
|
283
202
|
|
|
@@ -294,17 +213,14 @@ ${colorize.bold("Options")}
|
|
|
294
213
|
`);
|
|
295
214
|
return;
|
|
296
215
|
}
|
|
297
|
-
|
|
298
216
|
clack.intro("create-dzx");
|
|
299
|
-
|
|
300
|
-
const dirArg = args.dir ?? args.positional[0];
|
|
217
|
+
const dirArg = typeof args.dir === "string" ? args.dir : args.positional[0];
|
|
301
218
|
const defaultDir = "my-agent";
|
|
302
|
-
|
|
303
219
|
let targetDir = path.resolve(process.cwd(), dirArg || defaultDir);
|
|
304
220
|
if (!isYes) {
|
|
305
221
|
const dirResponse = await clack.text({
|
|
306
222
|
message: "Project directory",
|
|
307
|
-
initialValue: dirArg || defaultDir
|
|
223
|
+
initialValue: dirArg || defaultDir
|
|
308
224
|
});
|
|
309
225
|
if (clack.isCancel(dirResponse)) {
|
|
310
226
|
clack.cancel("Aborted.");
|
|
@@ -312,17 +228,16 @@ ${colorize.bold("Options")}
|
|
|
312
228
|
}
|
|
313
229
|
targetDir = path.resolve(process.cwd(), dirResponse || defaultDir);
|
|
314
230
|
}
|
|
315
|
-
|
|
316
|
-
let template = args.template || (isYes ? "basic" : undefined);
|
|
231
|
+
let template = typeof args.template === "string" ? args.template : isYes ? "basic" : void 0;
|
|
317
232
|
if (!template) {
|
|
318
233
|
const templateResponse = await clack.select({
|
|
319
234
|
message: "Template",
|
|
320
235
|
options: [
|
|
321
236
|
{ value: "basic", label: "basic" },
|
|
322
237
|
{ value: "tools-only", label: "tools-only" },
|
|
323
|
-
{ value: "full", label: "full" }
|
|
238
|
+
{ value: "full", label: "full" }
|
|
324
239
|
],
|
|
325
|
-
initialValue: "basic"
|
|
240
|
+
initialValue: "basic"
|
|
326
241
|
});
|
|
327
242
|
if (clack.isCancel(templateResponse)) {
|
|
328
243
|
clack.cancel("Aborted.");
|
|
@@ -330,16 +245,15 @@ ${colorize.bold("Options")}
|
|
|
330
245
|
}
|
|
331
246
|
template = templateResponse;
|
|
332
247
|
}
|
|
333
|
-
|
|
334
|
-
let runtime = args.runtime || (isYes ? "node" : undefined);
|
|
248
|
+
let runtime = typeof args.runtime === "string" ? args.runtime : isYes ? "node" : void 0;
|
|
335
249
|
if (!runtime) {
|
|
336
250
|
const runtimeResponse = await clack.select({
|
|
337
251
|
message: "Runtime",
|
|
338
252
|
options: [
|
|
339
253
|
{ value: "node", label: "node" },
|
|
340
|
-
{ value: "deno", label: "deno" }
|
|
254
|
+
{ value: "deno", label: "deno" }
|
|
341
255
|
],
|
|
342
|
-
initialValue: "node"
|
|
256
|
+
initialValue: "node"
|
|
343
257
|
});
|
|
344
258
|
if (clack.isCancel(runtimeResponse)) {
|
|
345
259
|
clack.cancel("Aborted.");
|
|
@@ -347,67 +261,57 @@ ${colorize.bold("Options")}
|
|
|
347
261
|
}
|
|
348
262
|
runtime = runtimeResponse;
|
|
349
263
|
}
|
|
350
|
-
|
|
351
264
|
template = template ?? "basic";
|
|
352
265
|
runtime = runtime ?? "node";
|
|
353
|
-
|
|
354
266
|
if (!TEMPLATES.includes(template)) {
|
|
355
267
|
throw new Error(`Unknown template: ${template}`);
|
|
356
268
|
}
|
|
357
269
|
if (!RUNTIMES.includes(runtime)) {
|
|
358
270
|
throw new Error(`Unknown runtime: ${runtime}`);
|
|
359
271
|
}
|
|
360
|
-
|
|
361
272
|
if (!force && !isEmptyDir(targetDir)) {
|
|
362
273
|
throw new Error(`Target directory is not empty: ${targetDir}. Use --force to overwrite.`);
|
|
363
274
|
}
|
|
364
|
-
|
|
365
275
|
const templatesRoot = resolveTemplatesRoot();
|
|
366
276
|
const templateDir = path.join(templatesRoot, template);
|
|
367
277
|
if (!fs.existsSync(templateDir)) {
|
|
368
278
|
throw new Error(`Template not found: ${template}`);
|
|
369
279
|
}
|
|
370
|
-
|
|
371
280
|
if (force && !isYes) {
|
|
372
281
|
const confirmation = await clack.confirm({
|
|
373
282
|
message: "This will overwrite existing files. Continue?",
|
|
374
|
-
initialValue: false
|
|
283
|
+
initialValue: false
|
|
375
284
|
});
|
|
376
285
|
if (clack.isCancel(confirmation) || confirmation === false) {
|
|
377
286
|
clack.cancel("Aborted.");
|
|
378
287
|
process.exit(1);
|
|
379
288
|
}
|
|
380
289
|
}
|
|
381
|
-
|
|
382
290
|
const spinner = createSpinner(process.stdout.isTTY);
|
|
383
291
|
const stepLabels = [
|
|
384
292
|
"Validating destination",
|
|
385
293
|
"Copying template",
|
|
386
294
|
"Configuring manifest",
|
|
387
|
-
...
|
|
388
|
-
"Finalizing"
|
|
295
|
+
...shouldInstall ? ["Installing dependencies"] : [],
|
|
296
|
+
"Finalizing"
|
|
389
297
|
];
|
|
390
298
|
const stepLabelWidth = stepLabels.reduce((max, label) => Math.max(max, label.length), 0);
|
|
391
299
|
const stepTimes = [];
|
|
392
300
|
let stepStart = Date.now();
|
|
393
301
|
let lastStep = "";
|
|
394
302
|
let spinnerStarted = false;
|
|
395
|
-
|
|
396
303
|
const logStep = (label, ms) => {
|
|
397
304
|
const paddedLabel = label.padEnd(stepLabelWidth);
|
|
398
305
|
const paddedMs = `${ms}ms`.padStart(6);
|
|
399
306
|
const line = `${colorize.cyan(symbols.step)} ${colorize.gray(paddedLabel)} ${colorize.dim(paddedMs)}`;
|
|
400
307
|
if (spinner.isEnabled) {
|
|
401
308
|
spinner.pause();
|
|
402
|
-
// eslint-disable-next-line no-console
|
|
403
309
|
console.log(line);
|
|
404
310
|
spinner.resume();
|
|
405
311
|
} else {
|
|
406
|
-
// eslint-disable-next-line no-console
|
|
407
312
|
console.log(line);
|
|
408
313
|
}
|
|
409
314
|
};
|
|
410
|
-
|
|
411
315
|
const step = (message) => {
|
|
412
316
|
const now = Date.now();
|
|
413
317
|
if (lastStep) {
|
|
@@ -426,31 +330,24 @@ ${colorize.bold("Options")}
|
|
|
426
330
|
}
|
|
427
331
|
}
|
|
428
332
|
};
|
|
429
|
-
|
|
430
333
|
const dzxVersion = await getDzxVersion();
|
|
431
334
|
const banner = `${colorize.blue(symbols.brand)} ${colorize.bold("create-dzx")} ${colorize.gray("scaffold")}`;
|
|
432
|
-
// eslint-disable-next-line no-console
|
|
433
335
|
console.log(banner);
|
|
434
|
-
|
|
435
336
|
step("Validating destination");
|
|
436
337
|
if (!force) {
|
|
437
338
|
const templateFiles = listFiles(templateDir);
|
|
438
339
|
const collisions = templateFiles.filter((file) => fs.existsSync(path.join(targetDir, file)));
|
|
439
340
|
if (collisions.length > 0) {
|
|
440
|
-
const preview = collisions
|
|
441
|
-
.slice(0, 8)
|
|
442
|
-
.map((file) => `- ${file}`)
|
|
443
|
-
.join("\n");
|
|
341
|
+
const preview = collisions.slice(0, 8).map((file) => `- ${file}`).join("\n");
|
|
444
342
|
const suffix = collisions.length > 8 ? "\n- ..." : "";
|
|
445
343
|
throw new Error(
|
|
446
|
-
`Refusing to overwrite existing files. Use --force to proceed
|
|
344
|
+
`Refusing to overwrite existing files. Use --force to proceed.
|
|
345
|
+
${preview}${suffix}`
|
|
447
346
|
);
|
|
448
347
|
}
|
|
449
348
|
}
|
|
450
|
-
|
|
451
349
|
step("Copying template");
|
|
452
350
|
copyDir(templateDir, targetDir);
|
|
453
|
-
|
|
454
351
|
step("Configuring manifest");
|
|
455
352
|
const manifestPath = path.join(targetDir, "mcp.json");
|
|
456
353
|
if (fs.existsSync(manifestPath)) {
|
|
@@ -459,25 +356,23 @@ ${colorize.bold("Options")}
|
|
|
459
356
|
manifest.runtime = runtime;
|
|
460
357
|
fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2));
|
|
461
358
|
}
|
|
462
|
-
|
|
463
|
-
// Update package.json with correct @dwizi/dzx version
|
|
464
359
|
const pkgPath = path.join(targetDir, "package.json");
|
|
465
360
|
if (fs.existsSync(pkgPath)) {
|
|
466
361
|
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
|
|
467
|
-
if (pkg.dependencies
|
|
362
|
+
if (pkg.dependencies?.["@dwizi/dzx"] === "string") {
|
|
468
363
|
pkg.dependencies["@dwizi/dzx"] = `^${dzxVersion}`;
|
|
469
|
-
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2)
|
|
364
|
+
fs.writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}
|
|
365
|
+
`);
|
|
470
366
|
}
|
|
471
367
|
}
|
|
472
|
-
|
|
473
368
|
if (shouldInstall) {
|
|
474
369
|
step("Installing dependencies");
|
|
475
370
|
if (!fs.existsSync(pkgPath)) {
|
|
476
371
|
if (spinner.isEnabled) spinner.stop();
|
|
477
372
|
throw new Error("Missing package.json in template. Cannot install dependencies.");
|
|
478
373
|
}
|
|
479
|
-
const
|
|
480
|
-
const installCommand = getInstallCommand(
|
|
374
|
+
const pm2 = detectPackageManager(targetDir);
|
|
375
|
+
const installCommand = getInstallCommand(pm2);
|
|
481
376
|
try {
|
|
482
377
|
await runCommand(installCommand, targetDir);
|
|
483
378
|
} catch {
|
|
@@ -485,7 +380,6 @@ ${colorize.bold("Options")}
|
|
|
485
380
|
throw new Error(`Dependency installation failed. Run \`${installCommand}\` manually.`);
|
|
486
381
|
}
|
|
487
382
|
}
|
|
488
|
-
|
|
489
383
|
step("Finalizing");
|
|
490
384
|
if (lastStep) {
|
|
491
385
|
const ms = Date.now() - stepStart;
|
|
@@ -493,32 +387,27 @@ ${colorize.bold("Options")}
|
|
|
493
387
|
logStep(lastStep, ms);
|
|
494
388
|
}
|
|
495
389
|
spinner.stop();
|
|
496
|
-
|
|
497
390
|
const totalMs = stepTimes.reduce((sum, item) => sum + item.ms, 0);
|
|
498
391
|
const summaryLines = [
|
|
499
392
|
{ label: "dir", value: targetDir },
|
|
500
393
|
{ label: "template", value: template },
|
|
501
394
|
{ label: "runtime", value: runtime },
|
|
502
395
|
{ label: "install", value: shouldInstall ? "yes" : "no" },
|
|
503
|
-
{ label: "ready", value: `${totalMs}ms` }
|
|
396
|
+
{ label: "ready", value: `${totalMs}ms` }
|
|
504
397
|
];
|
|
505
|
-
// eslint-disable-next-line no-console
|
|
506
398
|
console.log("");
|
|
507
|
-
// eslint-disable-next-line no-console
|
|
508
399
|
console.log(`${colorize.green(symbols.check)} ${colorize.bold("Project ready")}`);
|
|
509
400
|
printKeyValueList(summaryLines);
|
|
510
401
|
const pm = shouldInstall ? detectPackageManager(targetDir) : "pnpm";
|
|
402
|
+
const runCommand2 = getRunCommand(pm, "dev");
|
|
511
403
|
const nextSteps = [
|
|
512
404
|
`cd ${path.basename(targetDir)}`,
|
|
513
|
-
shouldInstall ?
|
|
514
|
-
shouldInstall ? "" :
|
|
405
|
+
shouldInstall ? runCommand2 : `${pm} install`,
|
|
406
|
+
shouldInstall ? "" : runCommand2
|
|
515
407
|
].filter(Boolean);
|
|
516
|
-
// eslint-disable-next-line no-console
|
|
517
408
|
console.log(`${colorize.gray("next")} ${colorize.cyan(nextSteps.join(" && "))}`);
|
|
518
409
|
}
|
|
519
|
-
|
|
520
410
|
main().catch((err) => {
|
|
521
|
-
// eslint-disable-next-line no-console
|
|
522
411
|
console.error(err);
|
|
523
412
|
process.exit(1);
|
|
524
413
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dwizi/create-dzx",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.11",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"publishConfig": {
|
|
@@ -29,10 +29,17 @@
|
|
|
29
29
|
"node": ">=24"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
|
-
"@
|
|
32
|
+
"@biomejs/biome": "^2.3.13",
|
|
33
|
+
"@dwizi/dzx": "*",
|
|
34
|
+
"@types/node": "^25.1.0",
|
|
35
|
+
"esbuild": "^0.27.2",
|
|
36
|
+
"typescript": "^5.9.3"
|
|
33
37
|
},
|
|
34
38
|
"scripts": {
|
|
35
39
|
"build": "node scripts/build.mjs",
|
|
40
|
+
"lint": "biome check .",
|
|
41
|
+
"format": "biome format .",
|
|
42
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
36
43
|
"test": "node --test tests/*.test.mjs",
|
|
37
44
|
"fix:lockfile": "pnpm install --lockfile-only --ignore-workspace"
|
|
38
45
|
}
|