@jvittechs/j 1.0.39 → 1.0.40

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
@@ -13,7 +13,7 @@ import {
13
13
  STATUS_ICONS,
14
14
  TaskService,
15
15
  createTaskSummaryCommand
16
- } from "./chunk-KOEMGOAP.js";
16
+ } from "./chunk-ZG3KLHJ4.js";
17
17
 
18
18
  // src/utils/node-version-check.ts
19
19
  import chalk from "chalk";
@@ -49,7 +49,7 @@ function checkNodeVersion() {
49
49
  }
50
50
 
51
51
  // src/cli.ts
52
- import { Command as Command86 } from "commander";
52
+ import { Command as Command87 } from "commander";
53
53
 
54
54
  // src/services/error-log.service.ts
55
55
  import { promises as fs } from "fs";
@@ -149,7 +149,7 @@ import { basename as basename5 } from "path";
149
149
  // package.json
150
150
  var package_default = {
151
151
  name: "@jvittechs/j",
152
- version: "1.0.39",
152
+ version: "1.0.40",
153
153
  description: "A unified CLI tool for JV-IT TECHS developers to manage Jai1 Framework. Supports both `j` and `jai1` commands. Please contact TeamAI for usage instructions.",
154
154
  type: "module",
155
155
  bin: {
@@ -10801,7 +10801,7 @@ function createHooksCommand() {
10801
10801
  }
10802
10802
 
10803
10803
  // src/commands/tasks/index.ts
10804
- import { Command as Command58 } from "commander";
10804
+ import { Command as Command59 } from "commander";
10805
10805
 
10806
10806
  // src/commands/tasks/add.ts
10807
10807
  import { Command as Command48 } from "commander";
@@ -11277,6 +11277,7 @@ ${chalk30.bold("\u2501\u2501\u2501 ALL COMMANDS \u2501\u2501\u2501")}
11277
11277
  ${chalk30.cyan("jai1 t dep")} <childId> <parentId> [-j]
11278
11278
  ${chalk30.cyan("jai1 t sync")} [--pull] [--push]
11279
11279
  ${chalk30.cyan("jai1 t summary")} [-j]
11280
+ ${chalk30.cyan("jai1 t groups")} [-s status] [-j] ${chalk30.dim("(alias: parents)")}
11280
11281
  ${chalk30.cyan("jai1 t guide")}
11281
11282
 
11282
11283
  ${chalk30.dim("-j / --json available on all commands (except guide, sync)")}
@@ -11287,9 +11288,59 @@ function createTaskGuideCommand() {
11287
11288
  });
11288
11289
  }
11289
11290
 
11291
+ // src/commands/tasks/parents.ts
11292
+ import { Command as Command58 } from "commander";
11293
+ import chalk31 from "chalk";
11294
+ var PARENT_STATUS_ICONS = {
11295
+ done: "\u2705",
11296
+ in_progress: "\u{1F535}",
11297
+ ready: "\u{1F4CB}",
11298
+ todo: "\u{1F534}"
11299
+ };
11300
+ function formatProgress(p) {
11301
+ const completed = p.done + p.cancelled;
11302
+ if (p.status === "done") {
11303
+ return chalk31.green(`${completed}/${p.total} done`);
11304
+ }
11305
+ const parts = [];
11306
+ if (p.in_progress > 0) parts.push(`${p.in_progress} in_progress`);
11307
+ if (p.ready > 0) parts.push(`${p.ready} ready`);
11308
+ if (p.blocked > 0) parts.push(chalk31.red(`${p.blocked} blocked`));
11309
+ if (p.done > 0) parts.push(`${p.done} done`);
11310
+ return `${completed}/${p.total} tasks` + (parts.length > 0 ? ` (${parts.join(", ")})` : "");
11311
+ }
11312
+ function createTaskParentsCommand() {
11313
+ return new Command58("groups").aliases(["parents", "pg"]).description("List task groups with computed status").option("-s, --status <status>", "Filter by computed status: done, in_progress, ready, todo").option("-j, --json", "Output JSON").action(async (options) => {
11314
+ const service = new TaskService();
11315
+ const parents = await service.getParents(options.status);
11316
+ if (options.json) {
11317
+ console.log(JSON.stringify(parents, null, 2));
11318
+ return;
11319
+ }
11320
+ if (parents.length === 0) {
11321
+ if (options.status) {
11322
+ console.log(chalk31.dim(`No groups with status: ${options.status}`));
11323
+ } else {
11324
+ console.log(chalk31.dim("No task groups found."));
11325
+ console.log(chalk31.dim('\u{1F4A1} Add tasks with parent: jai1 t add "..." -P feature/xxx'));
11326
+ }
11327
+ return;
11328
+ }
11329
+ const header = options.status ? `\u{1F4E6} Task Groups \u2014 ${options.status} (${parents.length})` : `\u{1F4E6} Task Groups (${parents.length})`;
11330
+ console.log(chalk31.bold(header));
11331
+ console.log();
11332
+ for (const p of parents) {
11333
+ const icon = PARENT_STATUS_ICONS[p.status] || "\u{1F4CB}";
11334
+ const progress = formatProgress(p);
11335
+ console.log(` ${icon} ${chalk31.bold(p.name)} ${chalk31.dim("\u2014")} ${progress}`);
11336
+ }
11337
+ console.log();
11338
+ });
11339
+ }
11340
+
11290
11341
  // src/commands/tasks/index.ts
