@dwizi/create-dzx 0.1.10 → 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 +45 -159
- 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,144 +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
183
|
const { createRequire } = await import("node:module");
|
|
257
|
-
const
|
|
258
|
-
const dzxPkgJsonPath =
|
|
184
|
+
const require2 = createRequire(import.meta.url);
|
|
185
|
+
const dzxPkgJsonPath = require2.resolve("@dwizi/dzx/package.json", { paths: [process.cwd()] });
|
|
259
186
|
const dzxPkg = JSON.parse(fs.readFileSync(dzxPkgJsonPath, "utf8"));
|
|
260
187
|
if (dzxPkg && typeof dzxPkg.version === "string" && dzxPkg.version.trim()) {
|
|
261
188
|
return dzxPkg.version.trim();
|
|
262
189
|
}
|
|
263
190
|
} catch {
|
|
264
191
|
}
|
|
265
|
-
// Fallback version if we cannot resolve an installed @dwizi/dzx
|
|
266
192
|
return "*";
|
|
267
193
|
}
|
|
268
|
-
|
|
269
|
-
/**
|
|
270
|
-
* Main scaffolding function.
|
|
271
|
-
*/
|
|
272
194
|
async function main() {
|
|
273
195
|
const args = parseArgs(process.argv.slice(2));
|
|
274
|
-
const force =
|
|
275
|
-
const isYes =
|
|
276
|
-
const shouldInstall = args.install
|
|
277
|
-
|
|
278
|
-
: args["no-install"]
|
|
279
|
-
? false
|
|
280
|
-
: true; // Default to installing for scaffold mode
|
|
281
|
-
|
|
282
|
-
if (args.help || args.h) {
|
|
283
|
-
// 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) {
|
|
284
200
|
console.log(`
|
|
285
201
|
${colorize.blue(symbols.brand)} ${colorize.bold("create-dzx")}
|
|
286
202
|
|
|
@@ -297,17 +213,14 @@ ${colorize.bold("Options")}
|
|
|
297
213
|
`);
|
|
298
214
|
return;
|
|
299
215
|
}
|
|
300
|
-
|
|
301
216
|
clack.intro("create-dzx");
|
|
302
|
-
|
|
303
|
-
const dirArg = args.dir ?? args.positional[0];
|
|
217
|
+
const dirArg = typeof args.dir === "string" ? args.dir : args.positional[0];
|
|
304
218
|
const defaultDir = "my-agent";
|
|
305
|
-
|
|
306
219
|
let targetDir = path.resolve(process.cwd(), dirArg || defaultDir);
|
|
307
220
|
if (!isYes) {
|
|
308
221
|
const dirResponse = await clack.text({
|
|
309
222
|
message: "Project directory",
|
|
310
|
-
initialValue: dirArg || defaultDir
|
|
223
|
+
initialValue: dirArg || defaultDir
|
|
311
224
|
});
|
|
312
225
|
if (clack.isCancel(dirResponse)) {
|
|
313
226
|
clack.cancel("Aborted.");
|
|
@@ -315,17 +228,16 @@ ${colorize.bold("Options")}
|
|
|
315
228
|
}
|
|
316
229
|
targetDir = path.resolve(process.cwd(), dirResponse || defaultDir);
|
|
317
230
|
}
|
|
318
|
-
|
|
319
|
-
let template = args.template || (isYes ? "basic" : undefined);
|
|
231
|
+
let template = typeof args.template === "string" ? args.template : isYes ? "basic" : void 0;
|
|
320
232
|
if (!template) {
|
|
321
233
|
const templateResponse = await clack.select({
|
|
322
234
|
message: "Template",
|
|
323
235
|
options: [
|
|
324
236
|
{ value: "basic", label: "basic" },
|
|
325
237
|
{ value: "tools-only", label: "tools-only" },
|
|
326
|
-
{ value: "full", label: "full" }
|
|
238
|
+
{ value: "full", label: "full" }
|
|
327
239
|
],
|
|
328
|
-
initialValue: "basic"
|
|
240
|
+
initialValue: "basic"
|
|
329
241
|
});
|
|
330
242
|
if (clack.isCancel(templateResponse)) {
|
|
331
243
|
clack.cancel("Aborted.");
|
|
@@ -333,16 +245,15 @@ ${colorize.bold("Options")}
|
|
|
333
245
|
}
|
|
334
246
|
template = templateResponse;
|
|
335
247
|
}
|
|
336
|
-
|
|
337
|
-
let runtime = args.runtime || (isYes ? "node" : undefined);
|
|
248
|
+
let runtime = typeof args.runtime === "string" ? args.runtime : isYes ? "node" : void 0;
|
|
338
249
|
if (!runtime) {
|
|
339
250
|
const runtimeResponse = await clack.select({
|
|
340
251
|
message: "Runtime",
|
|
341
252
|
options: [
|
|
342
253
|
{ value: "node", label: "node" },
|
|
343
|
-
{ value: "deno", label: "deno" }
|
|
254
|
+
{ value: "deno", label: "deno" }
|
|
344
255
|
],
|
|
345
|
-
initialValue: "node"
|
|
256
|
+
initialValue: "node"
|
|
346
257
|
});
|
|
347
258
|
if (clack.isCancel(runtimeResponse)) {
|
|
348
259
|
clack.cancel("Aborted.");
|
|
@@ -350,67 +261,57 @@ ${colorize.bold("Options")}
|
|
|
350
261
|
}
|
|
351
262
|
runtime = runtimeResponse;
|
|
352
263
|
}
|
|
353
|
-
|
|
354
264
|
template = template ?? "basic";
|
|
355
265
|
runtime = runtime ?? "node";
|
|
356
|
-
|
|
357
266
|
if (!TEMPLATES.includes(template)) {
|
|
358
267
|
throw new Error(`Unknown template: ${template}`);
|
|
359
268
|
}
|
|
360
269
|
if (!RUNTIMES.includes(runtime)) {
|
|
361
270
|
throw new Error(`Unknown runtime: ${runtime}`);
|
|
362
271
|
}
|
|
363
|
-
|
|
364
272
|
if (!force && !isEmptyDir(targetDir)) {
|
|
365
273
|
throw new Error(`Target directory is not empty: ${targetDir}. Use --force to overwrite.`);
|
|
366
274
|
}
|
|
367
|
-
|
|
368
275
|
const templatesRoot = resolveTemplatesRoot();
|
|
369
276
|
const templateDir = path.join(templatesRoot, template);
|
|
370
277
|
if (!fs.existsSync(templateDir)) {
|
|
371
278
|
throw new Error(`Template not found: ${template}`);
|
|
372
279
|
}
|
|
373
|
-
|
|
374
280
|
if (force && !isYes) {
|
|
375
281
|
const confirmation = await clack.confirm({
|
|
376
282
|
message: "This will overwrite existing files. Continue?",
|
|
377
|
-
initialValue: false
|
|
283
|
+
initialValue: false
|
|
378
284
|
});
|
|
379
285
|
if (clack.isCancel(confirmation) || confirmation === false) {
|
|
380
286
|
clack.cancel("Aborted.");
|
|
381
287
|
process.exit(1);
|
|
382
288
|
}
|
|
383
289
|
}
|
|
384
|
-
|
|
385
290
|
const spinner = createSpinner(process.stdout.isTTY);
|
|
386
291
|
const stepLabels = [
|
|
387
292
|
"Validating destination",
|
|
388
293
|
"Copying template",
|
|
389
294
|
"Configuring manifest",
|
|
390
|
-
...
|
|
391
|
-
"Finalizing"
|
|
295
|
+
...shouldInstall ? ["Installing dependencies"] : [],
|
|
296
|
+
"Finalizing"
|
|
392
297
|
];
|
|
393
298
|
const stepLabelWidth = stepLabels.reduce((max, label) => Math.max(max, label.length), 0);
|
|
394
299
|
const stepTimes = [];
|
|
395
300
|
let stepStart = Date.now();
|
|
396
301
|
let lastStep = "";
|
|
397
302
|
let spinnerStarted = false;
|
|
398
|
-
|
|
399
303
|
const logStep = (label, ms) => {
|
|
400
304
|
const paddedLabel = label.padEnd(stepLabelWidth);
|
|
401
305
|
const paddedMs = `${ms}ms`.padStart(6);
|
|
402
306
|
const line = `${colorize.cyan(symbols.step)} ${colorize.gray(paddedLabel)} ${colorize.dim(paddedMs)}`;
|
|
403
307
|
if (spinner.isEnabled) {
|
|
404
308
|
spinner.pause();
|
|
405
|
-
// eslint-disable-next-line no-console
|
|
406
309
|
console.log(line);
|
|
407
310
|
spinner.resume();
|
|
408
311
|
} else {
|
|
409
|
-
// eslint-disable-next-line no-console
|
|
410
312
|
console.log(line);
|
|
411
313
|
}
|
|
412
314
|
};
|
|
413
|
-
|
|
414
315
|
const step = (message) => {
|
|
415
316
|
const now = Date.now();
|
|
416
317
|
if (lastStep) {
|
|
@@ -429,31 +330,24 @@ ${colorize.bold("Options")}
|
|
|
429
330
|
}
|
|
430
331
|
}
|
|
431
332
|
};
|
|
432
|
-
|
|
433
333
|
const dzxVersion = await getDzxVersion();
|
|
434
334
|
const banner = `${colorize.blue(symbols.brand)} ${colorize.bold("create-dzx")} ${colorize.gray("scaffold")}`;
|
|
435
|
-
// eslint-disable-next-line no-console
|
|
436
335
|
console.log(banner);
|
|
437
|
-
|
|
438
336
|
step("Validating destination");
|
|
439
337
|
if (!force) {
|
|
440
338
|
const templateFiles = listFiles(templateDir);
|
|
441
339
|
const collisions = templateFiles.filter((file) => fs.existsSync(path.join(targetDir, file)));
|
|
442
340
|
if (collisions.length > 0) {
|
|
443
|
-
const preview = collisions
|
|
444
|
-
.slice(0, 8)
|
|
445
|
-
.map((file) => `- ${file}`)
|
|
446
|
-
.join("\n");
|
|
341
|
+
const preview = collisions.slice(0, 8).map((file) => `- ${file}`).join("\n");
|
|
447
342
|
const suffix = collisions.length > 8 ? "\n- ..." : "";
|
|
448
343
|
throw new Error(
|
|
449
|
-
`Refusing to overwrite existing files. Use --force to proceed
|
|
344
|
+
`Refusing to overwrite existing files. Use --force to proceed.
|
|
345
|
+
${preview}${suffix}`
|
|
450
346
|
);
|
|
451
347
|
}
|
|
452
348
|
}
|
|
453
|
-
|
|
454
349
|
step("Copying template");
|
|
455
350
|
copyDir(templateDir, targetDir);
|
|
456
|
-
|
|
457
351
|
step("Configuring manifest");
|
|
458
352
|
const manifestPath = path.join(targetDir, "mcp.json");
|
|
459
353
|
if (fs.existsSync(manifestPath)) {
|
|
@@ -462,25 +356,23 @@ ${colorize.bold("Options")}
|
|
|
462
356
|
manifest.runtime = runtime;
|
|
463
357
|
fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2));
|
|
464
358
|
}
|
|
465
|
-
|
|
466
|
-
// Update package.json with correct @dwizi/dzx version
|
|
467
359
|
const pkgPath = path.join(targetDir, "package.json");
|
|
468
360
|
if (fs.existsSync(pkgPath)) {
|
|
469
361
|
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
|
|
470
|
-
if (pkg.dependencies
|
|
362
|
+
if (pkg.dependencies?.["@dwizi/dzx"] === "string") {
|
|
471
363
|
pkg.dependencies["@dwizi/dzx"] = `^${dzxVersion}`;
|
|
472
|
-
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2)
|
|
364
|
+
fs.writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}
|
|
365
|
+
`);
|
|
473
366
|
}
|
|
474
367
|
}
|
|
475
|
-
|
|
476
368
|
if (shouldInstall) {
|
|
477
369
|
step("Installing dependencies");
|
|
478
370
|
if (!fs.existsSync(pkgPath)) {
|
|
479
371
|
if (spinner.isEnabled) spinner.stop();
|
|
480
372
|
throw new Error("Missing package.json in template. Cannot install dependencies.");
|
|
481
373
|
}
|
|
482
|
-
const
|
|
483
|
-
const installCommand = getInstallCommand(
|
|
374
|
+
const pm2 = detectPackageManager(targetDir);
|
|
375
|
+
const installCommand = getInstallCommand(pm2);
|
|
484
376
|
try {
|
|
485
377
|
await runCommand(installCommand, targetDir);
|
|
486
378
|
} catch {
|
|
@@ -488,7 +380,6 @@ ${colorize.bold("Options")}
|
|
|
488
380
|
throw new Error(`Dependency installation failed. Run \`${installCommand}\` manually.`);
|
|
489
381
|
}
|
|
490
382
|
}
|
|
491
|
-
|
|
492
383
|
step("Finalizing");
|
|
493
384
|
if (lastStep) {
|
|
494
385
|
const ms = Date.now() - stepStart;
|
|
@@ -496,32 +387,27 @@ ${colorize.bold("Options")}
|
|
|
496
387
|
logStep(lastStep, ms);
|
|
497
388
|
}
|
|
498
389
|
spinner.stop();
|
|
499
|
-
|
|
500
390
|
const totalMs = stepTimes.reduce((sum, item) => sum + item.ms, 0);
|
|
501
391
|
const summaryLines = [
|
|
502
392
|
{ label: "dir", value: targetDir },
|
|
503
393
|
{ label: "template", value: template },
|
|
504
394
|
{ label: "runtime", value: runtime },
|
|
505
395
|
{ label: "install", value: shouldInstall ? "yes" : "no" },
|
|
506
|
-
{ label: "ready", value: `${totalMs}ms` }
|
|
396
|
+
{ label: "ready", value: `${totalMs}ms` }
|
|
507
397
|
];
|
|
508
|
-
// eslint-disable-next-line no-console
|
|
509
398
|
console.log("");
|
|
510
|
-
// eslint-disable-next-line no-console
|
|
511
399
|
console.log(`${colorize.green(symbols.check)} ${colorize.bold("Project ready")}`);
|
|
512
400
|
printKeyValueList(summaryLines);
|
|
513
401
|
const pm = shouldInstall ? detectPackageManager(targetDir) : "pnpm";
|
|
402
|
+
const runCommand2 = getRunCommand(pm, "dev");
|
|
514
403
|
const nextSteps = [
|
|
515
404
|
`cd ${path.basename(targetDir)}`,
|
|
516
|
-
shouldInstall ?
|
|
517
|
-
shouldInstall ? "" :
|
|
405
|
+
shouldInstall ? runCommand2 : `${pm} install`,
|
|
406
|
+
shouldInstall ? "" : runCommand2
|
|
518
407
|
].filter(Boolean);
|
|
519
|
-
// eslint-disable-next-line no-console
|
|
520
408
|
console.log(`${colorize.gray("next")} ${colorize.cyan(nextSteps.join(" && "))}`);
|
|
521
409
|
}
|
|
522
|
-
|
|
523
410
|
main().catch((err) => {
|
|
524
|
-
// eslint-disable-next-line no-console
|
|
525
411
|
console.error(err);
|
|
526
412
|
process.exit(1);
|
|
527
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
|
}
|