@project-ajax/create 0.0.38 → 0.0.39

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/dist/index.js +331 -57
  2. package/package.json +5 -3
package/dist/index.js CHANGED
@@ -1,14 +1,200 @@
1
1
  #!/usr/bin/env node
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __commonJS = (cb, mod) => function __require() {
9
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
20
+ // If the importer is in node compatibility mode or this is not an ESM
21
+ // file that has been converted to a CommonJS file using a Babel-
22
+ // compatible transform (i.e. "__esModule" has not been set), then set
23
+ // "default" to the CommonJS "module.exports" for node compatibility.
24
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
25
+ mod
26
+ ));
27
+
28
+ // ../../node_modules/picocolors/picocolors.js
29
+ var require_picocolors = __commonJS({
30
+ "../../node_modules/picocolors/picocolors.js"(exports, module) {
31
+ "use strict";
32
+ var p = process || {};
33
+ var argv = p.argv || [];
34
+ var env = p.env || {};
35
+ var isColorSupported = !(!!env.NO_COLOR || argv.includes("--no-color")) && (!!env.FORCE_COLOR || argv.includes("--color") || p.platform === "win32" || (p.stdout || {}).isTTY && env.TERM !== "dumb" || !!env.CI);
36
+ var formatter = (open, close, replace = open) => (input2) => {
37
+ let string = "" + input2, index = string.indexOf(close, open.length);
38
+ return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close;
39
+ };
40
+ var replaceClose = (string, close, replace, index) => {
41
+ let result = "", cursor = 0;
42
+ do {
43
+ result += string.substring(cursor, index) + replace;
44
+ cursor = index + close.length;
45
+ index = string.indexOf(close, cursor);
46
+ } while (~index);
47
+ return result + string.substring(cursor);
48
+ };
49
+ var createColors = (enabled = isColorSupported) => {
50
+ let f = enabled ? formatter : () => String;
51
+ return {
52
+ isColorSupported: enabled,
53
+ reset: f("\x1B[0m", "\x1B[0m"),
54
+ bold: f("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m"),
55
+ dim: f("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m"),
56
+ italic: f("\x1B[3m", "\x1B[23m"),
57
+ underline: f("\x1B[4m", "\x1B[24m"),
58
+ inverse: f("\x1B[7m", "\x1B[27m"),
59
+ hidden: f("\x1B[8m", "\x1B[28m"),
60
+ strikethrough: f("\x1B[9m", "\x1B[29m"),
61
+ black: f("\x1B[30m", "\x1B[39m"),
62
+ red: f("\x1B[31m", "\x1B[39m"),
63
+ green: f("\x1B[32m", "\x1B[39m"),
64
+ yellow: f("\x1B[33m", "\x1B[39m"),
65
+ blue: f("\x1B[34m", "\x1B[39m"),
66
+ magenta: f("\x1B[35m", "\x1B[39m"),
67
+ cyan: f("\x1B[36m", "\x1B[39m"),
68
+ white: f("\x1B[37m", "\x1B[39m"),
69
+ gray: f("\x1B[90m", "\x1B[39m"),
70
+ bgBlack: f("\x1B[40m", "\x1B[49m"),
71
+ bgRed: f("\x1B[41m", "\x1B[49m"),
72
+ bgGreen: f("\x1B[42m", "\x1B[49m"),
73
+ bgYellow: f("\x1B[43m", "\x1B[49m"),
74
+ bgBlue: f("\x1B[44m", "\x1B[49m"),
75
+ bgMagenta: f("\x1B[45m", "\x1B[49m"),
76
+ bgCyan: f("\x1B[46m", "\x1B[49m"),
77
+ bgWhite: f("\x1B[47m", "\x1B[49m"),
78
+ blackBright: f("\x1B[90m", "\x1B[39m"),
79
+ redBright: f("\x1B[91m", "\x1B[39m"),
80
+ greenBright: f("\x1B[92m", "\x1B[39m"),
81
+ yellowBright: f("\x1B[93m", "\x1B[39m"),
82
+ blueBright: f("\x1B[94m", "\x1B[39m"),
83
+ magentaBright: f("\x1B[95m", "\x1B[39m"),
84
+ cyanBright: f("\x1B[96m", "\x1B[39m"),
85
+ whiteBright: f("\x1B[97m", "\x1B[39m"),
86
+ bgBlackBright: f("\x1B[100m", "\x1B[49m"),
87
+ bgRedBright: f("\x1B[101m", "\x1B[49m"),
88
+ bgGreenBright: f("\x1B[102m", "\x1B[49m"),
89
+ bgYellowBright: f("\x1B[103m", "\x1B[49m"),
90
+ bgBlueBright: f("\x1B[104m", "\x1B[49m"),
91
+ bgMagentaBright: f("\x1B[105m", "\x1B[49m"),
92
+ bgCyanBright: f("\x1B[106m", "\x1B[49m"),
93
+ bgWhiteBright: f("\x1B[107m", "\x1B[49m")
94
+ };
95
+ };
96
+ module.exports = createColors();
97
+ module.exports.createColors = createColors;
98
+ }
99
+ });
2
100
 