11291
11342
  function createTasksCommand() {
11292
- const cmd = new Command58("tasks").alias("t").description("Task management \u2014 track, assign, and manage development tasks").hook("preAction", (thisCommand, actionCommand) => {
11343
+ const cmd = new Command59("tasks").alias("t").description("Task management \u2014 track, assign, and manage development tasks").hook("preAction", (thisCommand, actionCommand) => {
11293
11344
  if (actionCommand.name() !== "guide") {
11294
11345
  TaskService.ensureJai1Dir();
11295
11346
  }
@@ -11304,21 +11355,22 @@ function createTasksCommand() {
11304
11355
  cmd.addCommand(createTaskDepCommand());
11305
11356
  cmd.addCommand(createTaskSyncCommand());
11306
11357
  cmd.addCommand(createTaskSummaryCommand());
11358
+ cmd.addCommand(createTaskParentsCommand());
11307
11359
  cmd.addCommand(createTaskGuideCommand());
11308
11360
  cmd.action(async () => {
11309
- const { handleTaskSummary } = await import("./summary-O75DZKM2.js");
11361
+ const { handleTaskSummary } = await import("./summary-AEJ34P4Q.js");
11310
11362
  await handleTaskSummary({ json: false });
11311
11363
  });
11312
11364
  return cmd;
11313
11365
  }
11314
11366
 
11315
11367
  // src/commands/kit/index.ts
11316
- import { Command as Command62 } from "commander";
11317
- import chalk32 from "chalk";
11368
+ import { Command as Command63 } from "commander";
11369
+ import chalk33 from "chalk";
11318
11370
 
11319
11371
  // src/commands/kit/list.ts
11320
- import { Command as Command59 } from "commander";
11321
- import chalk31 from "chalk";
11372
+ import { Command as Command60 } from "commander";
11373
+ import chalk32 from "chalk";
11322
11374
  import Table6 from "cli-table3";
11323
11375
 
11324
11376
  // src/services/starter-kit.service.ts
@@ -11386,13 +11438,13 @@ var StarterKitService = class {
11386
11438
 
11387
11439
  // src/commands/kit/list.ts
11388
11440
  function createKitListCommand() {
11389
- return new Command59("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) => {
11441
+ return new Command60("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) => {
11390
11442
  const configService = new ConfigService();
11391
11443
  const config = await configService.load();
11392
11444
  if (!config) {
11393
11445
  throw new ValidationError('Not initialized. Run "jai1 auth" first.');
11394
11446
  }
11395
- console.log(chalk31.cyan("\u{1F4E6} \u0110ang t\u1EA3i danh s\xE1ch starter kits..."));
11447
+ console.log(chalk32.cyan("\u{1F4E6} \u0110ang t\u1EA3i danh s\xE1ch starter kits..."));
11396
11448
  console.log();
11397
11449
  const kitService = new StarterKitService();
11398
11450
  const kits = await kitService.list(config, {
@@ -11400,9 +11452,9 @@ function createKitListCommand() {
11400
11452
  search: options.search
11401
11453
  });
11402
11454
  if (kits.length === 0) {
11403
- console.log(chalk31.yellow("Kh\xF4ng t\xECm th\u1EA5y starter kits n\xE0o."));
11455
+ console.log(chalk32.yellow("Kh\xF4ng t\xECm th\u1EA5y starter kits n\xE0o."));
11404
11456
  if (options.category || options.search) {
11405
- console.log(chalk31.dim("Th\u1EED b\u1ECF filter \u0111\u1EC3 xem t\u1EA5t c\u1EA3."));
11457
+ console.log(chalk32.dim("Th\u1EED b\u1ECF filter \u0111\u1EC3 xem t\u1EA5t c\u1EA3."));
11406
11458
  }
11407
11459
  return;
11408
11460
  }
@@ -11426,35 +11478,35 @@ function createKitListCommand() {
11426
11478
  const categoryKits = byCategory[category];
11427
11479
  const categoryIcon = category === "frontend" ? "\u{1F3A8}" : category === "backend" ? "\u2699\uFE0F" : category === "fullstack" ? "\u{1F680}" : "\u{1F4E6}";
11428
11480
  console.log(
11429
- chalk31.bold(`${categoryIcon} ${category.charAt(0).toUpperCase() + category.slice(1)}`)
11481
+ chalk32.bold(`${categoryIcon} ${category.charAt(0).toUpperCase() + category.slice(1)}`)
11430
11482
  );
11431
11483
  const table = new Table6({
11432
11484
  head: [
11433
- chalk31.cyan("Slug"),
11434
- chalk31.cyan("M\xF4 t\u1EA3"),
11435
- chalk31.cyan("Version")
11485
+ chalk32.cyan("Slug"),
11486
+ chalk32.cyan("M\xF4 t\u1EA3"),
11487
+ chalk32.cyan("Version")
11436
11488
  ],
11437
11489
  style: { head: [], border: ["gray"] }
11438
11490
  });
11439
11491
  for (const kit of categoryKits) {
11440
11492
  table.push([
11441
- chalk31.white(kit.slug),
11442
- chalk31.dim(kit.description.slice(0, 50)),
11443
- chalk31.green(`v${kit.version}`)
11493
+ chalk32.white(kit.slug),
11494
+ chalk32.dim(kit.description.slice(0, 50)),
11495
+ chalk32.green(`v${kit.version}`)
11444
11496
  ]);
11445
11497
  }
11446
11498
  console.log(table.toString());
11447
11499
  console.log();
11448
11500
  }
11449
- console.log(chalk31.dim(`T\u1ED5ng c\u1ED9ng: ${kits.length} starter kit(s)`));
11450
- console.log(chalk31.dim('\n\u{1F4A1} Ch\u1EA1y "jai1 kit create <slug>" \u0111\u1EC3 t\u1EA1o project m\u1EDBi'));
11501
+ console.log(chalk32.dim(`T\u1ED5ng c\u1ED9ng: ${kits.length} starter kit(s)`));
11502
+ console.log(chalk32.dim('\n\u{1F4A1} Ch\u1EA1y "jai1 kit create <slug>" \u0111\u1EC3 t\u1EA1o project m\u1EDBi'));
11451
11503
  });
11452
11504
  }
11453
11505
 
11454
11506
  // src/commands/kit/info.ts
11455
- import { Command as Command60 } from "commander";
11507
+ import { Command as Command61 } from "commander";
11456
11508
  function createKitInfoCommand() {
11457
- return new Command60("info").description("Show detailed information about a starter kit").argument("<slug>", "Starter kit slug").action(async (slug) => {
11509
+ return new Command61("info").description("Show detailed information about a starter kit").argument("<slug>", "Starter kit slug").action(async (slug) => {
11458
11510
  const configService = new ConfigService();
11459
11511
  const config = await configService.load();
11460
11512
  if (!config) {
@@ -11503,7 +11555,7 @@ Post-Init Commands:`);
11503
11555
  }
11504
11556
 
11505
11557
  // src/commands/kit/create.ts
11506
- import { Command as Command61 } from "commander";
11558
+ import { Command as Command62 } from "commander";
11507
11559
  import { promises as fs20 } from "fs";
11508
11560
  import { join as join11 } from "path";
11509
11561
  import { select as select3, input as input2, checkbox as checkbox4 } from "@inquirer/prompts";
@@ -11548,7 +11600,7 @@ var HookExecutor = class {
11548
11600
 
11549
11601
  // src/commands/kit/create.ts
11550
11602
  function createKitCreateCommand() {
11551
- return new Command61("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) => {
11603
+ return new Command62("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) => {
11552
11604
  const configService = new ConfigService();
11553
11605
  const config = await configService.load();
11554
11606
  if (!config) {
@@ -11727,23 +11779,23 @@ async function getAllFiles(dir) {
11727
11779
 
11728
11780
  // src/commands/kit/index.ts
11729
11781
  function showKitHelp() {
11730
- console.log(chalk32.bold.cyan("\u{1F4E6} jai1 kit") + chalk32.dim(" - Qu\u1EA3n l\xFD starter kits"));
11782
+ console.log(chalk33.bold.cyan("\u{1F4E6} jai1 kit") + chalk33.dim(" - Qu\u1EA3n l\xFD starter kits"));
11731
11783
  console.log();
11732
- console.log(chalk32.bold("C\xE1c l\u1EC7nh:"));
11733
- console.log(` ${chalk32.cyan("list")} Li\u1EC7t k\xEA c\xE1c starter kits c\xF3 s\u1EB5n`);
11734
- console.log(` ${chalk32.cyan("info")} Xem chi ti\u1EBFt m\u1ED9t starter kit`);
11735
- console.log(` ${chalk32.cyan("create")} T\u1EA1o project m\u1EDBi t\u1EEB starter kit`);
11784
+ console.log(chalk33.bold("C\xE1c l\u1EC7nh:"));
11785
+ console.log(` ${chalk33.cyan("list")} Li\u1EC7t k\xEA c\xE1c starter kits c\xF3 s\u1EB5n`);
11786
+ console.log(` ${chalk33.cyan("info")} Xem chi ti\u1EBFt m\u1ED9t starter kit`);
11787
+ console.log(` ${chalk33.cyan("create")} T\u1EA1o project m\u1EDBi t\u1EEB starter kit`);
11736
11788
  console.log();
11737
- console.log(chalk32.bold("V\xED d\u1EE5:"));
11738
- console.log(chalk32.dim(" $ jai1 kit list"));
11739
- console.log(chalk32.dim(" $ jai1 kit list --category frontend"));
11740
- console.log(chalk32.dim(" $ jai1 kit info next-tw4-shadcn"));
11741
- console.log(chalk32.dim(" $ jai1 kit create next-tw4-shadcn my-project"));
11789
+ console.log(chalk33.bold("V\xED d\u1EE5:"));
11790
+ console.log(chalk33.dim(" $ jai1 kit list"));
11791
+ console.log(chalk33.dim(" $ jai1 kit list --category frontend"));
11792
+ console.log(chalk33.dim(" $ jai1 kit info next-tw4-shadcn"));
11793
+ console.log(chalk33.dim(" $ jai1 kit create next-tw4-shadcn my-project"));
11742
11794
  console.log();
11743
- console.log(chalk32.dim('Ch\u1EA1y "jai1 kit <l\u1EC7nh> --help" \u0111\u1EC3 xem chi ti\u1EBFt'));
11795
+ console.log(chalk33.dim('Ch\u1EA1y "jai1 kit <l\u1EC7nh> --help" \u0111\u1EC3 xem chi ti\u1EBFt'));
11744
11796
  }
11745
11797
  function createKitCommand() {
11746
- const cmd = new Command62("kit").description("Manage starter kits for new projects").action(() => {
11798
+ const cmd = new Command63("kit").description("Manage starter kits for new projects").action(() => {
11747
11799
  showKitHelp();
11748
11800
  });
11749
11801
  cmd.addCommand(createKitListCommand());
@@ -11753,21 +11805,21 @@ function createKitCommand() {
11753
11805
  }
11754
11806
 
11755
11807
  // src/commands/rules/index.ts
11756
- import { Command as Command69 } from "commander";
11757
- import chalk34 from "chalk";
11808
+ import { Command as Command70 } from "commander";
11809
+ import chalk35 from "chalk";
11758
11810
 
11759
11811
  // src/commands/rules/list.ts
11760
- import { Command as Command63 } from "commander";
11761
- import chalk33 from "chalk";
11812
+ import { Command as Command64 } from "commander";
11813
+ import chalk34 from "chalk";
11762
11814
  import Table7 from "cli-table3";
11763
11815
  function createRulesListCommand() {
11764
- return new Command63("list").description("List available rule presets").option("--json", "Output as JSON").action(async (options) => {
11816
+ return new Command64("list").description("List available rule presets").option("--json", "Output as JSON").action(async (options) => {
11765
11817
  const configService = new ConfigService();
11766
11818
  const config = await configService.load();
11767
11819
  if (!config) {
11768
11820
  throw new ValidationError('Not initialized. Run "jai1 auth" first.');
11769
11821
  }
11770
- console.log(chalk33.cyan("\u{1F4CB} \u0110ang t\u1EA3i danh s\xE1ch rule presets..."));
11822
+ console.log(chalk34.cyan("\u{1F4CB} \u0110ang t\u1EA3i danh s\xE1ch rule presets..."));
11771
11823
  console.log();
11772
11824
  try {
11773
11825
  const response = await fetch(`${config.apiUrl}/api/rules/presets`, {
@@ -11784,23 +11836,23 @@ function createRulesListCommand() {
11784
11836
  return;
11785
11837
  }
11786
11838
  if (data.total === 0) {
11787
- console.log(chalk33.yellow("Kh\xF4ng c\xF3 presets n\xE0o."));
11839
+ console.log(chalk34.yellow("Kh\xF4ng c\xF3 presets n\xE0o."));
11788
11840
  return;
11789
11841
  }
11790
11842
  console.log(
11791
- chalk33.green(`\u2713 T\xECm th\u1EA5y ${chalk33.bold(data.total)} preset${data.total > 1 ? "s" : ""}`)
11843
+ chalk34.green(`\u2713 T\xECm th\u1EA5y ${chalk34.bold(data.total)} preset${data.total > 1 ? "s" : ""}`)
11792
11844
  );
11793
11845
  console.log();
11794
11846
  for (const preset of data.presets) {
11795
- console.log(chalk33.bold.cyan(`\u{1F4E6} ${preset.slug}`));
11847
+ console.log(chalk34.bold.cyan(`\u{1F4E6} ${preset.slug}`));
11796
11848
  const table = new Table7({
11797
11849
  style: { head: [], border: ["gray"], compact: true },
11798
11850
  colWidths: [15, 55]
11799
11851
  });
11800
11852
  table.push(
11801
- [chalk33.dim("T\xEAn"), chalk33.white(preset.name)],
11802
- [chalk33.dim("M\xF4 t\u1EA3"), chalk33.white(preset.description)],
11803
- [chalk33.dim("Version"), chalk33.green(`v${preset.version}`)]
11853
+ [chalk34.dim("T\xEAn"), chalk34.white(preset.name)],
11854
+ [chalk34.dim("M\xF4 t\u1EA3"), chalk34.white(preset.description)],
11855
+ [chalk34.dim("Version"), chalk34.green(`v${preset.version}`)]
11804
11856
  );
11805
11857
  const stackParts = [];
11806
11858
  if (preset.stack.frontend) stackParts.push(preset.stack.frontend);
@@ -11808,16 +11860,16 @@ function createRulesListCommand() {
11808
11860
  if (preset.stack.css) stackParts.push(preset.stack.css);
11809
11861
  if (preset.stack.database) stackParts.push(preset.stack.database);
11810
11862
  if (stackParts.length > 0) {
11811
- table.push([chalk33.dim("Stack"), chalk33.yellow(stackParts.join(" + "))]);
11863
+ table.push([chalk34.dim("Stack"), chalk34.yellow(stackParts.join(" + "))]);
11812
11864
  }
11813
11865
  table.push(
11814
- [chalk33.dim("Tags"), chalk33.dim(preset.tags.join(", ") || "-")],
11815
- [chalk33.dim("Downloads"), chalk33.white(preset.downloads.toString())]
11866
+ [chalk34.dim("Tags"), chalk34.dim(preset.tags.join(", ") || "-")],
11867
+ [chalk34.dim("Downloads"), chalk34.white(preset.downloads.toString())]
11816
11868
  );
11817
11869
  console.log(table.toString());
11818
11870
  console.log();
11819
11871
  }
11820
- console.log(chalk33.dim('\u{1F4A1} Ch\u1EA1y "jai1 rules apply <name>" \u0111\u1EC3 \xE1p d\u1EE5ng preset'));
11872
+ console.log(chalk34.dim('\u{1F4A1} Ch\u1EA1y "jai1 rules apply <name>" \u0111\u1EC3 \xE1p d\u1EE5ng preset'));
11821
11873
  } catch (error) {
11822
11874
  throw new Error(
11823
11875
  `L\u1ED7i khi t\u1EA3i presets: ${error instanceof Error ? error.message : String(error)}`
@@ -11827,7 +11879,7 @@ function createRulesListCommand() {
11827
11879
  }
11828
11880
 
11829
11881
  // src/commands/rules/init.ts
11830
- import { Command as Command64 } from "commander";
11882
+ import { Command as Command65 } from "commander";
11831
11883
  import { promises as fs22 } from "fs";
11832
11884
  import { join as join13 } from "path";
11833
11885
  import { select as select4, confirm as confirm10 } from "@inquirer/prompts";
@@ -11952,7 +12004,7 @@ var ProjectConfigService = class {
11952
12004
 
11953
12005
  // src/commands/rules/init.ts
11954
12006
  function createRulesInitCommand() {
11955
- return new Command64("init").description("Apply rule preset to project").option("--preset <slug>", "Preset slug to apply").option("--output <format>", "Output format: cursor, agents-md, both (default: cursor)", "cursor").option("-y, --yes", "Skip confirmations").action(async (options) => {
12007
+ return new Command65("init").description("Apply rule preset to project").option("--preset <slug>", "Preset slug to apply").option("--output <format>", "Output format: cursor, agents-md, both (default: cursor)", "cursor").option("-y, --yes", "Skip confirmations").action(async (options) => {
11956
12008
  const configService = new ConfigService();
11957
12009
  const config = await configService.load();
11958
12010
  if (!config) {
@@ -12084,7 +12136,7 @@ async function applyAgentsMdFormat(bundle) {
12084
12136
  }
12085
12137
 
12086
12138
  // src/commands/rules/apply.ts
12087
- import { Command as Command65 } from "commander";
12139
+ import { Command as Command66 } from "commander";
12088
12140
  import { promises as fs24 } from "fs";
12089
12141
  import { join as join15 } from "path";
12090
12142
  import { search, confirm as confirm11, checkbox as checkbox5 } from "@inquirer/prompts";
@@ -12598,7 +12650,7 @@ Restoring backup from ${metadata.timestamp}...`);
12598
12650
 
12599
12651
  // src/commands/rules/apply.ts
12600
12652
  function createRulesApplyCommand() {
12601
- return new Command65("apply").description("Apply rule preset to project with multi-IDE support").argument("[preset]", "Preset slug to apply (optional)").option("--ides <ides>", 'Comma-separated list of IDE formats (cursor,windsurf,antigravity,claude,agentsmd,gemini) or "all"').option("--skip-backup", "Skip backup creation").option("-y, --yes", "Skip all confirmations (auto mode)").action(async (presetSlug, options) => {
12653
+ return new Command66("apply").description("Apply rule preset to project with multi-IDE support").argument("[preset]", "Preset slug to apply (optional)").option("--ides <ides>", 'Comma-separated list of IDE formats (cursor,windsurf,antigravity,claude,agentsmd,gemini) or "all"').option("--skip-backup", "Skip backup creation").option("-y, --yes", "Skip all confirmations (auto mode)").action(async (presetSlug, options) => {
12602
12654
  const configService = new ConfigService();
12603
12655
  const config = await configService.load();
12604
12656
  if (!config) {
@@ -12893,11 +12945,11 @@ function createRulesApplyCommand() {
12893
12945
  }
12894
12946
 
12895
12947
  // src/commands/rules/restore.ts
12896
- import { Command as Command66 } from "commander";
12948
+ import { Command as Command67 } from "commander";
12897
12949
  import { join as join16 } from "path";
12898
12950
  import { select as select5, confirm as confirm12 } from "@inquirer/prompts";
12899
12951
  function createRulesRestoreCommand() {
12900
- return new Command66("restore").description("Restore rules from a backup").option("--latest", "Restore the most recent backup").option("-y, --yes", "Skip confirmation").action(async (options) => {
12952
+ return new Command67("restore").description("Restore rules from a backup").option("--latest", "Restore the most recent backup").option("-y, --yes", "Skip confirmation").action(async (options) => {
12901
12953
  const backupService = new BackupService();
12902
12954
  const backups = await backupService.listBackups();
12903
12955
  if (backups.length === 0) {
@@ -12966,12 +13018,12 @@ function formatTimestamp(timestamp) {
12966
13018
  }
12967
13019
 
12968
13020
  // src/commands/rules/sync.ts
12969
- import { Command as Command67 } from "commander";
13021
+ import { Command as Command68 } from "commander";
12970
13022
  import { promises as fs25 } from "fs";
12971
13023
  import { join as join17 } from "path";
12972
13024
  import { checkbox as checkbox6, confirm as confirm13, Separator } from "@inquirer/prompts";
12973
13025
  function createRulesSyncCommand() {
12974
- return new Command67("sync").description("Regenerate rule outputs for all configured IDEs").option("--ides <ides>", "Comma-separated list of IDEs to sync (default: all configured)").option("--detect", "Auto-detect active IDEs instead of using config").option("-y, --yes", "Skip confirmations").action(async (options) => {
13026
+ return new Command68("sync").description("Regenerate rule outputs for all configured IDEs").option("--ides <ides>", "Comma-separated list of IDEs to sync (default: all configured)").option("--detect", "Auto-detect active IDEs instead of using config").option("-y, --yes", "Skip confirmations").action(async (options) => {
12975
13027
  const rulePresetDir = join17(process.cwd(), ".jai1", "rule-preset");
12976
13028
  const presetJsonPath = join17(rulePresetDir, "preset.json");
12977
13029
  let presetExists = false;
@@ -13189,11 +13241,11 @@ function buildIdeChoices(currentIdes, detected, suggestions) {
13189
13241
  }
13190
13242
 
13191
13243
  // src/commands/rules/info.ts
13192
- import { Command as Command68 } from "commander";
13244
+ import { Command as Command69 } from "commander";
13193
13245
  import { promises as fs26 } from "fs";
13194
13246
  import { join as join18 } from "path";
13195
13247
  function createRulesInfoCommand() {
13196
- return new Command68("info").description("Show current preset information").option("--json", "Output as JSON").action(async (options) => {
13248
+ return new Command69("info").description("Show current preset information").option("--json", "Output as JSON").action(async (options) => {
13197
13249
  const projectConfigService = new ProjectConfigService();
13198
13250
  const rulesConfig = await projectConfigService.loadRules();
13199
13251
  if (!rulesConfig) {
@@ -13296,26 +13348,26 @@ async function checkIdeFilesExist(ideId, format) {
13296
13348
 
13297
13349
  // src/commands/rules/index.ts
13298
13350
  function showRulesHelp() {
13299
- console.log(chalk34.bold.cyan("\u{1F4CB} jai1 rules") + chalk34.dim(" - Qu\u1EA3n l\xFD rule presets cho AI agents"));
13351
+ console.log(chalk35.bold.cyan("\u{1F4CB} jai1 rules") + chalk35.dim(" - Qu\u1EA3n l\xFD rule presets cho AI agents"));
13300
13352
  console.log();
13301
- console.log(chalk34.bold("C\xE1c l\u1EC7nh:"));
13302
- console.log(` ${chalk34.cyan("list")} Li\u1EC7t k\xEA c\xE1c presets c\xF3 s\u1EB5n`);
13303
- console.log(` ${chalk34.cyan("info")} Xem chi ti\u1EBFt m\u1ED9t preset`);
13304
- console.log(` ${chalk34.cyan("init")} Kh\u1EDFi t\u1EA1o rules t\u1EEB preset`);
13305
- console.log(` ${chalk34.cyan("apply")} \xC1p d\u1EE5ng preset v\xE0o project`);
13306
- console.log(` ${chalk34.cyan("sync")} \u0110\u1ED3ng b\u1ED9 rules sang c\xE1c \u0111\u1ECBnh d\u1EA1ng IDE`);
13307
- console.log(` ${chalk34.cyan("restore")} Kh\xF4i ph\u1EE5c rules t\u1EEB backup`);
13353
+ console.log(chalk35.bold("C\xE1c l\u1EC7nh:"));
13354
+ console.log(` ${chalk35.cyan("list")} Li\u1EC7t k\xEA c\xE1c presets c\xF3 s\u1EB5n`);
13355
+ console.log(` ${chalk35.cyan("info")} Xem chi ti\u1EBFt m\u1ED9t preset`);
13356
+ console.log(` ${chalk35.cyan("init")} Kh\u1EDFi t\u1EA1o rules t\u1EEB preset`);
13357
+ console.log(` ${chalk35.cyan("apply")} \xC1p d\u1EE5ng preset v\xE0o project`);
13358
+ console.log(` ${chalk35.cyan("sync")} \u0110\u1ED3ng b\u1ED9 rules sang c\xE1c \u0111\u1ECBnh d\u1EA1ng IDE`);
13359
+ console.log(` ${chalk35.cyan("restore")} Kh\xF4i ph\u1EE5c rules t\u1EEB backup`);
13308
13360
  console.log();
13309
- console.log(chalk34.bold("V\xED d\u1EE5:"));
13310
- console.log(chalk34.dim(" $ jai1 rules list"));
13311
- console.log(chalk34.dim(" $ jai1 rules info react-typescript"));
13312
- console.log(chalk34.dim(" $ jai1 rules init --preset=react-typescript"));
13313
- console.log(chalk34.dim(" $ jai1 rules apply react-typescript"));
13361
+ console.log(chalk35.bold("V\xED d\u1EE5:"));
13362
+ console.log(chalk35.dim(" $ jai1 rules list"));
13363
+ console.log(chalk35.dim(" $ jai1 rules info react-typescript"));
13364
+ console.log(chalk35.dim(" $ jai1 rules init --preset=react-typescript"));
13365
+ console.log(chalk35.dim(" $ jai1 rules apply react-typescript"));
13314
13366
  console.log();
13315
- console.log(chalk34.dim('Ch\u1EA1y "jai1 rules <l\u1EC7nh> --help" \u0111\u1EC3 xem chi ti\u1EBFt'));
13367
+ console.log(chalk35.dim('Ch\u1EA1y "jai1 rules <l\u1EC7nh> --help" \u0111\u1EC3 xem chi ti\u1EBFt'));
13316
13368
  }
13317
13369
  function createRulesCommand() {
13318
- const rulesCommand = new Command69("rules").description("Manage rule presets for AI agents").action(() => {
13370
+ const rulesCommand = new Command70("rules").description("Manage rule presets for AI agents").action(() => {
13319
13371
  showRulesHelp();
13320
13372
  });
13321
13373
  rulesCommand.addCommand(createRulesListCommand());
@@ -13328,12 +13380,12 @@ function createRulesCommand() {
13328
13380
  }
13329
13381
 
13330
13382
  // src/commands/skills/index.ts
13331
- import { Command as Command75 } from "commander";
13332
- import chalk40 from "chalk";
13383
+ import { Command as Command76 } from "commander";
13384
+ import chalk41 from "chalk";
13333
13385
 
13334
13386
  // src/commands/skills/find.ts
13335
- import { Command as Command70 } from "commander";
13336
- import chalk35 from "chalk";
13387
+ import { Command as Command71 } from "commander";
13388
+ import chalk36 from "chalk";
13337
13389
  import Table8 from "cli-table3";
13338
13390
 
13339
13391
  // src/services/skills.service.ts
@@ -13627,7 +13679,7 @@ var SkillsService = class {
13627
13679
 
13628
13680
  // src/commands/skills/find.ts
13629
13681
  function createSkillsFindCommand() {
13630
- return new Command70("find").description("Search for skills on server or npm").argument("<query>", "Search query").option("--skillsh", "Search on npm skills registry instead of Jai1 server").option("--all", "Search on both Jai1 server and npm").action(async (query, options) => {
13682
+ return new Command71("find").description("Search for skills on server or npm").argument("<query>", "Search query").option("--skillsh", "Search on npm skills registry instead of Jai1 server").option("--all", "Search on both Jai1 server and npm").action(async (query, options) => {
13631
13683
  const searchNpm = options.skillsh || options.all;
13632
13684
  const searchServer = !options.skillsh || options.all;
13633
13685
  if (searchServer) {
@@ -13636,19 +13688,19 @@ function createSkillsFindCommand() {
13636
13688
  if (!config) {
13637
13689
  throw new ValidationError('Ch\u01B0a x\xE1c th\u1EF1c. Ch\u1EA1y "jai1 auth" tr\u01B0\u1EDBc.');
13638
13690
  }
13639
- console.log(chalk35.cyan("\u{1F50D} \u0110ang t\xECm ki\u1EBFm tr\xEAn Jai1 server..."));
13691
+ console.log(chalk36.cyan("\u{1F50D} \u0110ang t\xECm ki\u1EBFm tr\xEAn Jai1 server..."));
13640
13692
  console.log();
13641
13693
  const skillsService = new SkillsService();
13642
13694
  const results = await skillsService.searchFromServer(config, query);
13643
13695
  if (results.length === 0) {
13644
- console.log(chalk35.yellow("Kh\xF4ng t\xECm th\u1EA5y skills n\xE0o tr\xEAn server."));
13696
+ console.log(chalk36.yellow("Kh\xF4ng t\xECm th\u1EA5y skills n\xE0o tr\xEAn server."));
13645
13697
  } else {
13646
13698
  const table = new Table8({
13647
13699
  head: [
13648
- chalk35.cyan("T\xEAn"),
13649
- chalk35.cyan("M\xF4 t\u1EA3"),
13650
- chalk35.cyan("Version"),
13651
- chalk35.cyan("Downloads")
13700
+ chalk36.cyan("T\xEAn"),
13701
+ chalk36.cyan("M\xF4 t\u1EA3"),
13702
+ chalk36.cyan("Version"),
13703
+ chalk36.cyan("Downloads")
13652
13704
  ],
13653
13705
  style: { head: [], border: ["gray"] },
13654
13706
  colWidths: [25, 40, 10, 12]
@@ -13656,70 +13708,70 @@ function createSkillsFindCommand() {
13656
13708
  for (const skill of results) {
13657
13709
  const name = skill.filepath.replace("skills/", "");
13658
13710
  table.push([
13659
- chalk35.white(name),
13660
- chalk35.dim((skill.description || "").slice(0, 38)),
13661
- chalk35.green(skill.version || "-"),
13662
- chalk35.dim(String(skill.downloads || 0))
13711
+ chalk36.white(name),
13712
+ chalk36.dim((skill.description || "").slice(0, 38)),
13713
+ chalk36.green(skill.version || "-"),
13714
+ chalk36.dim(String(skill.downloads || 0))
13663
13715
  ]);
13664
13716
  }
13665
- console.log(chalk35.bold(`\u{1F4E6} Jai1 Server (${results.length} k\u1EBFt qu\u1EA3)`));
13717
+ console.log(chalk36.bold(`\u{1F4E6} Jai1 Server (${results.length} k\u1EBFt qu\u1EA3)`));
13666
13718
  console.log(table.toString());
13667
13719
  console.log();
13668
13720
  }
13669
13721
  }
13670
13722
  if (searchNpm) {
13671
- console.log(chalk35.cyan("\u{1F50D} \u0110ang t\xECm ki\u1EBFm tr\xEAn npm skills..."));
13723
+ console.log(chalk36.cyan("\u{1F50D} \u0110ang t\xECm ki\u1EBFm tr\xEAn npm skills..."));
13672
13724
  console.log();
13673
13725
  const skillsService = new SkillsService();
13674
13726
  try {
13675
13727
  const output = await skillsService.npmSkillsFind(query);
13676
- console.log(chalk35.bold("\u{1F310} npm Skills Registry"));
13728
+ console.log(chalk36.bold("\u{1F310} npm Skills Registry"));
13677
13729
  console.log(output);
13678
13730
  } catch (error) {
13679
- console.log(chalk35.yellow(
13731
+ console.log(chalk36.yellow(
13680
13732
  `Kh\xF4ng th\u1EC3 t\xECm ki\u1EBFm tr\xEAn npm: ${error instanceof Error ? error.message : String(error)}`
13681
13733
  ));
13682
13734
  }
13683
13735
  }
13684
13736
  if (searchServer && !searchNpm) {
13685
- console.log(chalk35.dim('\u{1F4A1} D\xF9ng "j skills add <t\xEAn>" \u0111\u1EC3 c\xE0i \u0111\u1EB7t t\u1EEB server'));
13737
+ console.log(chalk36.dim('\u{1F4A1} D\xF9ng "j skills add <t\xEAn>" \u0111\u1EC3 c\xE0i \u0111\u1EB7t t\u1EEB server'));
13686
13738
  } else if (searchNpm && !searchServer) {
13687
- console.log(chalk35.dim('\u{1F4A1} D\xF9ng "j skills add <owner/repo@skill> --skillsh" \u0111\u1EC3 c\xE0i \u0111\u1EB7t'));
13739
+ console.log(chalk36.dim('\u{1F4A1} D\xF9ng "j skills add <owner/repo@skill> --skillsh" \u0111\u1EC3 c\xE0i \u0111\u1EB7t'));
13688
13740
  } else {
13689
- console.log(chalk35.dim("\u{1F4A1} C\xE0i \u0111\u1EB7t:"));
13690
- console.log(chalk35.dim(" Server: j skills add <t\xEAn>"));
13691
- console.log(chalk35.dim(" Skills.sh: j skills add <owner/repo@skill> --skillsh"));
13741
+ console.log(chalk36.dim("\u{1F4A1} C\xE0i \u0111\u1EB7t:"));
13742
+ console.log(chalk36.dim(" Server: j skills add <t\xEAn>"));
13743
+ console.log(chalk36.dim(" Skills.sh: j skills add <owner/repo@skill> --skillsh"));
13692
13744
  }
13693
13745
  });
13694
13746
  }
13695
13747
 
13696
13748
  // src/commands/skills/add.ts
13697
- import { Command as Command71 } from "commander";
13749
+ import { Command as Command72 } from "commander";
13698
13750
  import { join as join20 } from "path";
13699
- import chalk36 from "chalk";
13751
+ import chalk37 from "chalk";
13700
13752
  import { checkbox as checkbox7 } from "@inquirer/prompts";
13701
13753
  function createSkillsAddCommand() {
13702
- return new Command71("add").description("Install a skill to .jai1/skills/").argument("<name>", "Skill name or source (npm: GitHub shorthand, URL)").option("--skillsh", "Install from npm skills registry instead of Jai1 server").option("--sync", "Auto-sync to IDE(s) after install").option("--ides <ides...>", "Target IDEs for sync (cursor, windsurf, antigravity, claudecode, opencode)").option("--all", "Sync to all available IDEs").option("-y, --yes", "Headless mode (skip all prompts)").action(async (name, options) => {
13754
+ return new Command72("add").description("Install a skill to .jai1/skills/").argument("<name>", "Skill name or source (npm: GitHub shorthand, URL)").option("--skillsh", "Install from npm skills registry instead of Jai1 server").option("--sync", "Auto-sync to IDE(s) after install").option("--ides <ides...>", "Target IDEs for sync (cursor, windsurf, antigravity, claudecode, opencode)").option("--all", "Sync to all available IDEs").option("-y, --yes", "Headless mode (skip all prompts)").action(async (name, options) => {
13703
13755
  const skillsService = new SkillsService();
13704
13756
  const projectRoot = process.cwd();
13705
13757
  const headless = options.yes === true;
13706
13758
  if (options.skillsh) {
13707
- console.log(chalk36.cyan(`\u{1F310} \u0110ang c\xE0i \u0111\u1EB7t skill t\u1EEB npm: ${name}...`));
13759
+ console.log(chalk37.cyan(`\u{1F310} \u0110ang c\xE0i \u0111\u1EB7t skill t\u1EEB npm: ${name}...`));
13708
13760
  console.log();
13709
13761
  const output = await skillsService.npmSkillsAdd(name, projectRoot);
13710
13762
  console.log(output);
13711
- console.log(chalk36.green("\u2705 C\xE0i \u0111\u1EB7t t\u1EEB npm th\xE0nh c\xF4ng!"));
13763
+ console.log(chalk37.green("\u2705 C\xE0i \u0111\u1EB7t t\u1EEB npm th\xE0nh c\xF4ng!"));
13712
13764
  } else {
13713
13765
  const configService = new ConfigService();
13714
13766
  const config = await configService.load();
13715
13767
  if (!config) {
13716
13768
  throw new ValidationError('Ch\u01B0a x\xE1c th\u1EF1c. Ch\u1EA1y "jai1 auth" tr\u01B0\u1EDBc.');
13717
13769
  }
13718
- console.log(chalk36.cyan(`\u{1F4E6} \u0110ang c\xE0i \u0111\u1EB7t skill: ${name}...`));
13770
+ console.log(chalk37.cyan(`\u{1F4E6} \u0110ang c\xE0i \u0111\u1EB7t skill: ${name}...`));
13719
13771
  console.log();
13720
13772
  const targetDir = join20(projectRoot, ".jai1");
13721
13773
  await skillsService.installFromServer(config, name, targetDir);
13722
- console.log(chalk36.green(`\u2705 \u0110\xE3 c\xE0i \u0111\u1EB7t skill "${name}" v\xE0o .jai1/skills/${name}/`));
13774
+ console.log(chalk37.green(`\u2705 \u0110\xE3 c\xE0i \u0111\u1EB7t skill "${name}" v\xE0o .jai1/skills/${name}/`));
13723
13775
  }
13724
13776
  console.log();
13725
13777
  if (options.sync) {
@@ -13744,7 +13796,7 @@ function createSkillsAddCommand() {
13744
13796
  });
13745
13797
  }
13746
13798
  if (selectedIdes.length > 0) {
13747
- console.log(chalk36.cyan("\u{1F504} \u0110ang sync sang IDE(s)..."));
13799
+ console.log(chalk37.cyan("\u{1F504} \u0110ang sync sang IDE(s)..."));
13748
13800
  console.log();
13749
13801
  const slug = name.includes("/") ? name.split("/").pop() : name;
13750
13802
  const result = await skillsService.syncToIdes(
@@ -13757,24 +13809,24 @@ function createSkillsAddCommand() {
13757
13809
  }
13758
13810
  );
13759
13811
  console.log();
13760
- console.log(chalk36.green(`\u2705 Sync ho\xE0n t\u1EA5t! Created: ${result.created}, Updated: ${result.updated}`));
13812
+ console.log(chalk37.green(`\u2705 Sync ho\xE0n t\u1EA5t! Created: ${result.created}, Updated: ${result.updated}`));
13761
13813
  if (result.errors > 0) {
13762
- console.log(chalk36.yellow(`\u26A0\uFE0F Errors: ${result.errors}`));
13814
+ console.log(chalk37.yellow(`\u26A0\uFE0F Errors: ${result.errors}`));
13763
13815
  }
13764
13816
  }
13765
13817
  } else {
13766
- console.log(chalk36.dim('\u{1F4A1} Ch\u1EA1y "j skills sync" \u0111\u1EC3 \u0111\u1ED3ng b\u1ED9 sang IDE(s)'));
13767
- console.log(chalk36.dim(' ho\u1EB7c "j ide sync" \u0111\u1EC3 sync to\xE0n b\u1ED9 .jai1/'));
13818
+ console.log(chalk37.dim('\u{1F4A1} Ch\u1EA1y "j skills sync" \u0111\u1EC3 \u0111\u1ED3ng b\u1ED9 sang IDE(s)'));
13819
+ console.log(chalk37.dim(' ho\u1EB7c "j ide sync" \u0111\u1EC3 sync to\xE0n b\u1ED9 .jai1/'));
13768
13820
  }
13769
13821
  });
13770
13822
  }
13771
13823
 
13772
13824
  // src/commands/skills/list.ts
13773
- import { Command as Command72 } from "commander";
13774
- import chalk37 from "chalk";
13825
+ import { Command as Command73 } from "commander";
13826
+ import chalk38 from "chalk";
13775
13827
  import Table9 from "cli-table3";
13776
13828
  function createSkillsListCommand() {
13777
- return new Command72("list").description("List installed skills or available skills on server").option("--available", "List all skills available on Jai1 server").option("-s, --search <term>", "Search skills by name or description").action(async (options) => {
13829
+ return new Command73("list").description("List installed skills or available skills on server").option("--available", "List all skills available on Jai1 server").option("-s, --search <term>", "Search skills by name or description").action(async (options) => {
13778
13830
  const skillsService = new SkillsService();
13779
13831
  if (options.available) {
13780
13832
  const configService = new ConfigService();
@@ -13782,19 +13834,19 @@ function createSkillsListCommand() {
13782
13834
  if (!config) {
13783
13835
  throw new ValidationError('Ch\u01B0a x\xE1c th\u1EF1c. Ch\u1EA1y "jai1 auth" tr\u01B0\u1EDBc.');
13784
13836
  }
13785
- console.log(chalk37.cyan("\u{1F4E6} \u0110ang t\u1EA3i danh s\xE1ch skills t\u1EEB server..."));
13837
+ console.log(chalk38.cyan("\u{1F4E6} \u0110ang t\u1EA3i danh s\xE1ch skills t\u1EEB server..."));
13786
13838
  console.log();
13787
13839
  const results = await skillsService.searchFromServer(config, options.search);
13788
13840
  if (results.length === 0) {
13789
- console.log(chalk37.yellow("Kh\xF4ng t\xECm th\u1EA5y skills n\xE0o."));
13841
+ console.log(chalk38.yellow("Kh\xF4ng t\xECm th\u1EA5y skills n\xE0o."));
13790
13842
  return;
13791
13843
  }
13792
13844
  const table = new Table9({
13793
13845
  head: [
13794
- chalk37.cyan("T\xEAn"),
13795
- chalk37.cyan("M\xF4 t\u1EA3"),
13796
- chalk37.cyan("Version"),
13797
- chalk37.cyan("Downloads")
13846
+ chalk38.cyan("T\xEAn"),
13847
+ chalk38.cyan("M\xF4 t\u1EA3"),
13848
+ chalk38.cyan("Version"),
13849
+ chalk38.cyan("Downloads")
13798
13850
  ],
13799
13851
  style: { head: [], border: ["gray"] },
13800
13852
  colWidths: [28, 40, 10, 12]
@@ -13802,63 +13854,63 @@ function createSkillsListCommand() {
13802
13854
  for (const skill of results) {
13803
13855
  const name = skill.filepath.replace("skills/", "");
13804
13856
  table.push([
13805
- chalk37.white(name),
13806
- chalk37.dim((skill.description || "").slice(0, 38)),
13807
- chalk37.green(skill.version || "-"),
13808
- chalk37.dim(String(skill.downloads || 0))
13857
+ chalk38.white(name),
13858
+ chalk38.dim((skill.description || "").slice(0, 38)),
13859
+ chalk38.green(skill.version || "-"),
13860
+ chalk38.dim(String(skill.downloads || 0))
13809
13861
  ]);
13810
13862
  }
13811
13863
  console.log(table.toString());
13812
13864
  console.log();
13813
- console.log(chalk37.dim(`T\u1ED5ng c\u1ED9ng: ${results.length} skill(s)`));
13814
- console.log(chalk37.dim('\n\u{1F4A1} D\xF9ng "j skills add <t\xEAn>" \u0111\u1EC3 c\xE0i \u0111\u1EB7t'));
13865
+ console.log(chalk38.dim(`T\u1ED5ng c\u1ED9ng: ${results.length} skill(s)`));
13866
+ console.log(chalk38.dim('\n\u{1F4A1} D\xF9ng "j skills add <t\xEAn>" \u0111\u1EC3 c\xE0i \u0111\u1EB7t'));
13815
13867
  } else {
13816
13868
  const projectRoot = process.cwd();
13817
13869
  const skills = await skillsService.listLocal(projectRoot);
13818
13870
  if (skills.length === 0) {
13819
- console.log(chalk37.yellow("Ch\u01B0a c\xF3 skills n\xE0o \u0111\u01B0\u1EE3c c\xE0i \u0111\u1EB7t."));
13871
+ console.log(chalk38.yellow("Ch\u01B0a c\xF3 skills n\xE0o \u0111\u01B0\u1EE3c c\xE0i \u0111\u1EB7t."));
13820
13872
  console.log();
13821
- console.log(chalk37.dim('\u{1F4A1} D\xF9ng "j skills add <t\xEAn>" \u0111\u1EC3 c\xE0i \u0111\u1EB7t'));
13822
- console.log(chalk37.dim(' ho\u1EB7c "j skills list --available" \u0111\u1EC3 xem skills c\xF3 s\u1EB5n'));
13873
+ console.log(chalk38.dim('\u{1F4A1} D\xF9ng "j skills add <t\xEAn>" \u0111\u1EC3 c\xE0i \u0111\u1EB7t'));
13874
+ console.log(chalk38.dim(' ho\u1EB7c "j skills list --available" \u0111\u1EC3 xem skills c\xF3 s\u1EB5n'));
13823
13875
  return;
13824
13876
  }
13825
- console.log(chalk37.bold.cyan("\u{1F6E0} Skills \u0111\xE3 c\xE0i \u0111\u1EB7t"));
13877
+ console.log(chalk38.bold.cyan("\u{1F6E0} Skills \u0111\xE3 c\xE0i \u0111\u1EB7t"));
13826
13878
  console.log();
13827
13879
  const table = new Table9({
13828
13880
  head: [
13829
- chalk37.cyan("T\xEAn"),
13830
- chalk37.cyan("M\xF4 t\u1EA3"),
13831
- chalk37.cyan("Files")
13881
+ chalk38.cyan("T\xEAn"),
13882
+ chalk38.cyan("M\xF4 t\u1EA3"),
13883
+ chalk38.cyan("Files")
13832
13884
  ],
13833
13885
  style: { head: [], border: ["gray"] },
13834
13886
  colWidths: [28, 45, 8]
13835
13887
  });
13836
13888
  for (const skill of skills) {
13837
13889
  table.push([
13838
- chalk37.white(skill.slug),
13839
- chalk37.dim(skill.description.slice(0, 43)),
13840
- chalk37.dim(String(skill.fileCount))
13890
+ chalk38.white(skill.slug),
13891
+ chalk38.dim(skill.description.slice(0, 43)),
13892
+ chalk38.dim(String(skill.fileCount))
13841
13893
  ]);
13842
13894
  }
13843
13895
  console.log(table.toString());
13844
13896
  console.log();
13845
- console.log(chalk37.dim(`T\u1ED5ng c\u1ED9ng: ${skills.length} skill(s)`));
13846
- console.log(chalk37.dim('\n\u{1F4A1} D\xF9ng "j skills sync" \u0111\u1EC3 \u0111\u1ED3ng b\u1ED9 sang IDE(s)'));
13897
+ console.log(chalk38.dim(`T\u1ED5ng c\u1ED9ng: ${skills.length} skill(s)`));
13898
+ console.log(chalk38.dim('\n\u{1F4A1} D\xF9ng "j skills sync" \u0111\u1EC3 \u0111\u1ED3ng b\u1ED9 sang IDE(s)'));
13847
13899
  }
13848
13900
  });
13849
13901
  }
13850
13902
 
13851
13903
  // src/commands/skills/info.ts
13852
- import { Command as Command73 } from "commander";
13853
- import chalk38 from "chalk";
13904
+ import { Command as Command74 } from "commander";
13905
+ import chalk39 from "chalk";
13854
13906
  function createSkillsInfoCommand() {
13855
- return new Command73("info").description("Show detailed information about a skill").argument("<name>", "Skill name").option("--server", "Show info from Jai1 server instead of local").action(async (name, options) => {
13907
+ return new Command74("info").description("Show detailed information about a skill").argument("<name>", "Skill name").option("--server", "Show info from Jai1 server instead of local").action(async (name, options) => {
13856
13908
  const skillsService = new SkillsService();
13857
13909
  if (options.server) {
13858
13910
  const configService = new ConfigService();
13859
13911
  const config = await configService.load();
13860
13912
  if (!config) {
13861
- console.log(chalk38.red('\u274C Ch\u01B0a x\xE1c th\u1EF1c. Ch\u1EA1y "jai1 auth" tr\u01B0\u1EDBc.'));
13913
+ console.log(chalk39.red('\u274C Ch\u01B0a x\xE1c th\u1EF1c. Ch\u1EA1y "jai1 auth" tr\u01B0\u1EDBc.'));
13862
13914
  process.exit(1);
13863
13915
  }
13864
13916
  const filepath = name.startsWith("skills/") ? name : `skills/${name}`;
@@ -13867,7 +13919,7 @@ function createSkillsInfoCommand() {
13867
13919
  try {
13868
13920
  const component = await componentsService.get(config, filepath);
13869
13921
  console.log(`
13870
- \u{1F6E0} ${chalk38.bold(component.name || name)}
13922
+ \u{1F6E0} ${chalk39.bold(component.name || name)}
13871
13923
  `);
13872
13924
  console.log(`Filepath: ${component.filepath}`);
13873
13925
  console.log(`Version: ${component.version}`);
@@ -13880,47 +13932,47 @@ function createSkillsInfoCommand() {
13880
13932
  }
13881
13933
  console.log(`Type: ${component.contentType}`);
13882
13934
  console.log();
13883
- console.log(chalk38.dim('\u{1F4A1} D\xF9ng "j skills add ' + name + '" \u0111\u1EC3 c\xE0i \u0111\u1EB7t'));
13935
+ console.log(chalk39.dim('\u{1F4A1} D\xF9ng "j skills add ' + name + '" \u0111\u1EC3 c\xE0i \u0111\u1EB7t'));
13884
13936
  } catch (error) {
13885
- console.log(chalk38.red(`\u274C Kh\xF4ng t\xECm th\u1EA5y skill "${name}" tr\xEAn server.`));
13937
+ console.log(chalk39.red(`\u274C Kh\xF4ng t\xECm th\u1EA5y skill "${name}" tr\xEAn server.`));
13886
13938
  process.exit(1);
13887
13939
  }
13888
13940
  } else {
13889
13941
  const projectRoot = process.cwd();
13890
13942
  const skill = await skillsService.getSkillInfo(projectRoot, name);
13891
13943
  if (!skill) {
13892
- console.log(chalk38.red(`\u274C Skill "${name}" ch\u01B0a \u0111\u01B0\u1EE3c c\xE0i \u0111\u1EB7t.`));
13893
- console.log(chalk38.dim('\u{1F4A1} D\xF9ng "j skills info ' + name + ' --server" \u0111\u1EC3 xem tr\xEAn server'));
13894
- console.log(chalk38.dim(' ho\u1EB7c "j skills add ' + name + '" \u0111\u1EC3 c\xE0i \u0111\u1EB7t'));
13944
+ console.log(chalk39.red(`\u274C Skill "${name}" ch\u01B0a \u0111\u01B0\u1EE3c c\xE0i \u0111\u1EB7t.`));
13945
+ console.log(chalk39.dim('\u{1F4A1} D\xF9ng "j skills info ' + name + ' --server" \u0111\u1EC3 xem tr\xEAn server'));
13946
+ console.log(chalk39.dim(' ho\u1EB7c "j skills add ' + name + '" \u0111\u1EC3 c\xE0i \u0111\u1EB7t'));
13895
13947
  process.exit(1);
13896
13948
  }
13897
13949
  console.log(`
13898
- \u{1F6E0} ${chalk38.bold(skill.name)}
13950
+ \u{1F6E0} ${chalk39.bold(skill.name)}
13899
13951
  `);
13900
13952
  console.log(`Slug: ${skill.slug}`);
13901
- console.log(`Description: ${skill.description || chalk38.dim("(none)")}`);
13953
+ console.log(`Description: ${skill.description || chalk39.dim("(none)")}`);
13902
13954
  console.log(`Path: ${skill.path}`);
13903
13955
  console.log(`Files: ${skill.fileCount}`);
13904
13956
  console.log();
13905
- console.log(chalk38.dim('\u{1F4A1} D\xF9ng "j skills sync" \u0111\u1EC3 \u0111\u1ED3ng b\u1ED9 sang IDE(s)'));
13957
+ console.log(chalk39.dim('\u{1F4A1} D\xF9ng "j skills sync" \u0111\u1EC3 \u0111\u1ED3ng b\u1ED9 sang IDE(s)'));
13906
13958
  }
13907
13959
  });
13908
13960
  }
13909
13961
 
13910
13962
  // src/commands/skills/sync.ts
13911
- import { Command as Command74 } from "commander";
13912
- import chalk39 from "chalk";
13963
+ import { Command as Command75 } from "commander";
13964
+ import chalk40 from "chalk";
13913
13965
  import { confirm as confirm15, checkbox as checkbox8 } from "@inquirer/prompts";
13914
13966
  function createSkillsSyncCommand() {
13915
- return new Command74("sync").description("Sync skills from .jai1/skills/ to IDE directories").option("--ides <ides...>", "Target IDEs (cursor, windsurf, antigravity, claudecode, opencode)").option("--skills <skills...>", "Specific skill slugs to sync (default: all)").option("--all", "Select all available IDEs").option("--dry-run", "Preview changes without writing files").option("-y, --yes", "Headless mode (skip all prompts)").action(async (options) => {
13967
+ return new Command75("sync").description("Sync skills from .jai1/skills/ to IDE directories").option("--ides <ides...>", "Target IDEs (cursor, windsurf, antigravity, claudecode, opencode)").option("--skills <skills...>", "Specific skill slugs to sync (default: all)").option("--all", "Select all available IDEs").option("--dry-run", "Preview changes without writing files").option("-y, --yes", "Headless mode (skip all prompts)").action(async (options) => {
13916
13968
  const skillsService = new SkillsService();
13917
13969
  const projectRoot = process.cwd();
13918
13970
  const headless = options.yes === true;
13919
- console.log(chalk39.bold.cyan("\n\u{1F504} Sync skills sang IDE(s)\n"));
13971
+ console.log(chalk40.bold.cyan("\n\u{1F504} Sync skills sang IDE(s)\n"));
13920
13972
  const localSkills = await skillsService.listLocal(projectRoot);
13921
13973
  if (localSkills.length === 0) {
13922
- console.log(chalk39.yellow("\u26A0\uFE0F Kh\xF4ng c\xF3 skills n\xE0o trong .jai1/skills/"));
13923
- console.log(chalk39.dim('\u{1F4A1} Ch\u1EA1y "j skills add <t\xEAn>" \u0111\u1EC3 c\xE0i \u0111\u1EB7t skills tr\u01B0\u1EDBc'));
13974
+ console.log(chalk40.yellow("\u26A0\uFE0F Kh\xF4ng c\xF3 skills n\xE0o trong .jai1/skills/"));
13975
+ console.log(chalk40.dim('\u{1F4A1} Ch\u1EA1y "j skills add <t\xEAn>" \u0111\u1EC3 c\xE0i \u0111\u1EB7t skills tr\u01B0\u1EDBc'));
13924
13976
  process.exit(1);
13925
13977
  }
13926
13978
  console.log(`\u{1F4C1} T\xECm th\u1EA5y ${localSkills.length} skill(s) trong .jai1/skills/`);
@@ -13952,7 +14004,7 @@ function createSkillsSyncCommand() {
13952
14004
  theme: checkboxTheme
13953
14005
  });
13954
14006
  if (selectedIdes.length === 0) {
13955
- console.log(chalk39.yellow("\n\u26A0\uFE0F Ch\u01B0a ch\u1ECDn IDE n\xE0o!"));
14007
+ console.log(chalk40.yellow("\n\u26A0\uFE0F Ch\u01B0a ch\u1ECDn IDE n\xE0o!"));
13956
14008
  process.exit(0);
13957
14009
  }
13958
14010
  }
@@ -13967,7 +14019,7 @@ function createSkillsSyncCommand() {
13967
14019
  console.log(` Total: ${totalFiles} skill folder(s) s\u1EBD \u0111\u01B0\u1EE3c sync
13968
14020
  `);
13969
14021
  if (options.dryRun) {
13970
- console.log(chalk39.dim("\u{1F50D} DRY RUN - Kh\xF4ng c\xF3 file n\xE0o \u0111\u01B0\u1EE3c ghi\n"));
14022
+ console.log(chalk40.dim("\u{1F50D} DRY RUN - Kh\xF4ng c\xF3 file n\xE0o \u0111\u01B0\u1EE3c ghi\n"));
13971
14023
  return;
13972
14024
  }
13973
14025
  if (!headless) {
@@ -13976,25 +14028,25 @@ function createSkillsSyncCommand() {
13976
14028
  default: true
13977
14029
  });
13978
14030
  if (!confirmed) {
13979
- console.log(chalk39.yellow("\n\u274C \u0110\xE3 h\u1EE7y sync.\n"));
14031
+ console.log(chalk40.yellow("\n\u274C \u0110\xE3 h\u1EE7y sync.\n"));
13980
14032
  process.exit(0);
13981
14033
  }
13982
14034
  }
13983
- console.log(chalk39.cyan("\n\u{1F504} \u0110ang sync...\n"));
14035
+ console.log(chalk40.cyan("\n\u{1F504} \u0110ang sync...\n"));
13984
14036
  const result = await skillsService.syncToIdes(
13985
14037
  projectRoot,
13986
14038
  selectedIdes,
13987
14039
  selectedSlugs,
13988
14040
  (res) => {
13989
14041
  const icon = res.status === "created" ? "\u2713" : res.status === "updated" ? "\u21BB" : "\u2717";
13990
- const statusColor = res.status === "error" ? chalk39.red : chalk39.green;
13991
- console.log(` ${statusColor(icon)} ${res.ide}: ${res.skill} \u2192 ${chalk39.dim(res.path)}`);
14042
+ const statusColor = res.status === "error" ? chalk40.red : chalk40.green;
14043
+ console.log(` ${statusColor(icon)} ${res.ide}: ${res.skill} \u2192 ${chalk40.dim(res.path)}`);
13992
14044
  if (res.status === "error" && res.error) {
13993
- console.log(` ${chalk39.red("Error:")} ${res.error}`);
14045
+ console.log(` ${chalk40.red("Error:")} ${res.error}`);
13994
14046
  }
13995
14047
  }
13996
14048
  );
13997
- console.log(chalk39.green("\n\u2705 Sync ho\xE0n t\u1EA5t!\n"));
14049
+ console.log(chalk40.green("\n\u2705 Sync ho\xE0n t\u1EA5t!\n"));
13998
14050
  console.log(` Created: ${result.created}`);
13999
14051
  console.log(` Updated: ${result.updated}`);
14000
14052
  if (result.errors > 0) {
@@ -14007,27 +14059,27 @@ function createSkillsSyncCommand() {
14007
14059
  // src/commands/skills/index.ts
14008
14060
  function showSkillsHelp() {
14009
14061
  const cli = getCliName();
14010
- console.log(chalk40.bold.cyan("\u{1F6E0} " + cli + " skills") + chalk40.dim(" - Qu\u1EA3n l\xFD agent skills"));
14062
+ console.log(chalk41.bold.cyan("\u{1F6E0} " + cli + " skills") + chalk41.dim(" - Qu\u1EA3n l\xFD agent skills"));
14011
14063
  console.log();
14012
- console.log(chalk40.bold("C\xE1c l\u1EC7nh:"));
14013
- console.log(` ${chalk40.cyan("find")} T\xECm ki\u1EBFm skills tr\xEAn server ho\u1EB7c npm`);
14014
- console.log(` ${chalk40.cyan("add")} C\xE0i \u0111\u1EB7t skill v\xE0o .jai1/skills/`);
14015
- console.log(` ${chalk40.cyan("list")} Li\u1EC7t k\xEA skills \u0111\xE3 c\xE0i ho\u1EB7c c\xF3 s\u1EB5n`);
14016
- console.log(` ${chalk40.cyan("info")} Xem chi ti\u1EBFt m\u1ED9t skill`);
14017
- console.log(` ${chalk40.cyan("sync")} \u0110\u1ED3ng b\u1ED9 skills sang c\xE1c IDE`);
14064
+ console.log(chalk41.bold("C\xE1c l\u1EC7nh:"));
14065
+ console.log(` ${chalk41.cyan("find")} T\xECm ki\u1EBFm skills tr\xEAn server ho\u1EB7c npm`);
14066
+ console.log(` ${chalk41.cyan("add")} C\xE0i \u0111\u1EB7t skill v\xE0o .jai1/skills/`);
14067
+ console.log(` ${chalk41.cyan("list")} Li\u1EC7t k\xEA skills \u0111\xE3 c\xE0i ho\u1EB7c c\xF3 s\u1EB5n`);
14068
+ console.log(` ${chalk41.cyan("info")} Xem chi ti\u1EBFt m\u1ED9t skill`);
14069
+ console.log(` ${chalk41.cyan("sync")} \u0110\u1ED3ng b\u1ED9 skills sang c\xE1c IDE`);
14018
14070
  console.log();
14019
- console.log(chalk40.bold("V\xED d\u1EE5:"));
14020
- console.log(chalk40.dim(` $ ${cli} skills find audit`));
14021
- console.log(chalk40.dim(` $ ${cli} skills find "react" --skillsh`));
14022
- console.log(chalk40.dim(` $ ${cli} skills add brainstorming`));
14023
- console.log(chalk40.dim(` $ ${cli} skills add vercel/next-skills --skillsh`));
14024
- console.log(chalk40.dim(` $ ${cli} skills list`));
14025
- console.log(chalk40.dim(` $ ${cli} skills sync --all -y`));
14071
+ console.log(chalk41.bold("V\xED d\u1EE5:"));
14072
+ console.log(chalk41.dim(` $ ${cli} skills find audit`));
14073
+ console.log(chalk41.dim(` $ ${cli} skills find "react" --skillsh`));
14074
+ console.log(chalk41.dim(` $ ${cli} skills add brainstorming`));
14075
+ console.log(chalk41.dim(` $ ${cli} skills add vercel/next-skills --skillsh`));
14076
+ console.log(chalk41.dim(` $ ${cli} skills list`));
14077
+ console.log(chalk41.dim(` $ ${cli} skills sync --all -y`));
14026
14078
  console.log();
14027
- console.log(chalk40.dim(`Ch\u1EA1y "${cli} skills <l\u1EC7nh> --help" \u0111\u1EC3 xem chi ti\u1EBFt`));
14079
+ console.log(chalk41.dim(`Ch\u1EA1y "${cli} skills <l\u1EC7nh> --help" \u0111\u1EC3 xem chi ti\u1EBFt`));
14028
14080
  }
14029
14081
  function createSkillsCommand() {
14030
- const cmd = new Command75("skills").alias("s").description("Manage agent skills (search, install, sync to IDEs)").action(() => {
14082
+ const cmd = new Command76("skills").alias("s").description("Manage agent skills (search, install, sync to IDEs)").action(() => {
14031
14083
  showSkillsHelp();
14032
14084
  });
14033
14085
  cmd.addCommand(createSkillsFindCommand());
@@ -14039,7 +14091,7 @@ function createSkillsCommand() {
14039
14091
  }
14040
14092
 
14041
14093
  // src/commands/upgrade.ts
14042
- import { Command as Command76 } from "commander";
14094
+ import { Command as Command77 } from "commander";
14043
14095
  import { confirm as confirm16 } from "@inquirer/prompts";
14044
14096
  import { execSync as execSync5 } from "child_process";
14045
14097
  var colors2 = {
@@ -14051,7 +14103,7 @@ var colors2 = {
14051
14103
  bold: "\x1B[1m"
14052
14104
  };
14053
14105
  function createUpgradeCommand() {
14054
- return new Command76("upgrade").description("Upgrade CLI client to the latest version").option("--check", "Only check for updates without installing").option("--force", "Force upgrade without confirmation").action(async (options) => {
14106
+ return new Command77("upgrade").description("Upgrade CLI client to the latest version").option("--check", "Only check for updates without installing").option("--force", "Force upgrade without confirmation").action(async (options) => {
14055
14107
  await handleUpgrade(options);
14056
14108
  });
14057
14109
  }
@@ -14199,11 +14251,11 @@ function getInstallCommand(packageManager2) {
14199
14251
  }
14200
14252
 
14201
14253
  // src/commands/clean.ts
14202
- import { Command as Command77 } from "commander";
14254
+ import { Command as Command78 } from "commander";
14203
14255
  import { confirm as confirm17, select as select6 } from "@inquirer/prompts";
14204
14256
  import { join as join21 } from "path";
14205
14257
  function createCleanCommand() {
14206
- return new Command77("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) => {
14258
+ return new Command78("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) => {
14207
14259
  await handleClean(options);
14208
14260
  });
14209
14261
  }
@@ -14317,7 +14369,7 @@ async function cleanTarget(target, skipConfirm) {
14317
14369
  }
14318
14370
 
14319
14371
  // src/commands/redmine/check.ts
14320
- import { Command as Command78 } from "commander";
14372
+ import { Command as Command79 } from "commander";
14321
14373
 
14322
14374
  // src/services/redmine-config.service.ts
14323
14375
  import { readFile as readFile7 } from "fs/promises";
@@ -14624,7 +14676,7 @@ async function checkConnectivity(config) {
14624
14676
 
14625
14677
  // src/commands/redmine/check.ts
14626
14678
  function createRedmineCheckCommand() {
14627
- const cmd = new Command78("check").description("Check Redmine connectivity").option("-c, --config <path>", "Config file path", "redmine.config.yaml").option("--json", "Output as JSON").action(async (options) => {
14679
+ const cmd = new Command79("check").description("Check Redmine connectivity").option("-c, --config <path>", "Config file path", "redmine.config.yaml").option("--json", "Output as JSON").action(async (options) => {
14628
14680
  await handleRedmineCheck(options);
14629
14681
  });
14630
14682
  return cmd;
@@ -14652,7 +14704,7 @@ async function handleRedmineCheck(options) {
14652
14704
  }
14653
14705
 
14654
14706
  // src/commands/redmine/sync-issue.ts
14655
- import { Command as Command79 } from "commander";
14707
+ import { Command as Command80 } from "commander";
14656
14708
 
14657
14709
  // src/sync-issue.ts
14658
14710
  import { resolve as resolve3, relative } from "path";
@@ -15036,7 +15088,7 @@ function extractIssueIdFromUrl(url) {
15036
15088
 
15037
15089
  // src/commands/redmine/sync-issue.ts
15038
15090
  function createSyncIssueCommand() {
15039
- const cmd = new Command79("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) => {
15091
+ const cmd = new Command80("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) => {
15040
15092
  await handleSyncIssue(options);
15041
15093
  });
15042
15094
  return cmd;
@@ -15080,7 +15132,7 @@ async function handleSyncIssue(options) {
15080
15132
  }
15081
15133
 
15082
15134
  // src/commands/redmine/sync-project.ts
15083
- import { Command as Command80 } from "commander";
15135
+ import { Command as Command81 } from "commander";
15084
15136
 
15085
15137
  // src/sync-project.ts
15086
15138
  async function syncProject(config, options = {}) {
@@ -15150,7 +15202,7 @@ async function syncProject(config, options = {}) {
15150
15202
 
15151
15203
  // src/commands/redmine/sync-project.ts
15152
15204
  function createSyncProjectCommand() {
15153
- const cmd = new Command80("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) => {
15205
+ const cmd = new Command81("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) => {
15154
15206
  await handleSyncProject(options);
15155
15207
  });
15156
15208
  return cmd;
@@ -15205,12 +15257,12 @@ async function handleSyncProject(options) {
15205
15257
  }
15206
15258
 
15207
15259
  // src/commands/framework/info.ts
15208
- import { Command as Command81 } from "commander";
15260
+ import { Command as Command82 } from "commander";
15209
15261
  import { promises as fs28 } from "fs";
15210
15262
  import { join as join22 } from "path";
15211
15263
  import { homedir as homedir5 } from "os";
15212
15264
  function createInfoCommand() {
15213
- const cmd = new Command81("info").description("Show client configuration and status").option("--json", "Output as JSON").option("--verbose", "Show detailed information").action(async (options) => {
15265
+ const cmd = new Command82("info").description("Show client configuration and status").option("--json", "Output as JSON").option("--verbose", "Show detailed information").action(async (options) => {
15214
15266
  await handleInfo(options);
15215
15267
  });
15216
15268
  return cmd;
@@ -15266,7 +15318,7 @@ async function getProjectStatus2() {
15266
15318
  }
15267
15319
 
15268
15320
  // src/commands/self-update.ts
15269
- import { Command as Command82 } from "commander";
15321
+ import { Command as Command83 } from "commander";
15270
15322
  import { confirm as confirm18 } from "@inquirer/prompts";
15271
15323
  import { execSync as execSync6 } from "child_process";
15272
15324
  var colors3 = {
@@ -15278,7 +15330,7 @@ var colors3 = {
15278
15330
  bold: "\x1B[1m"
15279
15331
  };
15280
15332
  function createSelfUpdateCommand() {
15281
- return new Command82("self-update").description("Update CLI client to the latest version").option("--check", "Only check for updates without installing").option("--force", "Force update without confirmation").action(async (options) => {
15333
+ return new Command83("self-update").description("Update CLI client to the latest version").option("--check", "Only check for updates without installing").option("--force", "Force update without confirmation").action(async (options) => {
15282
15334
  await handleSelfUpdate(options);
15283
15335
  });
15284
15336
  }
@@ -15418,10 +15470,10 @@ function getInstallCommand2(packageManager2) {
15418
15470
  }
15419
15471
 
15420
15472
  // src/commands/clear-backups.ts
15421
- import { Command as Command83 } from "commander";
15473
+ import { Command as Command84 } from "commander";
15422
15474
  import { confirm as confirm19 } from "@inquirer/prompts";
15423
15475
  function createClearBackupsCommand() {
15424
- return new Command83("clear-backups").description("Clear backup files").option("-y, --yes", "Skip confirmation").action(async (options) => {
15476
+ return new Command84("clear-backups").description("Clear backup files").option("-y, --yes", "Skip confirmation").action(async (options) => {
15425
15477
  const service = new ComponentsService();
15426
15478
  const backups = await service.listBackups(process.cwd());
15427
15479
  if (backups.length === 0) {
@@ -15446,7 +15498,7 @@ function createClearBackupsCommand() {
15446
15498
  }
15447
15499
 
15448
15500
  // src/commands/vscode/index.ts
15449
- import { Command as Command84 } from "commander";
15501
+ import { Command as Command85 } from "commander";
15450
15502
  import { checkbox as checkbox9, confirm as confirm20, select as select7 } from "@inquirer/prompts";
15451
15503
  import fs29 from "fs/promises";
15452
15504
  import path12 from "path";
@@ -15586,7 +15638,7 @@ var PERFORMANCE_GROUPS2 = {
15586
15638
  }
15587
15639
  };
15588
15640
  function createVSCodeCommand() {
15589
- const vscodeCommand = new Command84("vscode").description("Qu\u1EA3n l\xFD c\xE0i \u0111\u1EB7t VSCode cho d\u1EF1 \xE1n hi\u1EC7n t\u1EA1i");
15641
+ const vscodeCommand = new Command85("vscode").description("Qu\u1EA3n l\xFD c\xE0i \u0111\u1EB7t VSCode cho d\u1EF1 \xE1n hi\u1EC7n t\u1EA1i");
15590
15642
  vscodeCommand.action(async () => {
15591
15643
  await interactiveMode2();
15592
15644
  });
@@ -15757,10 +15809,10 @@ async function resetSettings2(groupKeys) {
15757
15809
  }
15758
15810
 
15759
15811
  // src/commands/migrate-ide.ts
15760
- import { Command as Command85 } from "commander";
15812
+ import { Command as Command86 } from "commander";
15761
15813
  import { checkbox as checkbox10, confirm as confirm21 } from "@inquirer/prompts";
15762
15814
  function createMigrateIdeCommand() {
15763
- const cmd = new Command85("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) => {
15815
+ const cmd = new Command86("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) => {
15764
15816
  await runMigrateIde(options);
15765
15817
  });
15766
15818
  return cmd;
@@ -15869,20 +15921,20 @@ async function runMigrateIde(options) {
15869
15921
 
15870
15922
  // src/utils/help-formatter.ts
15871
15923
  import boxen4 from "boxen";
15872
- import chalk41 from "chalk";
15924
+ import chalk42 from "chalk";
15873
15925
  import gradient from "gradient-string";
15874
15926
  import figlet from "figlet";
15875
15927
  function showCustomHelp(version) {
15876
15928
  const title = figlet.textSync("JAI1", { font: "Small" });
15877
15929
  console.log(gradient.pastel(title));
15878
15930
  console.log(
15879
- boxen4(chalk41.cyan(`Agentic Coding CLI v${version}`), {
15931
+ boxen4(chalk42.cyan(`Agentic Coding CLI v${version}`), {
15880
15932
  padding: { left: 1, right: 1, top: 0, bottom: 0 },
15881
15933
  borderStyle: "round",
15882
15934
  borderColor: "cyan"
15883
15935
  })
15884
15936
  );
15885
- console.log(chalk41.bold("\n\u{1F527} Thi\u1EBFt l\u1EADp & Th\xF4ng tin"));
15937
+ console.log(chalk42.bold("\n\u{1F527} Thi\u1EBFt l\u1EADp & Th\xF4ng tin"));
15886
15938
  console.log(" auth X\xE1c th\u1EF1c v\xE0 c\u1EA5u h\xECnh client");
15887
15939
  console.log(" status Hi\u1EC3n th\u1ECB tr\u1EA1ng th\xE1i c\u1EA5u h\xECnh");
15888
15940
  console.log(" client-info T\u1EA1o th\xF4ng tin client \u0111\u1EC3 g\u1EEDi \u0111\u1ED9i ph\xE1t tri\u1EC3n");
@@ -15890,43 +15942,43 @@ function showCustomHelp(version) {
15890
15942
  console.log(" guide H\u01B0\u1EDBng d\u1EABn s\u1EED d\u1EE5ng nhanh");
15891
15943
  console.log(" quickstart B\u1EAFt \u0111\u1EA7u t\u1EEB \u0111\xE2u? (theo t\xECnh hu\u1ED1ng)");
15892
15944
  console.log(" doctor Chu\u1EA9n \u0111o\xE1n project hi\u1EC7n t\u1EA1i");
15893
- console.log(chalk41.bold("\n\u{1F4E6} Qu\u1EA3n l\xFD Components"));
15945
+ console.log(chalk42.bold("\n\u{1F4E6} Qu\u1EA3n l\xFD Components"));
15894
15946
  console.log(" apply C\xE0i \u0111\u1EB7t components (interactive)");
15895
15947
  console.log(" update C\u1EADp nh\u1EADt components \u0111\xE3 c\xE0i");
15896
15948
  console.log(" check Ki\u1EC3m tra c\u1EADp nh\u1EADt t\u1EEB server");
15897
- console.log(chalk41.bold("\n\u{1F5A5}\uFE0F IDE & T\xEDch h\u1EE3p"));
15949
+ console.log(chalk42.bold("\n\u{1F5A5}\uFE0F IDE & T\xEDch h\u1EE3p"));
15898
15950
  console.log(" ide L\u1EC7nh c\u1EA5u h\xECnh IDE");
15899
15951
  console.log(" chat Chat AI v\u1EDBi Jai1 LLM Proxy");
15900
15952
  console.log(" openai-keys Th\xF4ng tin API credentials");
15901
- console.log(chalk41.bold("\n\u{1F916} AI Tools"));
15953
+ console.log(chalk42.bold("\n\u{1F916} AI Tools"));
15902
15954
  console.log(" translate D\u1ECBch v\u0103n b\u1EA3n/file b\u1EB1ng AI");
15903
15955
  console.log(" image T\u1EA1o \u1EA3nh (Coming Soon)");
15904
15956
  console.log(" stats Th\u1ED1ng k\xEA s\u1EED d\u1EE5ng LLM");
15905
15957
  console.log(" feedback G\u1EEDi b\xE1o c\xE1o/\u0111\u1EC1 xu\u1EA5t");
15906
- console.log(chalk41.bold("\n\u{1F4C1} Project"));
15958
+ console.log(chalk42.bold("\n\u{1F4C1} Project"));
15907
15959
  console.log(" kit Qu\u1EA3n l\xFD starter kits");
15908
15960
  console.log(" tasks (t) Qu\u1EA3n l\xFD tasks ph\xE1t tri\u1EC3n");
15909
15961
  console.log(" rules Qu\u1EA3n l\xFD rule presets");
15910
15962
  console.log(" deps Qu\u1EA3n l\xFD dependencies");
15911
15963
  console.log(" redmine Redmine context sync");
15912
- console.log(chalk41.bold("\n\u2699\uFE0F B\u1EA3o tr\xEC"));
15964
+ console.log(chalk42.bold("\n\u2699\uFE0F B\u1EA3o tr\xEC"));
15913
15965
  console.log(" upgrade C\u1EADp nh\u1EADt CLI client");
15914
15966
  console.log(" clean D\u1ECDn d\u1EB9p cache/backup");
15915
15967
  console.log(" utils Developer utilities");
15916
15968
  const name = getCliName();
15917
- console.log(chalk41.dim(`
15969
+ console.log(chalk42.dim(`
15918
15970
  S\u1EED d\u1EE5ng: ${name} [l\u1EC7nh] --help \u0111\u1EC3 xem chi ti\u1EBFt`));
15919
15971
  }
15920
15972
  function showUnknownCommand(commandName) {
15921
- console.error(chalk41.red(`\u274C L\u1EC7nh kh\xF4ng t\u1ED3n t\u1EA1i: ${commandName}`));
15973
+ console.error(chalk42.red(`\u274C L\u1EC7nh kh\xF4ng t\u1ED3n t\u1EA1i: ${commandName}`));
15922
15974
  const name = getCliName();
15923
- console.error(chalk41.dim(`
15975
+ console.error(chalk42.dim(`
15924
15976
  G\u1EE3i \xFD: Ch\u1EA1y ${name} --help \u0111\u1EC3 xem danh s\xE1ch l\u1EC7nh`));
15925
15977
  }
15926
15978
 
15927
15979
  // src/cli.ts
15928
15980
  checkNodeVersion();
15929
- var program = new Command86();
15981
+ var program = new Command87();
15930
15982
  if (process.argv.includes("-v") || process.argv.includes("--version")) {
15931
15983
  console.log(package_default.version);
15932
15984
  if (!process.argv.includes("--skip-update-check")) {
@@ -15968,9 +16020,9 @@ program.addCommand(createSkillsCommand());
15968
16020
  program.addCommand(createHooksCommand());
15969
16021
  program.addCommand(createUpgradeCommand());
15970
16022
  program.addCommand(createCleanCommand());
15971
- var redmineCommand = new Command86("redmine").description("Redmine context sync commands");
16023
+ var redmineCommand = new Command87("redmine").description("Redmine context sync commands");
15972
16024
  redmineCommand.addCommand(createRedmineCheckCommand());
15973
- var syncCommand = new Command86("sync").description("Sync Redmine issues to markdown files");
16025
+ var syncCommand = new Command87("sync").description("Sync Redmine issues to markdown files");
15974
16026
  syncCommand.addCommand(createSyncIssueCommand());
15975
16027
  syncCommand.addCommand(createSyncProjectCommand());
15976
16028
  redmineCommand.addCommand(syncCommand);