@jvittechs/jai1-cli 0.1.83 → 0.1.85

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/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/cli.ts
4
- import { Command as Command45 } from "commander";
4
+ import { Command as Command47 } from "commander";
5
5
 
6
6
  // src/errors/index.ts
7
7
  var Jai1Error = class extends Error {
@@ -33,7 +33,7 @@ var NetworkError = class extends Jai1Error {
33
33
  // package.json
34
34
  var package_default = {
35
35
  name: "@jvittechs/jai1-cli",
36
- version: "0.1.83",
36
+ version: "0.1.85",
37
37
  description: "A unified CLI tool for JV-IT TECHS developers to manage Jai1 Framework. Please contact TeamAI for usage instructions.",
38
38
  type: "module",
39
39
  bin: {
@@ -7238,14 +7238,417 @@ Quick Usage:
7238
7238
  return utilsCommand;
7239
7239
  }
7240
7240
 
7241
+ // src/commands/deps/index.ts
7242
+ import { Command as Command30 } from "commander";
7243
+
7244
+ // src/commands/deps/upgrade.ts
7245
+ import { Command as Command29 } from "commander";
7246
+ import { checkbox as checkbox3, confirm as confirm4 } from "@inquirer/prompts";
7247
+
7248
+ // src/services/deps.service.ts
7249
+ import { promises as fs9 } from "fs";
7250
+ import path6 from "path";
7251
+ import { execSync } from "child_process";
7252
+ import pLimit2 from "p-limit";
7253
+ var DepsService = class {
7254
+ versionCache = /* @__PURE__ */ new Map();
7255
+ /**
7256
+ * Đọc package.json từ thư mục
7257
+ */
7258
+ async readPackageJson(cwd) {
7259
+ const pkgPath = path6.join(cwd, "package.json");
7260
+ try {
7261
+ const content = await fs9.readFile(pkgPath, "utf-8");
7262
+ return JSON.parse(content);
7263
+ } catch (error) {
7264
+ if (error.code === "ENOENT") {
7265
+ throw new Error("Kh\xF4ng t\xECm th\u1EA5y package.json trong th\u01B0 m\u1EE5c hi\u1EC7n t\u1EA1i");
7266
+ }
7267
+ throw new Error(`L\u1ED7i \u0111\u1ECDc package.json: ${error.message}`);
7268
+ }
7269
+ }
7270
+ /**
7271
+ * Lấy version mới nhất từ npm registry
7272
+ */
7273
+ async fetchLatestVersion(packageName) {
7274
+ if (this.versionCache.has(packageName)) {
7275
+ return this.versionCache.get(packageName);
7276
+ }
7277
+ try {
7278
+ const response = await fetch(
7279
+ `https://registry.npmjs.org/${encodeURIComponent(packageName)}/latest`,
7280
+ { signal: AbortSignal.timeout(1e4) }
7281
+ );
7282
+ if (!response.ok) {
7283
+ return null;
7284
+ }
7285
+ const data = await response.json();
7286
+ this.versionCache.set(packageName, data.version);
7287
+ return data.version;
7288
+ } catch {
7289
+ return null;
7290
+ }
7291
+ }
7292
+ /**
7293
+ * Fetch nhiều packages cùng lúc với giới hạn concurrent
7294
+ */
7295
+ async fetchBulkVersions(packages, onProgress) {
7296
+ const limit = pLimit2(10);
7297
+ const total = packages.length;
7298
+ let completed = 0;
7299
+ const results = await Promise.all(
7300
+ packages.map(
7301
+ (pkg) => limit(async () => {
7302
+ const latest = await this.fetchLatestVersion(pkg.name);
7303
+ completed++;
7304
+ onProgress?.(completed, total);
7305
+ if (!latest) {
7306
+ return null;
7307
+ }
7308
+ const currentClean = this.stripSemverPrefix(pkg.current);
7309
+ const canUpgrade = this.isNewerVersion(latest, currentClean);
7310
+ return {
7311
+ name: pkg.name,
7312
+ current: pkg.current,
7313
+ latest,
7314
+ latestWithPrefix: this.preserveSemverPrefix(pkg.current, latest),
7315
+ type: pkg.type,
7316
+ canUpgrade
7317
+ };
7318
+ })
7319
+ )
7320
+ );
7321
+ return results.filter((r) => r !== null && r.canUpgrade);
7322
+ }
7323
+ /**
7324
+ * Loại bỏ semver prefix (^, ~, >=, etc.)
7325
+ */
7326
+ stripSemverPrefix(version) {
7327
+ return version.replace(/^[~^>=<]+/, "");
7328
+ }
7329
+ /**
7330
+ * Giữ nguyên semver prefix khi upgrade
7331
+ */
7332
+ preserveSemverPrefix(current, latest) {
7333
+ const match = current.match(/^([~^>=<]*)/);
7334
+ const prefix = match?.[1] || "";
7335
+ return prefix + latest;
7336
+ }
7337
+ /**
7338
+ * So sánh version để xác định có cần upgrade không
7339
+ */
7340
+ isNewerVersion(remote, local) {
7341
+ const remoteParts = remote.split(".").map(Number);
7342
+ const localParts = local.split(".").map(Number);
7343
+ for (let i = 0; i < 3; i++) {
7344
+ const r = remoteParts[i] || 0;
7345
+ const l = localParts[i] || 0;
7346
+ if (r > l) return true;
7347
+ if (r < l) return false;
7348
+ }
7349
+ return false;
7350
+ }
7351
+ /**
7352
+ * Detect package manager từ lock files
7353
+ * Priority:
7354
+ * 1. Lock file trong project
7355
+ * 2. pnpm nếu có cài đặt trong máy
7356
+ * 3. npm (fallback)
7357
+ */
7358
+ async detectPackageManager(cwd) {
7359
+ const lockFiles = [
7360
+ { file: "pnpm-lock.yaml", pm: "pnpm" },
7361
+ { file: "yarn.lock", pm: "yarn" },
7362
+ { file: "bun.lockb", pm: "bun" },
7363
+ { file: "package-lock.json", pm: "npm" }
7364
+ ];
7365
+ for (const { file, pm } of lockFiles) {
7366
+ try {
7367
+ await fs9.access(path6.join(cwd, file));
7368
+ return pm;
7369
+ } catch {
7370
+ }
7371
+ }
7372
+ const userAgent = process.env.npm_config_user_agent || "";
7373
+ if (userAgent.includes("pnpm")) return "pnpm";
7374
+ if (userAgent.includes("yarn")) return "yarn";
7375
+ if (userAgent.includes("bun")) return "bun";
7376
+ if (userAgent.includes("npm")) return "npm";
7377
+ if (this.isCommandAvailable("pnpm")) return "pnpm";
7378
+ return "npm";
7379
+ }
7380
+ /**
7381
+ * Kiểm tra command có sẵn trong hệ thống không
7382
+ */
7383
+ isCommandAvailable(command) {
7384
+ try {
7385
+ execSync(`${command} --version`, {
7386
+ stdio: ["pipe", "pipe", "pipe"]
7387
+ });
7388
+ return true;
7389
+ } catch {
7390
+ return false;
7391
+ }
7392
+ }
7393
+ /**
7394
+ * Tạo command để upgrade packages
7395
+ */
7396
+ getUpgradeCommands(packages, pm) {
7397
+ const deps = packages.filter((p) => p.type === "dep");
7398
+ const devDeps = packages.filter((p) => p.type === "dev");
7399
+ const formatPackages = (pkgs) => pkgs.map((p) => `${p.name}@${p.latestWithPrefix}`).join(" ");
7400
+ let depsCmd = null;
7401
+ let devDepsCmd = null;
7402
+ if (deps.length > 0) {
7403
+ const pkgList = formatPackages(deps);
7404
+ switch (pm) {
7405
+ case "pnpm":
7406
+ depsCmd = `pnpm add ${pkgList}`;
7407
+ break;
7408
+ case "yarn":
7409
+ depsCmd = `yarn add ${pkgList}`;
7410
+ break;
7411
+ case "bun":
7412
+ depsCmd = `bun add ${pkgList}`;
7413
+ break;
7414
+ default:
7415
+ depsCmd = `npm install ${pkgList}`;
7416
+ }
7417
+ }
7418
+ if (devDeps.length > 0) {
7419
+ const pkgList = formatPackages(devDeps);
7420
+ switch (pm) {
7421
+ case "pnpm":
7422
+ devDepsCmd = `pnpm add -D ${pkgList}`;
7423
+ break;
7424
+ case "yarn":
7425
+ devDepsCmd = `yarn add -D ${pkgList}`;
7426
+ break;
7427
+ case "bun":
7428
+ devDepsCmd = `bun add -D ${pkgList}`;
7429
+ break;
7430
+ default:
7431
+ devDepsCmd = `npm install -D ${pkgList}`;
7432
+ }
7433
+ }
7434
+ return { deps: depsCmd, devDeps: devDepsCmd };
7435
+ }
7436
+ /**
7437
+ * Thực thi upgrade command
7438
+ */
7439
+ executeUpgrade(command) {
7440
+ execSync(command, {
7441
+ stdio: "inherit",
7442
+ env: { ...process.env, FORCE_COLOR: "1" }
7443
+ });
7444
+ }
7445
+ };
7446
+
7447
+ // src/commands/deps/upgrade.ts
7448
+ var colors2 = {
7449
+ yellow: "\x1B[33m",
7450
+ green: "\x1B[32m",
7451
+ cyan: "\x1B[36m",
7452
+ red: "\x1B[31m",
7453
+ gray: "\x1B[90m",
7454
+ reset: "\x1B[0m",
7455
+ bold: "\x1B[1m",
7456
+ dim: "\x1B[2m"
7457
+ };
7458
+ function createDepsUpgradeCommand() {
7459
+ return new Command29("upgrade").description("Upgrade npm packages l\xEAn version m\u1EDBi nh\u1EA5t").option("--check", "Ch\u1EC9 ki\u1EC3m tra, kh\xF4ng upgrade").option("--all", "Upgrade t\u1EA5t c\u1EA3 kh\xF4ng c\u1EA7n ch\u1ECDn").option("--deps-only", "Ch\u1EC9 upgrade dependencies").option("--dev-only", "Ch\u1EC9 upgrade devDependencies").action(async (options) => {
7460
+ await handleDepsUpgrade(options);
7461
+ });
7462
+ }
7463
+ async function handleDepsUpgrade(options) {
7464
+ const depsService = new DepsService();
7465
+ const cwd = process.cwd();
7466
+ try {
7467
+ console.log(`
7468
+ ${colors2.cyan}\u{1F50D} \u0110ang \u0111\u1ECDc package.json...${colors2.reset}`);
7469
+ const pkg = await depsService.readPackageJson(cwd);
7470
+ const packagesToCheck = [];
7471
+ if (!options.devOnly && pkg.dependencies) {
7472
+ for (const [name, version] of Object.entries(pkg.dependencies)) {
7473
+ if (isNpmVersion(version)) {
7474
+ packagesToCheck.push({ name, current: version, type: "dep" });
7475
+ }
7476
+ }
7477
+ }
7478
+ if (!options.depsOnly && pkg.devDependencies) {
7479
+ for (const [name, version] of Object.entries(pkg.devDependencies)) {
7480
+ if (isNpmVersion(version)) {
7481
+ packagesToCheck.push({ name, current: version, type: "dev" });
7482
+ }
7483
+ }
7484
+ }
7485
+ if (packagesToCheck.length === 0) {
7486
+ console.log(`${colors2.yellow}\u26A0\uFE0F Kh\xF4ng t\xECm th\u1EA5y packages \u0111\u1EC3 ki\u1EC3m tra${colors2.reset}
7487
+ `);
7488
+ return;
7489
+ }
7490
+ const depsCount = packagesToCheck.filter((p) => p.type === "dep").length;
7491
+ const devCount = packagesToCheck.filter((p) => p.type === "dev").length;
7492
+ console.log(
7493
+ `${colors2.bold}\u{1F4E6} T\xECm th\u1EA5y ${depsCount} dependencies v\xE0 ${devCount} devDependencies${colors2.reset}
7494
+ `
7495
+ );
7496
+ console.log(`${colors2.cyan}\u23F3 Ki\u1EC3m tra phi\xEAn b\u1EA3n m\u1EDBi nh\u1EA5t...${colors2.reset}`);
7497
+ const upgradablePackages = await depsService.fetchBulkVersions(
7498
+ packagesToCheck,
7499
+ (completed, total) => {
7500
+ const progress = Math.round(completed / total * 100);
7501
+ const bar = "\u2588".repeat(Math.floor(progress / 5)) + "\u2591".repeat(20 - Math.floor(progress / 5));
7502
+ process.stdout.write(`\r[${bar}] ${completed}/${total} packages`);
7503
+ }
7504
+ );
7505
+ console.log("\n");
7506
+ if (upgradablePackages.length === 0) {
7507
+ console.log(`${colors2.green}\u2705 T\u1EA5t c\u1EA3 packages \u0111\xE3 l\xE0 phi\xEAn b\u1EA3n m\u1EDBi nh\u1EA5t!${colors2.reset}
7508
+ `);
7509
+ return;
7510
+ }
7511
+ displayUpgradeTable(upgradablePackages);
7512
+ if (options.check) {
7513
+ console.log(
7514
+ `${colors2.cyan}\u{1F4A1} Ch\u1EA1y "jai1 deps upgrade" \u0111\u1EC3 ti\u1EBFn h\xE0nh upgrade.${colors2.reset}
7515
+ `
7516
+ );
7517
+ return;
7518
+ }
7519
+ let selectedPackages;
7520
+ if (options.all) {
7521
+ selectedPackages = upgradablePackages;
7522
+ console.log(`${colors2.cyan}\u{1F4CB} \u0110\xE3 ch\u1ECDn t\u1EA5t c\u1EA3 ${selectedPackages.length} packages${colors2.reset}
7523
+ `);
7524
+ } else {
7525
+ try {
7526
+ const selected = await checkbox3({
7527
+ message: "Ch\u1ECDn packages \u0111\u1EC3 upgrade (ESC \u0111\u1EC3 h\u1EE7y):",
7528
+ choices: upgradablePackages.map((pkg2) => ({
7529
+ name: `${pkg2.name} (${pkg2.current} \u2192 ${pkg2.latestWithPrefix}) [${pkg2.type}]`,
7530
+ value: pkg2.name,
7531
+ checked: true
7532
+ // Mặc định chọn tất cả
7533
+ })),
7534
+ instructions: "\u2191\u2193 navigate \u2022 space select \u2022 a all \u2022 i invert \u2022 \u23CE submit \u2022 esc cancel"
7535
+ });
7536
+ if (selected.length === 0) {
7537
+ console.log(`${colors2.yellow}\u23F8\uFE0F Kh\xF4ng c\xF3 packages n\xE0o \u0111\u01B0\u1EE3c ch\u1ECDn${colors2.reset}
7538
+ `);
7539
+ return;
7540
+ }
7541
+ selectedPackages = upgradablePackages.filter((pkg2) => selected.includes(pkg2.name));
7542
+ } catch {
7543
+ console.log(`
7544
+ ${colors2.yellow}\u23F8\uFE0F \u0110\xE3 h\u1EE7y${colors2.reset}
7545
+ `);
7546
+ return;
7547
+ }
7548
+ }
7549
+ let shouldProceed;
7550
+ try {
7551
+ shouldProceed = await confirm4({
7552
+ message: `Ti\u1EBFn h\xE0nh upgrade ${selectedPackages.length} packages?`,
7553
+ default: true
7554
+ });
7555
+ } catch {
7556
+ console.log(`
7557
+ ${colors2.yellow}\u23F8\uFE0F \u0110\xE3 h\u1EE7y${colors2.reset}
7558
+ `);
7559
+ return;
7560
+ }
7561
+ if (!shouldProceed) {
7562
+ console.log(`${colors2.yellow}\u23F8\uFE0F Upgrade \u0111\xE3 h\u1EE7y${colors2.reset}
7563
+ `);
7564
+ return;
7565
+ }
7566
+ const pm = await depsService.detectPackageManager(cwd);
7567
+ console.log(`
7568
+ ${colors2.cyan}\u{1F527} Package manager: ${pm}${colors2.reset}`);
7569
+ console.log(`${colors2.cyan}\u{1F4E5} \u0110ang upgrade...${colors2.reset}
7570
+ `);
7571
+ const commands = depsService.getUpgradeCommands(selectedPackages, pm);
7572
+ try {
7573
+ if (commands.deps) {
7574
+ console.log(`${colors2.dim}$ ${commands.deps}${colors2.reset}
7575
+ `);
7576
+ depsService.executeUpgrade(commands.deps);
7577
+ }
7578
+ if (commands.devDeps) {
7579
+ console.log(`
7580
+ ${colors2.dim}$ ${commands.devDeps}${colors2.reset}
7581
+ `);
7582
+ depsService.executeUpgrade(commands.devDeps);
7583
+ }
7584
+ console.log(
7585
+ `
7586
+ ${colors2.green}\u2705 \u0110\xE3 upgrade ${selectedPackages.length} packages th\xE0nh c\xF4ng!${colors2.reset}
7587
+ `
7588
+ );
7589
+ } catch (error) {
7590
+ console.error(`
7591
+ ${colors2.red}\u274C L\u1ED7i khi upgrade:${colors2.reset}`);
7592
+ console.error(`${colors2.red}${error.message}${colors2.reset}
7593
+ `);
7594
+ console.log(`${colors2.yellow}\u{1F4A1} B\u1EA1n c\xF3 th\u1EC3 th\u1EED upgrade th\u1EE7 c\xF4ng:${colors2.reset}`);
7595
+ if (commands.deps) console.log(` ${colors2.cyan}${commands.deps}${colors2.reset}`);
7596
+ if (commands.devDeps) console.log(` ${colors2.cyan}${commands.devDeps}${colors2.reset}`);
7597
+ console.log("");
7598
+ process.exit(1);
7599
+ }
7600
+ } catch (error) {
7601
+ console.error(`
7602
+ ${colors2.red}\u274C ${error.message}${colors2.reset}
7603
+ `);
7604
+ process.exit(1);
7605
+ }
7606
+ }
7607
+ function isNpmVersion(version) {
7608
+ if (version.startsWith("git") || version.startsWith("github") || version.startsWith("file:") || version.startsWith("link:") || version.startsWith("workspace:") || version.includes("://")) {
7609
+ return false;
7610
+ }
7611
+ return true;
7612
+ }
7613
+ function displayUpgradeTable(packages) {
7614
+ console.log(`${colors2.bold}\u{1F4CA} C\xF3 th\u1EC3 upgrade:${colors2.reset}
7615
+ `);
7616
+ const nameWidth = Math.max(7, ...packages.map((p) => p.name.length));
7617
+ const currentWidth = Math.max(8, ...packages.map((p) => p.current.length));
7618
+ const latestWidth = Math.max(8, ...packages.map((p) => p.latestWithPrefix.length));
7619
+ const header = `\u2502 ${"Package".padEnd(nameWidth)} \u2502 ${"Hi\u1EC7n t\u1EA1i".padEnd(currentWidth)} \u2502 ${"M\u1EDBi nh\u1EA5t".padEnd(latestWidth)} \u2502 Lo\u1EA1i \u2502`;
7620
+ const separator = `\u251C${"\u2500".repeat(nameWidth + 2)}\u253C${"\u2500".repeat(currentWidth + 2)}\u253C${"\u2500".repeat(latestWidth + 2)}\u253C\u2500\u2500\u2500\u2500\u2500\u2500\u2524`;
7621
+ const topBorder = `\u250C${"\u2500".repeat(nameWidth + 2)}\u252C${"\u2500".repeat(currentWidth + 2)}\u252C${"\u2500".repeat(latestWidth + 2)}\u252C\u2500\u2500\u2500\u2500\u2500\u2500\u2510`;
7622
+ const bottomBorder = `\u2514${"\u2500".repeat(nameWidth + 2)}\u2534${"\u2500".repeat(currentWidth + 2)}\u2534${"\u2500".repeat(latestWidth + 2)}\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2518`;
7623
+ console.log(topBorder);
7624
+ console.log(header);
7625
+ console.log(separator);
7626
+ for (const pkg of packages) {
7627
+ const typeLabel = pkg.type === "dep" ? "dep " : "dev ";
7628
+ const typeColor = pkg.type === "dep" ? colors2.cyan : colors2.yellow;
7629
+ console.log(
7630
+ `\u2502 ${pkg.name.padEnd(nameWidth)} \u2502 ${colors2.gray}${pkg.current.padEnd(currentWidth)}${colors2.reset} \u2502 ${colors2.green}${pkg.latestWithPrefix.padEnd(latestWidth)}${colors2.reset} \u2502 ${typeColor}${typeLabel}${colors2.reset}\u2502`
7631
+ );
7632
+ }
7633
+ console.log(bottomBorder);
7634
+ console.log("");
7635
+ }
7636
+
7637
+ // src/commands/deps/index.ts
7638
+ function createDepsCommand() {
7639
+ const depsCommand = new Command30("deps").description("Qu\u1EA3n l\xFD dependencies trong project");
7640
+ depsCommand.addCommand(createDepsUpgradeCommand());
7641
+ return depsCommand;
7642
+ }
7643
+
7241
7644
  // src/commands/kit/index.ts
7242
- import { Command as Command32 } from "commander";
7645
+ import { Command as Command34 } from "commander";
7243
7646
 
7244
7647
  // src/commands/kit/list.ts
7245
- import { Command as Command29 } from "commander";
7648
+ import { Command as Command31 } from "commander";
7246
7649
 
7247
7650
  // src/services/starter-kit.service.ts
7248
- import { promises as fs9 } from "fs";
7651
+ import { promises as fs10 } from "fs";
7249
7652
  import { join as join4 } from "path";
7250
7653
  import AdmZip from "adm-zip";
7251
7654
  var StarterKitService = class {
@@ -7294,22 +7697,22 @@ var StarterKitService = class {
7294
7697
  }
7295
7698
  if (onProgress) onProgress(30);
7296
7699
  const tmpDir = join4(process.env.TMPDIR || "/tmp", "jai1-kits");
7297
- await fs9.mkdir(tmpDir, { recursive: true });
7700
+ await fs10.mkdir(tmpDir, { recursive: true });
7298
7701
  const tmpFile = join4(tmpDir, `${slug}.zip`);
7299
7702
  const buffer = await response.arrayBuffer();
7300
- await fs9.writeFile(tmpFile, Buffer.from(buffer));
7703
+ await fs10.writeFile(tmpFile, Buffer.from(buffer));
7301
7704
  if (onProgress) onProgress(60);
7302
7705
  const zip = new AdmZip(tmpFile);
7303
- await fs9.mkdir(targetDir, { recursive: true });
7706
+ await fs10.mkdir(targetDir, { recursive: true });
7304
7707
  zip.extractAllTo(targetDir, true);
7305
7708
  if (onProgress) onProgress(100);
7306
- await fs9.unlink(tmpFile);
7709
+ await fs10.unlink(tmpFile);
7307
7710
  }
7308
7711
  };
7309
7712
 
7310
7713
  // src/commands/kit/list.ts
7311
7714
  function createKitListCommand() {
7312
- return new Command29("list").description("List available starter kits").option("-c, --category <category>", "Filter by category (backend, frontend, fullstack)").option("-s, --search <term>", "Search kits by name or description").action(async (options) => {
7715
+ return new Command31("list").description("List available starter kits").option("-c, --category <category>", "Filter by category (backend, frontend, fullstack)").option("-s, --search <term>", "Search kits by name or description").action(async (options) => {
7313
7716
  const configService = new ConfigService();
7314
7717
  const config = await configService.load();
7315
7718
  if (!config) {
@@ -7346,9 +7749,9 @@ function createKitListCommand() {
7346
7749
  }
7347
7750
 
7348
7751
  // src/commands/kit/info.ts
7349
- import { Command as Command30 } from "commander";
7752
+ import { Command as Command32 } from "commander";
7350
7753
  function createKitInfoCommand() {
7351
- return new Command30("info").description("Show detailed information about a starter kit").argument("<slug>", "Starter kit slug").action(async (slug) => {
7754
+ return new Command32("info").description("Show detailed information about a starter kit").argument("<slug>", "Starter kit slug").action(async (slug) => {
7352
7755
  const configService = new ConfigService();
7353
7756
  const config = await configService.load();
7354
7757
  if (!config) {
@@ -7397,10 +7800,10 @@ Post-Init Commands:`);
7397
7800
  }
7398
7801
 
7399
7802
  // src/commands/kit/create.ts
7400
- import { Command as Command31 } from "commander";
7401
- import { promises as fs10 } from "fs";
7803
+ import { Command as Command33 } from "commander";
7804
+ import { promises as fs11 } from "fs";
7402
7805
  import { join as join5 } from "path";
7403
- import { select as select2, input, checkbox as checkbox3 } from "@inquirer/prompts";
7806
+ import { select as select2, input, checkbox as checkbox4 } from "@inquirer/prompts";
7404
7807
  import { execa as execa2 } from "execa";
7405
7808
 
7406
7809
  // src/services/hook-executor.service.ts
@@ -7442,7 +7845,7 @@ var HookExecutor = class {
7442
7845
 
7443
7846
  // src/commands/kit/create.ts
7444
7847
  function createKitCreateCommand() {
7445
- return new Command31("create").description("Create a new project from a starter kit").argument("<slug>", "Starter kit slug").argument("[directory]", "Project directory (default: ./<slug>)").option("-y, --yes", "Auto mode - use defaults, no prompts").option("--name <name>", "Project name").option("--skip-install", "Skip dependency installation").option("--skip-git", "Skip git initialization").option("--skip-framework", "Skip framework apply").option("--skip-ide", "Skip IDE sync").action(async (slug, directory, options) => {
7848
+ return new Command33("create").description("Create a new project from a starter kit").argument("<slug>", "Starter kit slug").argument("[directory]", "Project directory (default: ./<slug>)").option("-y, --yes", "Auto mode - use defaults, no prompts").option("--name <name>", "Project name").option("--skip-install", "Skip dependency installation").option("--skip-git", "Skip git initialization").option("--skip-framework", "Skip framework apply").option("--skip-ide", "Skip IDE sync").action(async (slug, directory, options) => {
7446
7849
  const configService = new ConfigService();
7447
7850
  const config = await configService.load();
7448
7851
  if (!config) {
@@ -7464,7 +7867,7 @@ function createKitCreateCommand() {
7464
7867
  }
7465
7868
  const targetDir = directory || join5(process.cwd(), options.name || slug);
7466
7869
  try {
7467
- await fs10.access(targetDir);
7870
+ await fs11.access(targetDir);
7468
7871
  throw new Error(`Directory already exists: ${targetDir}`);
7469
7872
  } catch (error) {
7470
7873
  if (error.code !== "ENOENT") {
@@ -7539,7 +7942,8 @@ function createKitCreateCommand() {
7539
7942
  const hookExecutor = new HookExecutor(targetDir, variables);
7540
7943
  await hookExecutor.run(kit.config.hooks.postInit);
7541
7944
  }
7542
- if (!options.skipIde) {
7945
+ const shouldPromptIdeSync = kit.config.ide?.promptSync !== false;
7946
+ if (!options.skipIde && shouldPromptIdeSync) {
7543
7947
  const ideChoices = [
7544
7948
  { name: "Cursor", value: "cursor" },
7545
7949
  { name: "Windsurf", value: "windsurf" },
@@ -7554,7 +7958,7 @@ function createKitCreateCommand() {
7554
7958
  }
7555
7959
  } else {
7556
7960
  const defaultTargets = kit.config.ide?.defaultTargets || [];
7557
- const answer = await checkbox3({
7961
+ const answer = await checkbox4({
7558
7962
  message: "Ch\u1ECDn IDE \u0111\u1EC3 sync framework:",
7559
7963
  choices: ideChoices.map((c) => ({
7560
7964
  ...c,
@@ -7581,7 +7985,7 @@ function createKitCreateCommand() {
7581
7985
  async function applyVariableSubstitution(dir, variables) {
7582
7986
  const files = await getAllFiles(dir);
7583
7987
  for (const file of files) {
7584
- let content = await fs10.readFile(file, "utf-8");
7988
+ let content = await fs11.readFile(file, "utf-8");
7585
7989
  let modified = false;
7586
7990
  for (const [key, value] of Object.entries(variables)) {
7587
7991
  const regex = new RegExp(`\\{\\{${key}\\}\\}`, "g");
@@ -7591,13 +7995,13 @@ async function applyVariableSubstitution(dir, variables) {
7591
7995
  }
7592
7996
  }
7593
7997
  if (modified) {
7594
- await fs10.writeFile(file, content, "utf-8");
7998
+ await fs11.writeFile(file, content, "utf-8");
7595
7999
  }
7596
8000
  }
7597
8001
  }
7598
8002
  async function getAllFiles(dir) {
7599
8003
  const files = [];
7600
- const entries = await fs10.readdir(dir, { withFileTypes: true });
8004
+ const entries = await fs11.readdir(dir, { withFileTypes: true });
7601
8005
  for (const entry of entries) {
7602
8006
  const fullPath = join5(dir, entry.name);
7603
8007
  if (entry.isDirectory()) {
@@ -7613,7 +8017,7 @@ async function getAllFiles(dir) {
7613
8017
 
7614
8018
  // src/commands/kit/index.ts
7615
8019
  function createKitCommand() {
7616
- const cmd = new Command32("kit").description("Manage starter kits for new projects").action(() => {
8020
+ const cmd = new Command34("kit").description("Manage starter kits for new projects").action(() => {
7617
8021
  cmd.help();
7618
8022
  });
7619
8023
  cmd.addCommand(createKitListCommand());
@@ -7623,10 +8027,10 @@ function createKitCommand() {
7623
8027
  }
7624
8028
 
7625
8029
  // src/commands/upgrade.ts
7626
- import { Command as Command33 } from "commander";
7627
- import { confirm as confirm4 } from "@inquirer/prompts";
7628
- import { execSync } from "child_process";
7629
- var colors2 = {
8030
+ import { Command as Command35 } from "commander";
8031
+ import { confirm as confirm5 } from "@inquirer/prompts";
8032
+ import { execSync as execSync2 } from "child_process";
8033
+ var colors3 = {
7630
8034
  yellow: "\x1B[33m",
7631
8035
  green: "\x1B[32m",
7632
8036
  cyan: "\x1B[36m",
@@ -7635,7 +8039,7 @@ var colors2 = {
7635
8039
  bold: "\x1B[1m"
7636
8040
  };
7637
8041
  function createUpgradeCommand() {
7638
- return new Command33("upgrade").description("Upgrade jai1-client to the latest version").option("--check", "Only check for updates without installing").option("--force", "Force upgrade without confirmation").action(async (options) => {
8042
+ return new Command35("upgrade").description("Upgrade jai1-client to the latest version").option("--check", "Only check for updates without installing").option("--force", "Force upgrade without confirmation").action(async (options) => {
7639
8043
  await handleUpgrade(options);
7640
8044
  });
7641
8045
  }
@@ -7646,7 +8050,7 @@ async function handleUpgrade(options) {
7646
8050
  throw new ValidationError('Not initialized. Run "jai1 auth" first.');
7647
8051
  }
7648
8052
  try {
7649
- console.log(`${colors2.cyan}\u{1F50D} Checking for updates...${colors2.reset}`);
8053
+ console.log(`${colors3.cyan}\u{1F50D} Checking for updates...${colors3.reset}`);
7650
8054
  const response = await fetch(`${config.apiUrl}/api/versions/client`, {
7651
8055
  headers: {
7652
8056
  "JAI1-Access-Key": config.accessKey
@@ -7661,47 +8065,47 @@ async function handleUpgrade(options) {
7661
8065
  const latestVersion = data.version;
7662
8066
  const currentVersion = package_default.version;
7663
8067
  console.log(`
7664
- ${colors2.bold}Current version:${colors2.reset} ${currentVersion}`);
7665
- console.log(`${colors2.bold}Latest version:${colors2.reset} ${latestVersion}
8068
+ ${colors3.bold}Current version:${colors3.reset} ${currentVersion}`);
8069
+ console.log(`${colors3.bold}Latest version:${colors3.reset} ${latestVersion}
7666
8070
  `);
7667
8071
  if (!isNewerVersion2(latestVersion, currentVersion)) {
7668
- console.log(`${colors2.green}\u2705 You're already on the latest version!${colors2.reset}
8072
+ console.log(`${colors3.green}\u2705 You're already on the latest version!${colors3.reset}
7669
8073
  `);
7670
8074
  return;
7671
8075
  }
7672
- console.log(`${colors2.yellow}\u256D\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256E${colors2.reset}`);
7673
- console.log(`${colors2.yellow}\u2502${colors2.reset} ${colors2.bold}\u2B06\uFE0F Update available!${colors2.reset} ${currentVersion} \u2192 ${colors2.cyan}${latestVersion}${colors2.reset} ${colors2.yellow}\u2502${colors2.reset}`);
7674
- console.log(`${colors2.yellow}\u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256F${colors2.reset}
8076
+ console.log(`${colors3.yellow}\u256D\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256E${colors3.reset}`);
8077
+ console.log(`${colors3.yellow}\u2502${colors3.reset} ${colors3.bold}\u2B06\uFE0F Update available!${colors3.reset} ${currentVersion} \u2192 ${colors3.cyan}${latestVersion}${colors3.reset} ${colors3.yellow}\u2502${colors3.reset}`);
8078
+ console.log(`${colors3.yellow}\u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256F${colors3.reset}
7675
8079
  `);
7676
8080
  if (options.check) {
7677
- console.log(`${colors2.cyan}Run "jai1 upgrade" to install the latest version.${colors2.reset}
8081
+ console.log(`${colors3.cyan}Run "jai1 upgrade" to install the latest version.${colors3.reset}
7678
8082
  `);
7679
8083
  return;
7680
8084
  }
7681
8085
  if (!options.force) {
7682
- const shouldUpdate = await confirm4({
8086
+ const shouldUpdate = await confirm5({
7683
8087
  message: "Update to the latest version now?",
7684
8088
  default: true
7685
8089
  });
7686
8090
  if (!shouldUpdate) {
7687
- console.log(`${colors2.yellow}\u23F8\uFE0F Upgrade cancelled.${colors2.reset}
8091
+ console.log(`${colors3.yellow}\u23F8\uFE0F Upgrade cancelled.${colors3.reset}
7688
8092
  `);
7689
8093
  return;
7690
8094
  }
7691
8095
  }
7692
8096
  console.log(`
7693
- ${colors2.cyan}\u{1F4E5} Installing latest version...${colors2.reset}
8097
+ ${colors3.cyan}\u{1F4E5} Installing latest version...${colors3.reset}
7694
8098
  `);
7695
8099
  try {
7696
8100
  const packageManager2 = detectPackageManager();
7697
8101
  const installCommand = getInstallCommand(packageManager2);
7698
- console.log(`${colors2.cyan}Using ${packageManager2}...${colors2.reset}`);
7699
- execSync(installCommand, {
8102
+ console.log(`${colors3.cyan}Using ${packageManager2}...${colors3.reset}`);
8103
+ execSync2(installCommand, {
7700
8104
  stdio: "inherit",
7701
8105
  env: { ...process.env, FORCE_COLOR: "1" }
7702
8106
  });
7703
8107
  console.log(`
7704
- ${colors2.green}\u2705 Successfully upgraded to version ${latestVersion}!${colors2.reset}
8108
+ ${colors3.green}\u2705 Successfully upgraded to version ${latestVersion}!${colors3.reset}
7705
8109
  `);
7706
8110
  trackAction("upgrade", {
7707
8111
  from_version: currentVersion,
@@ -7711,17 +8115,17 @@ ${colors2.green}\u2705 Successfully upgraded to version ${latestVersion}!${color
7711
8115
  disableUpdateCheck();
7712
8116
  } catch (error) {
7713
8117
  console.error(`
7714
- ${colors2.red}\u274C Upgrade failed!${colors2.reset}`);
7715
- console.error(`${colors2.red}Error: ${error instanceof Error ? error.message : "Unknown error"}${colors2.reset}
8118
+ ${colors3.red}\u274C Upgrade failed!${colors3.reset}`);
8119
+ console.error(`${colors3.red}Error: ${error instanceof Error ? error.message : "Unknown error"}${colors3.reset}
7716
8120
  `);
7717
- console.error(`${colors2.yellow}\u{1F4A1} You can try manually upgrading with:${colors2.reset}`);
8121
+ console.error(`${colors3.yellow}\u{1F4A1} You can try manually upgrading with:${colors3.reset}`);
7718
8122
  const manualCommands = {
7719
8123
  npm: `npm install -g @jvittechs/jai1-cli@latest`,
7720
8124
  pnpm: `pnpm add -g @jvittechs/jai1-cli@latest`,
7721
8125
  yarn: `yarn global add @jvittechs/jai1-cli@latest`,
7722
8126
  bun: `bun add -g @jvittechs/jai1-cli@latest`
7723
8127
  };
7724
- console.error(` ${colors2.cyan}${manualCommands[packageManager]}${colors2.reset}
8128
+ console.error(` ${colors3.cyan}${manualCommands[packageManager]}${colors3.reset}
7725
8129
  `);
7726
8130
  throw error;
7727
8131
  }
@@ -7745,7 +8149,7 @@ function isNewerVersion2(remote, local) {
7745
8149
  }
7746
8150
  function detectPackageManager() {
7747
8151
  try {
7748
- const jai1Path = execSync("which jai1 || where jai1", {
8152
+ const jai1Path = execSync2("which jai1 || where jai1", {
7749
8153
  encoding: "utf-8",
7750
8154
  stdio: ["pipe", "pipe", "ignore"]
7751
8155
  }).trim();
@@ -7783,11 +8187,11 @@ function getInstallCommand(packageManager2) {
7783
8187
  }
7784
8188
 
7785
8189
  // src/commands/clean.ts
7786
- import { Command as Command34 } from "commander";
7787
- import { confirm as confirm5, select as select3 } from "@inquirer/prompts";
8190
+ import { Command as Command36 } from "commander";
8191
+ import { confirm as confirm6, select as select3 } from "@inquirer/prompts";
7788
8192
  import { join as join6 } from "path";
7789
8193
  function createCleanCommand() {
7790
- return new Command34("clean").description("Clean up backups, cache, and temporary files").option("-y, --yes", "Skip confirmation").option("--backups", "Clean only backup files").option("--all", "Clean all (backups + cache)").action(async (options) => {
8194
+ return new Command36("clean").description("Clean up backups, cache, and temporary files").option("-y, --yes", "Skip confirmation").option("--backups", "Clean only backup files").option("--all", "Clean all (backups + cache)").action(async (options) => {
7791
8195
  await handleClean(options);
7792
8196
  });
7793
8197
  }
@@ -7882,7 +8286,7 @@ async function cleanTarget(target, skipConfirm) {
7882
8286
  }
7883
8287
  const countStr = info.count ? ` (${info.count} items)` : "";
7884
8288
  if (!skipConfirm) {
7885
- const confirmed = await confirm5({
8289
+ const confirmed = await confirm6({
7886
8290
  message: `Delete ${target.name}${countStr}?`,
7887
8291
  default: false
7888
8292
  });
@@ -7900,7 +8304,7 @@ async function cleanTarget(target, skipConfirm) {
7900
8304
  }
7901
8305
 
7902
8306
  // src/commands/redmine/check.ts
7903
- import { Command as Command35 } from "commander";
8307
+ import { Command as Command37 } from "commander";
7904
8308
 
7905
8309
  // src/services/redmine-config.service.ts
7906
8310
  import { readFile as readFile6 } from "fs/promises";
@@ -8001,7 +8405,7 @@ var RedmineConfigService = class {
8001
8405
  // src/api.ts
8002
8406
  import { fetch as fetch2 } from "undici";
8003
8407
  import pRetry2 from "p-retry";
8004
- import pLimit2 from "p-limit";
8408
+ import pLimit3 from "p-limit";
8005
8409
  var RedmineApiError = class extends Error {
8006
8410
  constructor(message, status, response) {
8007
8411
  super(message);
@@ -8019,10 +8423,10 @@ var RedmineApiClient = class {
8019
8423
  this.baseUrl = config.baseUrl.replace(/\/$/, "");
8020
8424
  this.apiAccessToken = config.apiAccessToken;
8021
8425
  this.retryConfig = config.defaults.retry;
8022
- this.concurrencyLimit = pLimit2(config.defaults.concurrency);
8426
+ this.concurrencyLimit = pLimit3(config.defaults.concurrency);
8023
8427
  }
8024
- async request(path7, options = {}) {
8025
- const url = `${this.baseUrl}${path7}`;
8428
+ async request(path8, options = {}) {
8429
+ const url = `${this.baseUrl}${path8}`;
8026
8430
  const headers = {
8027
8431
  "X-Redmine-API-Key": this.apiAccessToken,
8028
8432
  "Content-Type": "application/json",
@@ -8083,8 +8487,8 @@ var RedmineApiClient = class {
8083
8487
  if (include && include.length > 0) {
8084
8488
  params.append("include", include.join(","));
8085
8489
  }
8086
- const path7 = `/issues/${issueId}.json${params.toString() ? `?${params.toString()}` : ""}`;
8087
- return this.request(path7);
8490
+ const path8 = `/issues/${issueId}.json${params.toString() ? `?${params.toString()}` : ""}`;
8491
+ return this.request(path8);
8088
8492
  }
8089
8493
  async getIssues(projectId, options = {}) {
8090
8494
  const params = new URLSearchParams();
@@ -8104,8 +8508,8 @@ var RedmineApiClient = class {
8104
8508
  if (options.updatedSince) {
8105
8509
  params.append("updated_on", `>=${options.updatedSince}`);
8106
8510
  }
8107
- const path7 = `/issues.json?${params.toString()}`;
8108
- return this.request(path7);
8511
+ const path8 = `/issues.json?${params.toString()}`;
8512
+ return this.request(path8);
8109
8513
  }
8110
8514
  async getAllIssues(projectId, options = {}) {
8111
8515
  const pageSize = options.pageSize || 100;
@@ -8207,7 +8611,7 @@ async function checkConnectivity(config) {
8207
8611
 
8208
8612
  // src/commands/redmine/check.ts
8209
8613
  function createRedmineCheckCommand() {
8210
- const cmd = new Command35("check").description("Check Redmine connectivity").option("-c, --config <path>", "Config file path", "redmine.config.yaml").option("--json", "Output as JSON").action(async (options) => {
8614
+ const cmd = new Command37("check").description("Check Redmine connectivity").option("-c, --config <path>", "Config file path", "redmine.config.yaml").option("--json", "Output as JSON").action(async (options) => {
8211
8615
  await handleRedmineCheck(options);
8212
8616
  });
8213
8617
  return cmd;
@@ -8235,7 +8639,7 @@ async function handleRedmineCheck(options) {
8235
8639
  }
8236
8640
 
8237
8641
  // src/commands/redmine/sync-issue.ts
8238
- import { Command as Command36 } from "commander";
8642
+ import { Command as Command38 } from "commander";
8239
8643
 
8240
8644
  // src/sync-issue.ts
8241
8645
  import { resolve as resolve3, relative } from "path";
@@ -8611,7 +9015,7 @@ function extractIssueIdFromUrl(url) {
8611
9015
 
8612
9016
  // src/commands/redmine/sync-issue.ts
8613
9017
  function createSyncIssueCommand() {
8614
- const cmd = new Command36("issue").description("Sync a single issue").option("-i, --id <number>", "Issue ID").option("-u, --url <url>", "Issue URL").option("--dry-run", "Preview without making changes").option("-c, --config <path>", "Config file path").option("-o, --output-dir <path>", "Output directory").option("--json", "Output as JSON").action(async (options) => {
9018
+ const cmd = new Command38("issue").description("Sync a single issue").option("-i, --id <number>", "Issue ID").option("-u, --url <url>", "Issue URL").option("--dry-run", "Preview without making changes").option("-c, --config <path>", "Config file path").option("-o, --output-dir <path>", "Output directory").option("--json", "Output as JSON").action(async (options) => {
8615
9019
  await handleSyncIssue(options);
8616
9020
  });
8617
9021
  return cmd;
@@ -8655,7 +9059,7 @@ async function handleSyncIssue(options) {
8655
9059
  }
8656
9060
 
8657
9061
  // src/commands/redmine/sync-project.ts
8658
- import { Command as Command37 } from "commander";
9062
+ import { Command as Command39 } from "commander";
8659
9063
 
8660
9064
  // src/sync-project.ts
8661
9065
  async function syncProject(config, options = {}) {
@@ -8725,7 +9129,7 @@ async function syncProject(config, options = {}) {
8725
9129
 
8726
9130
  // src/commands/redmine/sync-project.ts
8727
9131
  function createSyncProjectCommand() {
8728
- const cmd = new Command37("project").description("Sync all issues in a project").option("-s, --status <status>", "Filter by status (default: *)", "*").option("--updated-since <date>", "Only sync issues updated since YYYY-MM-DD").option("--concurrency <number>", "Number of concurrent requests").option("--page-size <number>", "Page size for API requests").option("--dry-run", "Preview without making changes").option("-c, --config <path>", "Config file path").option("-o, --output-dir <path>", "Output directory").option("--json", "Output as JSON").action(async (options) => {
9132
+ const cmd = new Command39("project").description("Sync all issues in a project").option("-s, --status <status>", "Filter by status (default: *)", "*").option("--updated-since <date>", "Only sync issues updated since YYYY-MM-DD").option("--concurrency <number>", "Number of concurrent requests").option("--page-size <number>", "Page size for API requests").option("--dry-run", "Preview without making changes").option("-c, --config <path>", "Config file path").option("-o, --output-dir <path>", "Output directory").option("--json", "Output as JSON").action(async (options) => {
8729
9133
  await handleSyncProject(options);
8730
9134
  });
8731
9135
  return cmd;
@@ -8780,12 +9184,12 @@ async function handleSyncProject(options) {
8780
9184
  }
8781
9185
 
8782
9186
  // src/commands/framework/info.ts
8783
- import { Command as Command38 } from "commander";
8784
- import { promises as fs11 } from "fs";
9187
+ import { Command as Command40 } from "commander";
9188
+ import { promises as fs12 } from "fs";
8785
9189
  import { join as join7 } from "path";
8786
9190
  import { homedir as homedir5 } from "os";
8787
9191
  function createInfoCommand() {
8788
- const cmd = new Command38("info").description("Show jai1-client configuration and status").option("--json", "Output as JSON").option("--verbose", "Show detailed information").action(async (options) => {
9192
+ const cmd = new Command40("info").description("Show jai1-client configuration and status").option("--json", "Output as JSON").option("--verbose", "Show detailed information").action(async (options) => {
8789
9193
  await handleInfo(options);
8790
9194
  });
8791
9195
  return cmd;
@@ -8833,7 +9237,7 @@ function maskKey3(key) {
8833
9237
  async function getProjectStatus2() {
8834
9238
  const projectJai1 = join7(process.cwd(), ".jai1");
8835
9239
  try {
8836
- await fs11.access(projectJai1);
9240
+ await fs12.access(projectJai1);
8837
9241
  return { exists: true, version: "Synced" };
8838
9242
  } catch {
8839
9243
  return { exists: false };
@@ -8841,10 +9245,10 @@ async function getProjectStatus2() {
8841
9245
  }
8842
9246
 
8843
9247
  // src/commands/self-update.ts
8844
- import { Command as Command39 } from "commander";
8845
- import { confirm as confirm6 } from "@inquirer/prompts";
8846
- import { execSync as execSync2 } from "child_process";
8847
- var colors3 = {
9248
+ import { Command as Command41 } from "commander";
9249
+ import { confirm as confirm7 } from "@inquirer/prompts";
9250
+ import { execSync as execSync3 } from "child_process";
9251
+ var colors4 = {
8848
9252
  yellow: "\x1B[33m",
8849
9253
  green: "\x1B[32m",
8850
9254
  cyan: "\x1B[36m",
@@ -8853,7 +9257,7 @@ var colors3 = {
8853
9257
  bold: "\x1B[1m"
8854
9258
  };
8855
9259
  function createSelfUpdateCommand() {
8856
- return new Command39("self-update").description("Update jai1-client to the latest version").option("--check", "Only check for updates without installing").option("--force", "Force update without confirmation").action(async (options) => {
9260
+ return new Command41("self-update").description("Update jai1-client to the latest version").option("--check", "Only check for updates without installing").option("--force", "Force update without confirmation").action(async (options) => {
8857
9261
  await handleSelfUpdate(options);
8858
9262
  });
8859
9263
  }
@@ -8864,7 +9268,7 @@ async function handleSelfUpdate(options) {
8864
9268
  throw new ValidationError('Not initialized. Run "jai1 auth" first.');
8865
9269
  }
8866
9270
  try {
8867
- console.log(`${colors3.cyan}\u{1F50D} Checking for updates...${colors3.reset}`);
9271
+ console.log(`${colors4.cyan}\u{1F50D} Checking for updates...${colors4.reset}`);
8868
9272
  const response = await fetch(`${config.apiUrl}/api/versions/client`, {
8869
9273
  headers: {
8870
9274
  "JAI1-Access-Key": config.accessKey
@@ -8879,47 +9283,47 @@ async function handleSelfUpdate(options) {
8879
9283
  const latestVersion = data.version;
8880
9284
  const currentVersion = package_default.version;
8881
9285
  console.log(`
8882
- ${colors3.bold}Current version:${colors3.reset} ${currentVersion}`);
8883
- console.log(`${colors3.bold}Latest version:${colors3.reset} ${latestVersion}
9286
+ ${colors4.bold}Current version:${colors4.reset} ${currentVersion}`);
9287
+ console.log(`${colors4.bold}Latest version:${colors4.reset} ${latestVersion}
8884
9288
  `);
8885
9289
  if (!isNewerVersion3(latestVersion, currentVersion)) {
8886
- console.log(`${colors3.green}\u2705 You're already on the latest version!${colors3.reset}
9290
+ console.log(`${colors4.green}\u2705 You're already on the latest version!${colors4.reset}
8887
9291
  `);
8888
9292
  return;
8889
9293
  }
8890
- console.log(`${colors3.yellow}\u256D\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256E${colors3.reset}`);
8891
- console.log(`${colors3.yellow}\u2502${colors3.reset} ${colors3.bold}\u2B06\uFE0F Update available!${colors3.reset} ${currentVersion} \u2192 ${colors3.cyan}${latestVersion}${colors3.reset} ${colors3.yellow}\u2502${colors3.reset}`);
8892
- console.log(`${colors3.yellow}\u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256F${colors3.reset}
9294
+ console.log(`${colors4.yellow}\u256D\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256E${colors4.reset}`);
9295
+ console.log(`${colors4.yellow}\u2502${colors4.reset} ${colors4.bold}\u2B06\uFE0F Update available!${colors4.reset} ${currentVersion} \u2192 ${colors4.cyan}${latestVersion}${colors4.reset} ${colors4.yellow}\u2502${colors4.reset}`);
9296
+ console.log(`${colors4.yellow}\u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256F${colors4.reset}
8893
9297
  `);
8894
9298
  if (options.check) {
8895
- console.log(`${colors3.cyan}Run "jai1 self-update" to install the latest version.${colors3.reset}
9299
+ console.log(`${colors4.cyan}Run "jai1 self-update" to install the latest version.${colors4.reset}
8896
9300
  `);
8897
9301
  return;
8898
9302
  }
8899
9303
  if (!options.force) {
8900
- const shouldUpdate = await confirm6({
9304
+ const shouldUpdate = await confirm7({
8901
9305
  message: "Update to the latest version now?",
8902
9306
  default: true
8903
9307
  });
8904
9308
  if (!shouldUpdate) {
8905
- console.log(`${colors3.yellow}\u23F8\uFE0F Update cancelled.${colors3.reset}
9309
+ console.log(`${colors4.yellow}\u23F8\uFE0F Update cancelled.${colors4.reset}
8906
9310
  `);
8907
9311
  return;
8908
9312
  }
8909
9313
  }
8910
9314
  console.log(`
8911
- ${colors3.cyan}\u{1F4E5} Installing latest version...${colors3.reset}
9315
+ ${colors4.cyan}\u{1F4E5} Installing latest version...${colors4.reset}
8912
9316
  `);
8913
9317
  try {
8914
9318
  const packageManager2 = detectPackageManager2();
8915
9319
  const installCommand = getInstallCommand2(packageManager2);
8916
- console.log(`${colors3.cyan}Using ${packageManager2}...${colors3.reset}`);
8917
- execSync2(installCommand, {
9320
+ console.log(`${colors4.cyan}Using ${packageManager2}...${colors4.reset}`);
9321
+ execSync3(installCommand, {
8918
9322
  stdio: "inherit",
8919
9323
  env: { ...process.env, FORCE_COLOR: "1" }
8920
9324
  });
8921
9325
  console.log(`
8922
- ${colors3.green}\u2705 Successfully updated to version ${latestVersion}!${colors3.reset}
9326
+ ${colors4.green}\u2705 Successfully updated to version ${latestVersion}!${colors4.reset}
8923
9327
  `);
8924
9328
  trackAction("self_update", {
8925
9329
  from_version: currentVersion,
@@ -8929,11 +9333,11 @@ ${colors3.green}\u2705 Successfully updated to version ${latestVersion}!${colors
8929
9333
  disableUpdateCheck();
8930
9334
  } catch (error) {
8931
9335
  console.error(`
8932
- ${colors3.red}\u274C Update failed!${colors3.reset}`);
8933
- console.error(`${colors3.red}Error: ${error instanceof Error ? error.message : "Unknown error"}${colors3.reset}
9336
+ ${colors4.red}\u274C Update failed!${colors4.reset}`);
9337
+ console.error(`${colors4.red}Error: ${error instanceof Error ? error.message : "Unknown error"}${colors4.reset}
8934
9338
  `);
8935
- console.error(`${colors3.yellow}\u{1F4A1} You can try manually updating with:${colors3.reset}`);
8936
- console.error(` ${colors3.cyan}npm install -g @jvittechs/jai1-cli@latest${colors3.reset}
9339
+ console.error(`${colors4.yellow}\u{1F4A1} You can try manually updating with:${colors4.reset}`);
9340
+ console.error(` ${colors4.cyan}npm install -g @jvittechs/jai1-cli@latest${colors4.reset}
8937
9341
  `);
8938
9342
  throw error;
8939
9343
  }
@@ -8961,17 +9365,17 @@ function detectPackageManager2() {
8961
9365
  if (userAgent.includes("yarn")) return "yarn";
8962
9366
  if (userAgent.includes("bun")) return "bun";
8963
9367
  try {
8964
- execSync2("pnpm --version", { stdio: "ignore" });
9368
+ execSync3("pnpm --version", { stdio: "ignore" });
8965
9369
  return "pnpm";
8966
9370
  } catch {
8967
9371
  }
8968
9372
  try {
8969
- execSync2("yarn --version", { stdio: "ignore" });
9373
+ execSync3("yarn --version", { stdio: "ignore" });
8970
9374
  return "yarn";
8971
9375
  } catch {
8972
9376
  }
8973
9377
  try {
8974
- execSync2("bun --version", { stdio: "ignore" });
9378
+ execSync3("bun --version", { stdio: "ignore" });
8975
9379
  return "bun";
8976
9380
  } catch {
8977
9381
  }
@@ -8993,10 +9397,10 @@ function getInstallCommand2(packageManager2) {
8993
9397
  }
8994
9398
 
8995
9399
  // src/commands/clear-backups.ts
8996
- import { Command as Command40 } from "commander";
8997
- import { confirm as confirm7 } from "@inquirer/prompts";
9400
+ import { Command as Command42 } from "commander";
9401
+ import { confirm as confirm8 } from "@inquirer/prompts";
8998
9402
  function createClearBackupsCommand() {
8999
- return new Command40("clear-backups").description("Clear backup files").option("-y, --yes", "Skip confirmation").action(async (options) => {
9403
+ return new Command42("clear-backups").description("Clear backup files").option("-y, --yes", "Skip confirmation").action(async (options) => {
9000
9404
  const service = new ComponentsService();
9001
9405
  const backups = await service.listBackups(process.cwd());
9002
9406
  if (backups.length === 0) {
@@ -9012,7 +9416,7 @@ function createClearBackupsCommand() {
9012
9416
  }
9013
9417
  console.log();
9014
9418
  if (!options.yes) {
9015
- const ok = await confirm7({ message: "Delete all backups?", default: false });
9419
+ const ok = await confirm8({ message: "Delete all backups?", default: false });
9016
9420
  if (!ok) return;
9017
9421
  }
9018
9422
  await service.clearBackups(process.cwd());
@@ -9021,10 +9425,10 @@ function createClearBackupsCommand() {
9021
9425
  }
9022
9426
 
9023
9427
  // src/commands/vscode/index.ts
9024
- import { Command as Command41 } from "commander";
9025
- import { checkbox as checkbox4, confirm as confirm8, select as select4 } from "@inquirer/prompts";
9026
- import fs12 from "fs/promises";
9027
- import path6 from "path";
9428
+ import { Command as Command43 } from "commander";
9429
+ import { checkbox as checkbox5, confirm as confirm9, select as select4 } from "@inquirer/prompts";
9430
+ import fs13 from "fs/promises";
9431
+ import path7 from "path";
9028
9432
  import { existsSync as existsSync3 } from "fs";
9029
9433
  var PERFORMANCE_GROUPS2 = {
9030
9434
  telemetry: {
@@ -9161,7 +9565,7 @@ var PERFORMANCE_GROUPS2 = {
9161
9565
  }
9162
9566
  };
9163
9567
  function createVSCodeCommand() {
9164
- const vscodeCommand = new Command41("vscode").description("Qu\u1EA3n l\xFD c\xE0i \u0111\u1EB7t VSCode cho d\u1EF1 \xE1n hi\u1EC7n t\u1EA1i");
9568
+ const vscodeCommand = new Command43("vscode").description("Qu\u1EA3n l\xFD c\xE0i \u0111\u1EB7t VSCode cho d\u1EF1 \xE1n hi\u1EC7n t\u1EA1i");
9165
9569
  vscodeCommand.action(async () => {
9166
9570
  await interactiveMode2();
9167
9571
  });
@@ -9229,7 +9633,7 @@ async function selectGroupsToApply2(action) {
9229
9633
  value: key
9230
9634
  }));
9231
9635
  try {
9232
- const selectedGroups = await checkbox4({
9636
+ const selectedGroups = await checkbox5({
9233
9637
  message: `Ch\u1ECDn c\xE1c nh\xF3m \u0111\u1EC3 ${action === "enable" ? "enable" : "disable"} (SPACE \u0111\u1EC3 ch\u1ECDn, ENTER \u0111\u1EC3 x\xE1c nh\u1EADn):`,
9234
9638
  choices
9235
9639
  });
@@ -9244,8 +9648,8 @@ async function selectGroupsToApply2(action) {
9244
9648
  }
9245
9649
  }
9246
9650
  async function applyGroups2(groupKeys, action) {
9247
- const vscodeDir = path6.join(process.cwd(), ".vscode");
9248
- const settingsPath = path6.join(vscodeDir, "settings.json");
9651
+ const vscodeDir = path7.join(process.cwd(), ".vscode");
9652
+ const settingsPath = path7.join(vscodeDir, "settings.json");
9249
9653
  const invalidGroups = groupKeys.filter((key) => !PERFORMANCE_GROUPS2[key]);
9250
9654
  if (invalidGroups.length > 0) {
9251
9655
  console.log(`
@@ -9254,18 +9658,18 @@ async function applyGroups2(groupKeys, action) {
9254
9658
  return;
9255
9659
  }
9256
9660
  if (!existsSync3(vscodeDir)) {
9257
- await fs12.mkdir(vscodeDir, { recursive: true });
9661
+ await fs13.mkdir(vscodeDir, { recursive: true });
9258
9662
  console.log("\u{1F4C1} \u0110\xE3 t\u1EA1o th\u01B0 m\u1EE5c .vscode/");
9259
9663
  }
9260
9664
  let currentSettings = {};
9261
9665
  if (existsSync3(settingsPath)) {
9262
9666
  try {
9263
- const content = await fs12.readFile(settingsPath, "utf-8");
9667
+ const content = await fs13.readFile(settingsPath, "utf-8");
9264
9668
  currentSettings = JSON.parse(content);
9265
9669
  console.log("\u{1F4C4} \u0110\xE3 \u0111\u1ECDc c\xE0i \u0111\u1EB7t hi\u1EC7n t\u1EA1i t\u1EEB settings.json");
9266
9670
  } catch {
9267
9671
  console.warn("\u26A0\uFE0F Kh\xF4ng th\u1EC3 \u0111\u1ECDc settings.json (c\xF3 th\u1EC3 ch\u1EE9a comments).");
9268
- const confirmOverwrite = await confirm8({
9672
+ const confirmOverwrite = await confirm9({
9269
9673
  message: "Ghi \u0111\xE8 file settings.json hi\u1EC7n t\u1EA1i?",
9270
9674
  default: false
9271
9675
  });
@@ -9300,19 +9704,19 @@ async function applyGroups2(groupKeys, action) {
9300
9704
  }
9301
9705
  }
9302
9706
  }
9303
- await fs12.writeFile(settingsPath, JSON.stringify(newSettings, null, 2));
9707
+ await fs13.writeFile(settingsPath, JSON.stringify(newSettings, null, 2));
9304
9708
  console.log(`
9305
9709
  \u2705 \u0110\xE3 c\u1EADp nh\u1EADt c\xE0i \u0111\u1EB7t VSCode t\u1EA1i: ${settingsPath}`);
9306
9710
  console.log("\u{1F4A1} M\u1EB9o: Kh\u1EDFi \u0111\u1ED9ng l\u1EA1i VSCode \u0111\u1EC3 \xE1p d\u1EE5ng c\xE1c thay \u0111\u1ED5i.");
9307
9711
  }
9308
9712
  async function resetSettings2(groupKeys) {
9309
- const vscodeDir = path6.join(process.cwd(), ".vscode");
9310
- const settingsPath = path6.join(vscodeDir, "settings.json");
9713
+ const vscodeDir = path7.join(process.cwd(), ".vscode");
9714
+ const settingsPath = path7.join(vscodeDir, "settings.json");
9311
9715
  if (!existsSync3(settingsPath)) {
9312
9716
  console.log("\n\u26A0\uFE0F Kh\xF4ng t\xECm th\u1EA5y file settings.json");
9313
9717
  return;
9314
9718
  }
9315
- const confirmReset = await confirm8({
9719
+ const confirmReset = await confirm9({
9316
9720
  message: groupKeys.length === 0 ? "Reset T\u1EA4T C\u1EA2 settings v\u1EC1 m\u1EB7c \u0111\u1ECBnh (x\xF3a to\xE0n b\u1ED9 file)?" : `Reset c\xE1c nh\xF3m: ${groupKeys.join(", ")}?`,
9317
9721
  default: false
9318
9722
  });
@@ -9321,7 +9725,7 @@ async function resetSettings2(groupKeys) {
9321
9725
  return;
9322
9726
  }
9323
9727
  if (groupKeys.length === 0) {
9324
- await fs12.unlink(settingsPath);
9728
+ await fs13.unlink(settingsPath);
9325
9729
  console.log("\n\u2705 \u0110\xE3 x\xF3a file settings.json");
9326
9730
  } else {
9327
9731
  await applyGroups2(groupKeys, "disable");
@@ -9332,9 +9736,9 @@ async function resetSettings2(groupKeys) {
9332
9736
  // src/commands/guide.ts
9333
9737
  import React40 from "react";
9334
9738
  import { render as render6 } from "ink";
9335
- import { Command as Command42 } from "commander";
9739
+ import { Command as Command44 } from "commander";
9336
9740
  function createGuideCommand() {
9337
- const cmd = new Command42("guide").description("Interactive guide center for Agentic Coding").option("--topic <topic>", "Open specific topic (intro, rules, workflows, prompts, skills)").action(async (options) => {
9741
+ const cmd = new Command44("guide").description("Interactive guide center for Agentic Coding").option("--topic <topic>", "Open specific topic (intro, rules, workflows, prompts, skills)").action(async (options) => {
9338
9742
  const { waitUntilExit } = render6(
9339
9743
  React40.createElement(GuideApp, {
9340
9744
  initialTopic: options.topic,
@@ -9351,9 +9755,9 @@ function createGuideCommand() {
9351
9755
  // src/commands/context.ts
9352
9756
  import React41 from "react";
9353
9757
  import { render as render7 } from "ink";
9354
- import { Command as Command43 } from "commander";
9758
+ import { Command as Command45 } from "commander";
9355
9759
  function createContextCommand() {
9356
- const cmd = new Command43("context").description("Kh\xE1m ph\xE1 v\xE0 qu\u1EA3n l\xFD context d\u1EF1 \xE1n cho c\xE1c IDE").option("--ide <ide>", "M\u1EDF tr\u1EF1c ti\u1EBFp IDE c\u1EE5 th\u1EC3 (cursor, windsurf, antigravity, jai1)").option("--type <type>", "Hi\u1EC3n th\u1ECB lo\u1EA1i context c\u1EE5 th\u1EC3 (rules, workflows, skills, agents, prompts)").option("--stats", "Hi\u1EC3n th\u1ECB th\u1ED1ng k\xEA context (non-interactive)").action(async (options) => {
9760
+ const cmd = new Command45("context").description("Kh\xE1m ph\xE1 v\xE0 qu\u1EA3n l\xFD context d\u1EF1 \xE1n cho c\xE1c IDE").option("--ide <ide>", "M\u1EDF tr\u1EF1c ti\u1EBFp IDE c\u1EE5 th\u1EC3 (cursor, windsurf, antigravity, jai1)").option("--type <type>", "Hi\u1EC3n th\u1ECB lo\u1EA1i context c\u1EE5 th\u1EC3 (rules, workflows, skills, agents, prompts)").option("--stats", "Hi\u1EC3n th\u1ECB th\u1ED1ng k\xEA context (non-interactive)").action(async (options) => {
9357
9761
  let initialIDE;
9358
9762
  if (options.ide) {
9359
9763
  const validIDEs = ["cursor", "windsurf", "antigravity", "jai1"];
@@ -9430,10 +9834,10 @@ async function printStats2() {
9430
9834
  }
9431
9835
 
9432
9836
  // src/commands/migrate-ide.ts
9433
- import { Command as Command44 } from "commander";
9434
- import { checkbox as checkbox5, confirm as confirm9 } from "@inquirer/prompts";
9837
+ import { Command as Command46 } from "commander";
9838
+ import { checkbox as checkbox6, confirm as confirm10 } from "@inquirer/prompts";
9435
9839
  function createMigrateIdeCommand() {
9436
- const cmd = new Command44("migrate-ide").description("Migrate .jai1 rules v\xE0 workflows sang IDEs (Cursor, Windsurf, Claude Code, etc.)").option("--ide <ides...>", "Target IDEs (cursor, windsurf, antigravity, claudecode, opencode)").option("--type <types...>", "Content types (rules, workflows, commands)").option("--dry-run", "Preview changes without writing files").action(async (options) => {
9840
+ const cmd = new Command46("migrate-ide").description("Migrate .jai1 rules v\xE0 workflows sang IDEs (Cursor, Windsurf, Claude Code, etc.)").option("--ide <ides...>", "Target IDEs (cursor, windsurf, antigravity, claudecode, opencode)").option("--type <types...>", "Content types (rules, workflows, commands)").option("--dry-run", "Preview changes without writing files").action(async (options) => {
9437
9841
  await runMigrateIde(options);
9438
9842
  });
9439
9843
  return cmd;
@@ -9461,7 +9865,7 @@ async function runMigrateIde(options) {
9461
9865
  value: ide
9462
9866
  };
9463
9867
  });
9464
- selectedIdes = await checkbox5({
9868
+ selectedIdes = await checkbox6({
9465
9869
  message: "Ch\u1ECDn IDE(s) \u0111\u1EC3 migrate (SPACE \u0111\u1EC3 ch\u1ECDn, ENTER \u0111\u1EC3 x\xE1c nh\u1EADn):",
9466
9870
  choices: ideChoices
9467
9871
  });
@@ -9480,7 +9884,7 @@ async function runMigrateIde(options) {
9480
9884
  { name: `Workflows (${content.workflows.length} files)`, value: "workflows" },
9481
9885
  { name: `Commands (${content.commands.length} files)`, value: "commands" }
9482
9886
  ];
9483
- selectedTypes = await checkbox5({
9887
+ selectedTypes = await checkbox6({
9484
9888
  message: "Ch\u1ECDn content types \u0111\u1EC3 migrate:",
9485
9889
  choices: typeChoices
9486
9890
  });
@@ -9502,7 +9906,7 @@ async function runMigrateIde(options) {
9502
9906
  if (options.dryRun) {
9503
9907
  console.log("\u{1F50D} DRY RUN - No files will be written\n");
9504
9908
  }
9505
- const confirmed = await confirm9({
9909
+ const confirmed = await confirm10({
9506
9910
  message: "Proceed with migration?",
9507
9911
  default: true
9508
9912
  });
@@ -9539,7 +9943,7 @@ async function runMigrateIde(options) {
9539
9943
  }
9540
9944
 
9541
9945
  // src/cli.ts
9542
- var program = new Command45();
9946
+ var program = new Command47();
9543
9947
  if (process.argv.includes("-v") || process.argv.includes("--version")) {
9544
9948
  console.log(package_default.version);
9545
9949
  if (!process.argv.includes("--skip-update-check")) {
@@ -9561,12 +9965,13 @@ program.addCommand(createOpenAiKeysCommand());
9561
9965
  program.addCommand(createStatsCommand());
9562
9966
  program.addCommand(createTranslateCommand());
9563
9967
  program.addCommand(createUtilsCommand());
9968
+ program.addCommand(createDepsCommand());
9564
9969
  program.addCommand(createKitCommand());
9565
9970
  program.addCommand(createUpgradeCommand());
9566
9971
  program.addCommand(createCleanCommand());
9567
- var redmineCommand = new Command45("redmine").description("Redmine context sync commands");
9972
+ var redmineCommand = new Command47("redmine").description("Redmine context sync commands");
9568
9973
  redmineCommand.addCommand(createRedmineCheckCommand());
9569
- var syncCommand = new Command45("sync").description("Sync Redmine issues to markdown files");
9974
+ var syncCommand = new Command47("sync").description("Sync Redmine issues to markdown files");
9570
9975
  syncCommand.addCommand(createSyncIssueCommand());
9571
9976
  syncCommand.addCommand(createSyncProjectCommand());
9572
9977
  redmineCommand.addCommand(syncCommand);
@@ -9606,6 +10011,7 @@ program.on("command:*", (operands) => {
9606
10011
  console.error(" translate Translate text, files, or folders using AI");
9607
10012
  console.error("");
9608
10013
  console.error(" \u{1F6E0}\uFE0F Developer Utilities");
10014
+ console.error(" deps Manage project dependencies");
9609
10015
  console.error(" utils Developer tools (password, uuid, hash, jwt, etc.)");
9610
10016
  console.error("");
9611
10017
  console.error(" \u{1F527} Maintenance");