3
101
  // src/run-create.ts
4
- import { execSync } from "child_process";
5
- import fs from "fs";
102
+ import { spawn, spawnSync } from "child_process";
103
+ import fs from "fs/promises";
6
104
  import path from "path";
7
105
  import { fileURLToPath } from "url";
8
106
  import { parseArgs } from "util";
9
107
  import * as prompts from "@inquirer/prompts";
10
- import chalk from "chalk";
11
- import ora from "ora";
108
+
109
+ // ../shared/dist/colors.js
110
+ var import_picocolors = __toESM(require_picocolors(), 1);
111
+ var colors = {
112
+ bold: import_picocolors.default.bold,
113
+ dim: import_picocolors.default.dim,
114
+ red: import_picocolors.default.red,
115
+ green: import_picocolors.default.green,
116
+ yellow: import_picocolors.default.yellow,
117
+ cyan: import_picocolors.default.cyan,
118
+ // Semantic aliases
119
+ success: import_picocolors.default.green,
120
+ error: import_picocolors.default.red,
121
+ warn: import_picocolors.default.yellow,
122
+ info: import_picocolors.default.cyan,
123
+ isColorSupported: import_picocolors.default.isColorSupported
124
+ };
125
+
126
+ // ../shared/dist/spinner.js
127
+ var BRAILLE_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
128
+ var REFRESH_INTERVAL = 80;
129
+ function isAnimationEnabled(stream) {
130
+ if (!stream.isTTY) return false;
131
+ if (process.env.CI) return false;
132
+ if (process.env.TERM === "dumb") return false;
133
+ return true;
134
+ }
135
+ function createSpinner(options) {
136
+ const stream = options.stream ?? process.stderr;
137
+ let text = options.text;
138
+ let frameIndex = 0;
139
+ let intervalId = null;
140
+ const animated = isAnimationEnabled(stream);
141
+ function clearLine() {
142
+ if (animated) {
143
+ stream.clearLine(0);
144
+ stream.cursorTo(0);
145
+ }
146
+ }
147
+ function render() {
148
+ clearLine();
149
+ stream.write(`${BRAILLE_FRAMES[frameIndex]} ${text}`);
150
+ frameIndex = (frameIndex + 1) % BRAILLE_FRAMES.length;
151
+ }
152
+ function writeLine(prefix, message) {
153
+ clearLine();
154
+ stream.write(`${prefix} ${message}
155
+ `);
156
+ }
157
+ function stop() {
158
+ if (intervalId) {
159
+ clearInterval(intervalId);
160
+ intervalId = null;
161
+ }
162
+ clearLine();
163
+ }
164
+ return {
165
+ start() {
166
+ if (animated) {
167
+ render();
168
+ intervalId = setInterval(render, REFRESH_INTERVAL);
169
+ } else {
170
+ stream.write(`${text}
171
+ `);
172
+ }
173
+ },
174
+ update(newText) {
175
+ text = newText;
176
+ if (!animated) {
177
+ stream.write(`${text}
178
+ `);
179
+ }
180
+ },
181
+ succeed(finalText) {
182
+ stop();
183
+ writeLine(colors.success("\u2713"), finalText ?? text);
184
+ },
185
+ fail(finalText) {
186
+ stop();
187
+ writeLine(colors.error("\u2717"), finalText ?? text);
188
+ },
189
+ warn(finalText) {
190
+ stop();
191
+ writeLine(colors.warn("\u26A0"), finalText ?? text);
192
+ },
193
+ stop
194
+ };
195
+ }
196
+
197
+ // src/run-create.ts
12
198
  var __filename = fileURLToPath(import.meta.url);
13
199
  var __dirname = path.dirname(__filename);
14
200
  function detectPackageManager() {
@@ -21,13 +207,13 @@ async function runCreate() {
21
207
  process.exit(0);
22
208
  } catch (err) {
23
209
  const message = err instanceof Error ? err.message : String(err);
24
- console.error(chalk.red(`
210
+ console.error(colors.red(`
25
211
  ${message}`));
26
212
  process.exit(1);
27
213
  }
28
214
  }
29
215
  async function run() {
30
- console.log(chalk.bold.cyan("\n\u{1F680} Create a new worker\n"));
216
+ console.log(colors.bold(colors.cyan("\n\u{1F680} Create a new worker\n")));
31
217
  const { values } = parseArgs({
32
218
  options: {
33
219
  directory: { type: "string", short: "d" },
@@ -47,7 +233,7 @@ async function run() {
47
233
  if (!directoryName) {
48
234
  if (!isTTY) {
49
235
  console.error(
50
- chalk.red(
236
+ colors.red(
51
237
  "Provide the path to the new worker project with --directory"
52
238
  )
53
239
  );
@@ -60,17 +246,17 @@ async function run() {
60
246
  });
61
247
  }
62
248
  if (!directoryName) {
63
- console.log(chalk.red("Cancelled."));
249
+ console.log(colors.red("Cancelled."));
64
250
  process.exit(1);
65
251
  }
66
252
  const destPath = directoryName === "." ? process.cwd() : path.resolve(process.cwd(), directoryName);
67
253
  const templatePath = getTemplatePath();
68
- const conflicts = analyzeConflicts(destPath, templatePath);
254
+ const conflicts = await analyzeConflicts(destPath, templatePath);
69
255
  if (conflicts.hasConflicts) {
70
256
  if (values.force) {
71
257
  } else if (!isTTY) {
72
258
  console.error(
73
- chalk.red(
259
+ colors.red(
74
260
  `Directory has conflicting files: ${conflicts.conflicts.join(", ")}
75
261
  Use --force to overwrite.`
76
262
  )
@@ -78,7 +264,7 @@ Use --force to overwrite.`
78
264
  process.exit(1);
79
265
  } else if (useDefaults) {
80
266
  console.error(
81
- chalk.red(
267
+ colors.red(
82
268
  "Directory has conflicting files. Use --force with --yes to overwrite."
83
269
  )
84
270
  );
@@ -95,14 +281,21 @@ Use --force to overwrite.`
95
281
  ]
96
282
  });
97
283
  if (action === "cancel") {
98
- console.log(chalk.yellow("Cancelled."));
284
+ console.log(colors.yellow("Cancelled."));
99
285
  process.exit(0);
100
286
  }
101
287
  }
102
288
  }
103
- const existingGit = fs.existsSync(path.join(destPath, ".git"));
289
+ const gitAvailable = isGitAvailable();
290
+ const destExists = await pathExists(destPath);
291
+ let existingGit = false;
292
+ if (gitAvailable && destExists) {
293
+ existingGit = isGitRepository(destPath);
294
+ }
104
295
  let shouldInitGit = false;
105
- if (existingGit) {
296
+ if (!gitAvailable) {
297
+ shouldInitGit = false;
298
+ } else if (existingGit) {
106
299
  } else if (values.git) {
107
300
  shouldInitGit = true;
108
301
  } else if (values["no-git"]) {
@@ -129,17 +322,23 @@ Use --force to overwrite.`
129
322
  default: true
130
323
  });
131
324
  }
132
- const spinner = ora("Setting up template...").start();
325
+ const spinner = createSpinner({ text: "Setting up template..." });
326
+ spinner.start();
327
+ let createdDestPath = false;
133
328
  try {
134
- if (!fs.existsSync(destPath)) {
135
- fs.mkdirSync(destPath, { recursive: true });
329
+ if (!await pathExists(destPath)) {
330
+ await fs.mkdir(destPath, { recursive: true });
331
+ createdDestPath = true;
136
332
  }
137
- spinner.text = "Copying template files...";
138
- copyTemplate(templatePath, destPath);
333
+ spinner.update("Copying template files...");
334
+ await copyTemplate(templatePath, destPath);
139
335
  spinner.succeed("Template files copied");
140
336
  if (shouldInitGit) {
141
- const gitSpinner = ora("Initializing git repository...").start();
142
- const gitSuccess = initializeGit(destPath);
337
+ const gitSpinner = createSpinner({
338
+ text: "Initializing git repository..."
339
+ });
340
+ gitSpinner.start();
341
+ const gitSuccess = await initializeGit(destPath);
143
342
  if (gitSuccess) {
144
343
  gitSpinner.succeed("Git repository initialized");
145
344
  } else {
@@ -148,24 +347,25 @@ Use --force to overwrite.`
148
347
  );
149
348
  }
150
349
  } else if (existingGit) {
151
- console.log(chalk.dim(" Git repository already exists"));
350
+ console.log(colors.dim(" Git repository already exists"));
152
351
  }
153
352
  if (shouldInstall) {
154
- const installSpinner = ora(
155
- `Installing dependencies with ${packageManager}...`
156
- ).start();
157
- const installSuccess = installPackages(destPath, packageManager);
353
+ const installSpinner = createSpinner({
354
+ text: `Installing dependencies with ${packageManager}...`
355
+ });
356
+ installSpinner.start();
357
+ const installSuccess = await installPackages(destPath, packageManager);
158
358
  if (installSuccess) {
159
359
  installSpinner.succeed(`Dependencies installed with ${packageManager}`);
160
360
  } else {
161
361
  installSpinner.fail("Failed to install dependencies");
162
362
  const cmd = packageManager === "bun" ? "bun install" : "npm install";
163
363
  console.log(
164
- chalk.yellow(` Run '${cmd}' manually to install dependencies`)
364
+ colors.yellow(` Run '${cmd}' manually to install dependencies`)
165
365
  );
166
366
  }
167
367
  }
168
- console.log(chalk.green("\n\u2728 Worker project created successfully!"));
368
+ console.log(colors.green("\n\u2728 Worker project created successfully!"));
169
369
  printNextSteps({
170
370
  directoryName,
171
371
  gitInitialized: shouldInitGit || existingGit,
@@ -174,27 +374,35 @@ Use --force to overwrite.`
174
374
  });
175
375
  } catch (err) {
176
376
  spinner.fail("Failed to create worker project.");
377
+ if (createdDestPath) {
378
+ try {
379
+ if (await pathExists(destPath) && (await fs.readdir(destPath)).length === 0) {
380
+ await fs.rm(destPath, { recursive: true, force: true });
381
+ }
382
+ } catch {
383
+ }
384
+ }
177
385
  throw err;
178
386
  }
179
387
  }
180
388
  function validateFlags(values) {
181
389
  if (values.git && values["no-git"]) {
182
- console.error(chalk.red("Cannot use both --git and --no-git"));
390
+ console.error(colors.red("Cannot use both --git and --no-git"));
183
391
  process.exit(1);
184
392
  }
185
393
  if (values.install && values["no-install"]) {
186
- console.error(chalk.red("Cannot use both --install and --no-install"));
394
+ console.error(colors.red("Cannot use both --install and --no-install"));
187
395
  process.exit(1);
188
396
  }
189
397
  }
190
- function analyzeConflicts(destPath, templatePath) {
191
- if (!fs.existsSync(destPath)) {
398
+ async function analyzeConflicts(destPath, templatePath) {
399
+ if (!await pathExists(destPath)) {
192
400
  return { conflicts: [], hasConflicts: false };
193
401
  }
194
- const templateFiles = fs.readdirSync(templatePath);
402
+ const templateFiles = await fs.readdir(templatePath);
195
403
  const conflicts = [];
196
404
  for (const file of templateFiles) {
197
- if (fs.existsSync(path.join(destPath, file))) {
405
+ if (await pathExists(path.join(destPath, file))) {
198
406
  conflicts.push(file);
199
407
  }
200
408
  }
@@ -203,42 +411,60 @@ function analyzeConflicts(destPath, templatePath) {
203
411
  function getTemplatePath() {
204
412
  return path.resolve(__dirname, "..", "template");
205
413
  }
206
- function copyTemplate(templatePath, destPath) {
207
- if (!fs.existsSync(templatePath)) {
414
+ async function pathExists(filepath) {
415
+ try {
416
+ await fs.access(filepath);
417
+ return true;
418
+ } catch {
419
+ return false;
420
+ }
421
+ }
422
+ async function copyTemplate(templatePath, destPath) {
423
+ if (!await pathExists(templatePath)) {
208
424
  throw new Error(
209
425
  `Template directory not found at ${templatePath}. This is likely a packaging issue.`
210
426
  );
211
427
  }
212
- const templateFiles = fs.readdirSync(templatePath);
428
+ const templateFiles = await fs.readdir(templatePath);
213
429
  for (const file of templateFiles) {
214
430
  const srcPath = path.join(templatePath, file);
215
431
  const destFilePath = path.join(destPath, file);
216
- fs.cpSync(srcPath, destFilePath, { recursive: true });
432
+ await fs.cp(srcPath, destFilePath, { recursive: true });
217
433
  }
218
434
  }
219
- function initializeGit(destPath) {
220
- try {
221
- execSync("git init", { cwd: destPath, stdio: "pipe" });
222
- return true;
223
- } catch {
224
- return false;
225
- }
435
+ async function initializeGit(destPath) {
436
+ return new Promise((resolve) => {
437
+ const child = spawn("git", ["init"], {
438
+ cwd: destPath,
439
+ stdio: "pipe"
440
+ });
441
+ child.on("close", (code) => {
442
+ resolve(code === 0);
443
+ });
444
+ child.on("error", () => {
445
+ resolve(false);
446
+ });
447
+ });
226
448
  }
227
- function installPackages(destPath, pm) {
228
- const cmd = pm === "bun" ? "bun install" : "npm install";
229
- try {
230
- execSync(cmd, {
449
+ async function installPackages(destPath, pm) {
450
+ return new Promise((resolve) => {
451
+ const command = pm === "bun" ? "bun" : "npm";
452
+ const args = ["install"];
453
+ const child = spawn(command, args, {
231
454
  cwd: destPath,
232
455
  stdio: "pipe",
233
456
  env: { ...process.env, FORCE_COLOR: "1" }
234
457
  });
235
- return true;
236
- } catch {
237
- return false;
238
- }
458
+ child.on("close", (code) => {
459
+ resolve(code === 0);
460
+ });
461
+ child.on("error", () => {
462
+ resolve(false);
463
+ });
464
+ });
239
465
  }
240
466
  function printNextSteps(state) {
241
- console.log(chalk.cyan("\nNext steps:\n"));
467
+ console.log(colors.cyan("\nNext steps:\n"));
242
468
  const steps = [];
243
469
  if (state.directoryName !== ".") {
244
470
  steps.push(`cd ${state.directoryName}`);
@@ -250,16 +476,64 @@ function printNextSteps(state) {
250
476
  const runPrefix = state.packageManager === "bun" ? "bunx" : "npx";
251
477
  steps.push(`${runPrefix} workers deploy`);
252
478
  for (let i = 0; i < steps.length; i++) {
253
- console.log(` ${chalk.bold(`${i + 1}.`)} ${chalk.bold(steps[i])}`);
479
+ console.log(` ${colors.bold(`${i + 1}.`)} ${colors.bold(steps[i])}`);
254
480
  }
255
481
  console.log("");
256
482
  console.log(
257
- chalk.dim(
483
+ colors.dim(
258
484
  ` Tip: Run '${state.packageManager === "bun" ? "bunx" : "npx"} workers auth login' to connect to your Notion workspace.
259
485
  `
260
486
  )
261
487
  );
262
488
  }
489
+ function isGitAvailable() {
490
+ const result = spawnSync("git", ["--version"], { encoding: "utf-8" });
491
+ if (result.error) {
492
+ if (result.error.code === "ENOENT") {
493
+ return false;
494
+ }
495
+ throw new Error(
496
+ `Failed to check git availability: ${result.error.message}`
497
+ );
498
+ }
499
+ return result.status === 0;
500
+ }
501
+ function isGitRepository(rootPath) {
502
+ const isInsideWorkTree = readGitRevParseBoolean(
503
+ rootPath,
504
+ "--is-inside-work-tree"
505
+ );
506
+ if (isInsideWorkTree === null) {
507
+ return false;
508
+ }
509
+ const isBareRepository = readGitRevParseBoolean(
510
+ rootPath,
511
+ "--is-bare-repository"
512
+ );
513
+ if (isBareRepository === null) {
514
+ return false;
515
+ }
516
+ return isInsideWorkTree || isBareRepository;
517
+ }
518
+ function readGitRevParseBoolean(rootPath, flag) {
519
+ const result = spawnSync("git", ["rev-parse", flag], {
520
+ cwd: rootPath,
521
+ encoding: "utf-8"
522
+ });
523
+ if (result.error) {
524
+ throw new Error(`Failed to check git repository: ${result.error.message}`);
525
+ }
526
+ if (result.status !== 0) {
527
+ const stderr = typeof result.stderr === "string" ? result.stderr.trim() : "";
528
+ if (stderr.includes("not a git repository")) {
529
+ return null;
530
+ }
531
+ const message = stderr ? `Failed to check git repository: ${stderr}` : "Failed to check git repository.";
532
+ throw new Error(message);
533
+ }
534
+ const stdout = typeof result.stdout === "string" ? result.stdout.trim() : "";
535
+ return stdout === "true";
536
+ }
263
537
  function safeInput(config) {
264
538
  return prompts.input(config).catch(handlePromptExit);
265
539
  }
@@ -271,7 +545,7 @@ function safeSelect(config) {
271
545
  }
272
546
  function handlePromptExit(err) {
273
547
  if (err instanceof Error && err.name === "ExitPromptError") {
274
- console.log(chalk.yellow("\nCancelled."));
548
+ console.log(colors.yellow("\nCancelled."));
275
549
  process.exit(0);
276
550
  }
277
551
  throw err;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@project-ajax/create",
3
- "version": "0.0.38",
3
+ "version": "0.0.39",
4
4
  "description": "Initialize a new Notion Workers extensions repo.",
5
5
  "bin": {
6
6
  "create-ajax": "dist/index.js"
@@ -14,6 +14,9 @@
14
14
  "entry": [
15
15
  "src/index.ts"
16
16
  ],
17
+ "noExternal": [
18
+ "@project-ajax/shared"
19
+ ],
17
20
  "splitting": false,
18
21
  "sourcemap": false,
19
22
  "clean": true,
@@ -29,8 +32,7 @@
29
32
  ],
30
33
  "dependencies": {
31
34
  "@inquirer/prompts": "^8.0.1",
32
- "chalk": "^5.3.0",
33
- "ora": "^8.0.1"
35
+ "@project-ajax/shared": "*"
34
36
  },
35
37
  "devDependencies": {
36
38
  "@types/node": "^22.19.0",