@jvittechs/j 1.0.24 → 1.0.26

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
@@ -42,7 +42,7 @@ function checkNodeVersion() {
42
42
  }
43
43
 
44
44
  // src/cli.ts
45
- import { Command as Command78 } from "commander";
45
+ import { Command as Command79 } from "commander";
46
46
 
47
47
  // src/errors/index.ts
48
48
  var Jai1Error = class extends Error {
@@ -169,7 +169,7 @@ import { basename as basename4 } from "path";
169
169
  // package.json
170
170
  var package_default = {
171
171
  name: "@jvittechs/j",
172
- version: "1.0.24",
172
+ version: "1.0.26",
173
173
  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.",
174
174
  type: "module",
175
175
  bin: {
@@ -4201,12 +4201,63 @@ function showGuide(name) {
4201
4201
  console.log();
4202
4202
  console.log(chalk8.dim(`\u{1F4A1} Ch\u1EA1y "${name} <l\u1EC7nh> --help" \u0111\u1EC3 xem chi ti\u1EBFt t\u1EEBng l\u1EC7nh.`));
4203
4203
  console.log(chalk8.dim(`\u{1F4A1} Ch\u1EA1y "${name} t guide" \u0111\u1EC3 xem h\u01B0\u1EDBng d\u1EABn task management \u0111\u1EA7y \u0111\u1EE7.`));
4204
+ console.log(chalk8.dim(`\u{1F4A1} Ch\u1EA1y "${name} quickstart" \u0111\u1EC3 xem h\u01B0\u1EDBng d\u1EABn theo t\xECnh hu\u1ED1ng ph\xE1t tri\u1EC3n.`));
4204
4205
  console.log();
4205
4206
  }
4206
4207
 
4207
- // src/commands/doctor.ts
4208
+ // src/commands/quickstart.ts
4208
4209
  import { Command as Command13 } from "commander";
4209
4210
  import chalk9 from "chalk";
4211
+ function createQuickstartCommand() {
4212
+ const cmd = new Command13("quickstart").description("H\u01B0\u1EDBng d\u1EABn nhanh theo t\u1EEBng t\xECnh hu\u1ED1ng ph\xE1t tri\u1EC3n").action(() => {
4213
+ const name = getCliName();
4214
+ showQuickstart(name);
4215
+ });
4216
+ return cmd;
4217
+ }
4218
+ function showQuickstart(name) {
4219
+ console.log(chalk9.cyan.bold("\n\u{1F680} Quickstart - B\u1EAFt \u0111\u1EA7u t\u1EEB \u0111\xE2u?\n"));
4220
+ console.log(chalk9.dim("Ch\u1ECDn t\xECnh hu\u1ED1ng ph\xF9 h\u1EE3p v\u1EDBi b\u1EA1n:\n"));
4221
+ console.log(chalk9.bold("\u2501\u2501\u2501 \u{1F3C1} M\u1EDAI B\u1EAET \u0110\u1EA6U \u2501\u2501\u2501"));
4222
+ console.log(` ${chalk9.cyan(`${name} doctor`)} Ki\u1EC3m tra project \u0111\xE3 setup \u0111\xFAng ch\u01B0a`);
4223
+ console.log(` ${chalk9.cyan(`${name} guide`)} Xem to\xE0n b\u1ED9 h\u01B0\u1EDBng d\u1EABn CLI commands`);
4224
+ console.log(` ${chalk9.cyan(`${name} t guide`)} H\u01B0\u1EDBng d\u1EABn chi ti\u1EBFt task management`);
4225
+ console.log();
4226
+ console.log(chalk9.bold("\u2501\u2501\u2501 \u{1F4CB} L\xCAN K\u1EBE HO\u1EA0CH \u2501\u2501\u2501"));
4227
+ console.log(` ${chalk9.cyan("/develop-feature")} Ph\xE1t tri\u1EC3n t\xEDnh n\u0103ng m\u1EDBi (FRD \u2192 TDD \u2192 Code)`);
4228
+ console.log(` ${chalk9.cyan("/plan")} L\xEAn k\u1EBF ho\u1EA1ch nhanh \u2192 t\u1EA1o tasks \u2192 implement`);
4229
+ console.log(` ${chalk9.cyan("/improve")} Ph\xE2n t\xEDch & \u0111\u1EC1 xu\u1EA5t c\u1EA3i thi\u1EC7n project`);
4230
+ console.log();
4231
+ console.log(chalk9.bold("\u2501\u2501\u2501 \u2705 L\xC0M VI\u1EC6C V\u1EDAI TASKS \u2501\u2501\u2501"));
4232
+ console.log(` ${chalk9.cyan("/pick-next-task")} Resume ho\u1EB7c b\u1EAFt \u0111\u1EA7u task ti\u1EBFp theo`);
4233
+ console.log(` ${chalk9.cyan("/review-tasks")} Review danh s\xE1ch tasks, ph\xE1t hi\u1EC7n v\u1EA5n \u0111\u1EC1`);
4234
+ console.log(` ${chalk9.cyan(`${name} t ready`)} Xem c\xE1c tasks s\u1EB5n s\xE0ng \u0111\u1EC3 l\xE0m`);
4235
+ console.log(` ${chalk9.cyan(`${name} t summary`)} Dashboard t\u1ED5ng quan tasks`);
4236
+ console.log();
4237
+ console.log(chalk9.bold("\u2501\u2501\u2501 \u{1F50D} CH\u1EA4T L\u01AF\u1EE2NG CODE \u2501\u2501\u2501"));
4238
+ console.log(` ${chalk9.cyan("/review-local-changes")} Review code thay \u0111\u1ED5i tr\u01B0\u1EDBc khi commit`);
4239
+ console.log(` ${chalk9.cyan("/commit-it")} Commit an to\xE0n v\u1EDBi message chi ti\u1EBFt`);
4240
+ console.log(` ${chalk9.cyan("/fix-bug")} Ph\xE2n t\xEDch & s\u1EEDa bug`);
4241
+ console.log();
4242
+ console.log(chalk9.bold("\u2501\u2501\u2501 \u{1F4DD} T\xC0I LI\u1EC6U \u2501\u2501\u2501"));
4243
+ console.log(` ${chalk9.cyan("/gen-feature-doc")} T\u1EA1o t\xE0i li\u1EC7u cho 1 t\xEDnh n\u0103ng`);
4244
+ console.log(` ${chalk9.cyan("/gen-all-features-doc")} T\u1EA1o t\xE0i li\u1EC7u cho to\xE0n b\u1ED9 t\xEDnh n\u0103ng`);
4245
+ console.log(` ${chalk9.cyan("/gen-project-overview")} T\u1EA1o t\u1ED5ng quan project`);
4246
+ console.log();
4247
+ console.log(chalk9.yellow.bold("\u2501\u2501\u2501 \u{1F4A1} FLOW PH\xC1T TRI\u1EC2N PH\u1ED4 BI\u1EBEN \u2501\u2501\u2501"));
4248
+ console.log(chalk9.dim(" 1. Ki\u1EC3m tra setup \u2192 j doctor"));
4249
+ console.log(chalk9.dim(" 2. L\xEAn k\u1EBF ho\u1EA1ch \u2192 /develop-feature ho\u1EB7c /plan"));
4250
+ console.log(chalk9.dim(" 3. L\xE0m task \u2192 /pick-next-task"));
4251
+ console.log(chalk9.dim(" 4. Review & commit \u2192 /review-local-changes \u2192 /commit-it"));
4252
+ console.log(chalk9.dim(" 5. Ki\u1EC3m tra tasks c\xF2n l\u1EA1i \u2192 /review-tasks"));
4253
+ console.log();
4254
+ console.log(chalk9.dim(`\u{1F4A1} Ch\u1EA1y "${name} guide" \u0111\u1EC3 xem \u0111\u1EA7y \u0111\u1EE7 danh s\xE1ch commands.`));
4255
+ console.log();
4256
+ }
4257
+
4258
+ // src/commands/doctor.ts
4259
+ import { Command as Command14 } from "commander";
4260
+ import chalk10 from "chalk";
4210
4261
  import { promises as fs9 } from "fs";
4211
4262
  import { join as join6 } from "path";
4212
4263
  var CORE_FILES = [
@@ -4225,7 +4276,7 @@ var CORE_FILES = [
4225
4276
  "skills/latest-version"
4226
4277
  ];
4227
4278
  function createDoctorCommand() {
4228
- const cmd = new Command13("doctor").description("Chu\u1EA9n \u0111o\xE1n project hi\u1EC7n t\u1EA1i").option("--json", "Output as JSON").action(async (options) => {
4279
+ const cmd = new Command14("doctor").description("Chu\u1EA9n \u0111o\xE1n project hi\u1EC7n t\u1EA1i").option("--json", "Output as JSON").action(async (options) => {
4229
4280
  await runDoctor(options);
4230
4281
  });
4231
4282
  return cmd;
@@ -4234,8 +4285,8 @@ async function runDoctor(options) {
4234
4285
  const name = getCliName();
4235
4286
  const results = [];
4236
4287
  if (!options.json) {
4237
- console.log(chalk9.cyan.bold("\n\u{1FA7A} Jai1 Doctor\n"));
4238
- console.log(chalk9.dim(` \u0110ang ki\u1EC3m tra project t\u1EA1i: ${process.cwd()}
4288
+ console.log(chalk10.cyan.bold("\n\u{1FA7A} Jai1 Doctor\n"));
4289
+ console.log(chalk10.dim(` \u0110ang ki\u1EC3m tra project t\u1EA1i: ${process.cwd()}
4239
4290
  `));
4240
4291
  }
4241
4292
  results.push(await checkAuth(name));
@@ -4248,19 +4299,19 @@ async function runDoctor(options) {
4248
4299
  return;
4249
4300
  }
4250
4301
  for (const result of results) {
4251
- const icon = result.passed ? chalk9.green("\u2713") : chalk9.red("\u2717");
4252
- const label = result.passed ? chalk9.green(result.message) : chalk9.red(result.message);
4253
- console.log(` ${icon} ${chalk9.bold(result.name)}: ${label}`);
4302
+ const icon = result.passed ? chalk10.green("\u2713") : chalk10.red("\u2717");
4303
+ const label = result.passed ? chalk10.green(result.message) : chalk10.red(result.message);
4304
+ console.log(` ${icon} ${chalk10.bold(result.name)}: ${label}`);
4254
4305
  if (result.details && result.details.length > 0) {
4255
4306
  for (const detail of result.details) {
4256
- console.log(chalk9.dim(` ${detail}`));
4307
+ console.log(chalk10.dim(` ${detail}`));
4257
4308
  }
4258
4309
  }
4259
4310
  if (!result.passed && result.suggestion) {
4260
4311
  const lines = result.suggestion.split("\n");
4261
- console.log(chalk9.yellow(` \u{1F4A1} ${lines[0]}`));
4312
+ console.log(chalk10.yellow(` \u{1F4A1} ${lines[0]}`));
4262
4313
  for (const line of lines.slice(1)) {
4263
- console.log(chalk9.yellow(` ${line}`));
4314
+ console.log(chalk10.yellow(` ${line}`));
4264
4315
  }
4265
4316
  }
4266
4317
  console.log();
@@ -4268,11 +4319,11 @@ async function runDoctor(options) {
4268
4319
  const passed = results.filter((r) => r.passed).length;
4269
4320
  const total = results.length;
4270
4321
  if (passed === total) {
4271
- console.log(chalk9.green.bold(` \u2705 T\u1EA5t c\u1EA3 ${total} ki\u1EC3m tra \u0111\xE3 pass!
4322
+ console.log(chalk10.green.bold(` \u2705 T\u1EA5t c\u1EA3 ${total} ki\u1EC3m tra \u0111\xE3 pass!
4272
4323
  `));
4273
4324
  } else {
4274
4325
  console.log(
4275
- chalk9.yellow(` \u26A0\uFE0F ${passed}/${total} ki\u1EC3m tra pass. Xem g\u1EE3i \xFD \u1EDF tr\xEAn \u0111\u1EC3 s\u1EEDa.
4326
+ chalk10.yellow(` \u26A0\uFE0F ${passed}/${total} ki\u1EC3m tra pass. Xem g\u1EE3i \xFD \u1EDF tr\xEAn \u0111\u1EC3 s\u1EEDa.
4276
4327
  `)
4277
4328
  );
4278
4329
  }
@@ -4428,7 +4479,7 @@ async function checkIde(cliName) {
4428
4479
  }
4429
4480
 
4430
4481
  // src/commands/chat.ts
4431
- import { Command as Command14 } from "commander";
4482
+ import { Command as Command15 } from "commander";
4432
4483
  import React12 from "react";
4433
4484
  import { render as render3 } from "ink";
4434
4485
 
@@ -6070,15 +6121,15 @@ async function handleChatCommand(options) {
6070
6121
  }
6071
6122
  }
6072
6123
  function createChatCommand() {
6073
- const cmd = new Command14("chat").description("AI chat with Jai1 LLM Proxy (default: web browser)").option("--model <model>", "Initial model to use (e.g., gpt-4o, claude-3-opus)").option("-t, --terminal", "Use terminal TUI mode instead of web browser").option("--port <port>", "Port for web server (default: auto-find available port)").option("--no-open", "Don't auto-open browser (web mode only)").action(async (options) => {
6124
+ const cmd = new Command15("chat").description("AI chat with Jai1 LLM Proxy (default: web browser)").option("--model <model>", "Initial model to use (e.g., gpt-4o, claude-3-opus)").option("-t, --terminal", "Use terminal TUI mode instead of web browser").option("--port <port>", "Port for web server (default: auto-find available port)").option("--no-open", "Don't auto-open browser (web mode only)").action(async (options) => {
6074
6125
  await handleChatCommand(options);
6075
6126
  });
6076
6127
  return cmd;
6077
6128
  }
6078
6129
 
6079
6130
  // src/commands/openai-keys.ts
6080
- import { Command as Command15 } from "commander";
6081
- import chalk10 from "chalk";
6131
+ import { Command as Command16 } from "commander";
6132
+ import chalk11 from "chalk";
6082
6133
  import boxen3 from "boxen";
6083
6134
  function maskKey2(key) {
6084
6135
  if (key.length <= 8) return "****";
@@ -6092,17 +6143,17 @@ async function handleOpenAiKeysCommand(options) {
6092
6143
  }
6093
6144
  const service = new LlmProxyService(config);
6094
6145
  console.log(
6095
- boxen3(chalk10.cyan.bold("\u{1F4E1} Jai1 LLM Proxy - OpenAI Compatible API"), {
6146
+ boxen3(chalk11.cyan.bold("\u{1F4E1} Jai1 LLM Proxy - OpenAI Compatible API"), {
6096
6147
  padding: { top: 0, bottom: 0, left: 1, right: 1 },
6097
6148
  borderStyle: "round",
6098
6149
  borderColor: "cyan"
6099
6150
  })
6100
6151
  );
6101
6152
  console.log();
6102
- console.log(chalk10.bold("\u{1F511} API Credentials"));
6103
- console.log(` ${chalk10.dim("BASE_URL:")} ${chalk10.white(service.getBaseUrl())}`);
6153
+ console.log(chalk11.bold("\u{1F511} API Credentials"));
6154
+ console.log(` ${chalk11.dim("BASE_URL:")} ${chalk11.white(service.getBaseUrl())}`);
6104
6155
  console.log(
6105
- ` ${chalk10.dim("API_KEY:")} ${options.full ? chalk10.green(service.getApiKey()) : chalk10.yellow(maskKey2(service.getApiKey()))}`
6156
+ ` ${chalk11.dim("API_KEY:")} ${options.full ? chalk11.green(service.getApiKey()) : chalk11.yellow(maskKey2(service.getApiKey()))}`
6106
6157
  );
6107
6158
  console.log();
6108
6159
  try {
@@ -6111,52 +6162,52 @@ async function handleOpenAiKeysCommand(options) {
6111
6162
  service.getLimits()
6112
6163
  ]);
6113
6164
  const allowedModels = models.filter((m) => m.allowed);
6114
- console.log(chalk10.bold("\u{1F4E6} Available Models"));
6165
+ console.log(chalk11.bold("\u{1F4E6} Available Models"));
6115
6166
  if (allowedModels.length === 0) {
6116
- console.log(chalk10.dim(" Kh\xF4ng c\xF3 models kh\u1EA3 d\u1EE5ng"));
6167
+ console.log(chalk11.dim(" Kh\xF4ng c\xF3 models kh\u1EA3 d\u1EE5ng"));
6117
6168
  } else {
6118
6169
  for (const model of allowedModels) {
6119
- const usageText = model.dailyLimit !== void 0 && model.usedToday !== void 0 ? chalk10.dim(` (${model.usedToday}/${model.dailyLimit} h\xF4m nay)`) : "";
6120
- console.log(` ${chalk10.green("\u2713")} ${chalk10.white(model.id)}${usageText}`);
6170
+ const usageText = model.dailyLimit !== void 0 && model.usedToday !== void 0 ? chalk11.dim(` (${model.usedToday}/${model.dailyLimit} h\xF4m nay)`) : "";
6171
+ console.log(` ${chalk11.green("\u2713")} ${chalk11.white(model.id)}${usageText}`);
6121
6172
  }
6122
6173
  }
6123
6174
  console.log();
6124
6175
  const defaultModel = allowedModels[0]?.id || "gpt-4o";
6125
- console.log(chalk10.bold("\u{1F4DD} Sample cURL"));
6176
+ console.log(chalk11.bold("\u{1F4DD} Sample cURL"));
6126
6177
  console.log();
6127
6178
  const curlSample = options.full ? service.generateFullCurlSample(defaultModel) : service.generateCurlSample(defaultModel);
6128
6179
  const curlLines = curlSample.split("\n");
6129
6180
  for (const line of curlLines) {
6130
- console.log(chalk10.dim(` ${line}`));
6181
+ console.log(chalk11.dim(` ${line}`));
6131
6182
  }
6132
6183
  console.log();
6133
- console.log(chalk10.bold("\u{1F4A1} C\xE1ch s\u1EED d\u1EE5ng"));
6134
- console.log(chalk10.dim(" - Thay th\u1EBF OpenAI API URL v\xE0 API Key"));
6135
- console.log(chalk10.dim(" - T\u01B0\u01A1ng th\xEDch: OpenAI SDK, LangChain, LlamaIndex, v.v."));
6136
- console.log(chalk10.dim(' - Ch\u1EA1y "jai1 chat" \u0111\u1EC3 chat tr\u1EF1c ti\u1EBFp'));
6184
+ console.log(chalk11.bold("\u{1F4A1} C\xE1ch s\u1EED d\u1EE5ng"));
6185
+ console.log(chalk11.dim(" - Thay th\u1EBF OpenAI API URL v\xE0 API Key"));
6186
+ console.log(chalk11.dim(" - T\u01B0\u01A1ng th\xEDch: OpenAI SDK, LangChain, LlamaIndex, v.v."));
6187
+ console.log(chalk11.dim(' - Ch\u1EA1y "jai1 chat" \u0111\u1EC3 chat tr\u1EF1c ti\u1EBFp'));
6137
6188
  if (!options.full) {
6138
- console.log(chalk10.dim(' - Ch\u1EA1y "jai1 openai-keys --full" \u0111\u1EC3 hi\u1EC3n th\u1ECB API key \u0111\u1EA7y \u0111\u1EE7'));
6189
+ console.log(chalk11.dim(' - Ch\u1EA1y "jai1 openai-keys --full" \u0111\u1EC3 hi\u1EC3n th\u1ECB API key \u0111\u1EA7y \u0111\u1EE7'));
6139
6190
  }
6140
6191
  } catch (error) {
6141
6192
  console.log();
6142
6193
  console.log(
6143
- chalk10.red("\u274C L\u1ED7i khi l\u1EA5y th\xF4ng tin API:"),
6144
- chalk10.dim(error instanceof Error ? error.message : String(error))
6194
+ chalk11.red("\u274C L\u1ED7i khi l\u1EA5y th\xF4ng tin API:"),
6195
+ chalk11.dim(error instanceof Error ? error.message : String(error))
6145
6196
  );
6146
- console.log(chalk10.dim('\n\u{1F4A1} Ki\u1EC3m tra API URL v\xE0 access key v\u1EDBi "jai1 status"'));
6197
+ console.log(chalk11.dim('\n\u{1F4A1} Ki\u1EC3m tra API URL v\xE0 access key v\u1EDBi "jai1 status"'));
6147
6198
  }
6148
6199
  }
6149
6200
  function createOpenAiKeysCommand() {
6150
- const cmd = new Command15("openai-keys").description("Show OpenAI-compatible API credentials and info").option("--full", "Show full API key (unmasked)").action(async (options) => {
6201
+ const cmd = new Command16("openai-keys").description("Show OpenAI-compatible API credentials and info").option("--full", "Show full API key (unmasked)").action(async (options) => {
6151
6202
  await handleOpenAiKeysCommand(options);
6152
6203
  });
6153
6204
  return cmd;
6154
6205
  }
6155
6206
 
6156
6207
  // src/commands/stats.ts
6157
- import { Command as Command16 } from "commander";
6208
+ import { Command as Command17 } from "commander";
6158
6209
  import Table2 from "cli-table3";
6159
- import chalk11 from "chalk";
6210
+ import chalk12 from "chalk";
6160
6211
  async function handleStatsCommand() {
6161
6212
  const configService = new ConfigService();
6162
6213
  const config = await configService.load();
@@ -6166,8 +6217,8 @@ async function handleStatsCommand() {
6166
6217
  );
6167
6218
  }
6168
6219
  const service = new LlmProxyService(config);
6169
- console.log(chalk11.bold("\n\u{1F4CA} Th\u1ED1ng K\xEA S\u1EED D\u1EE5ng LLM"));
6170
- console.log(chalk11.dim("\u2500".repeat(45)));
6220
+ console.log(chalk12.bold("\n\u{1F4CA} Th\u1ED1ng K\xEA S\u1EED D\u1EE5ng LLM"));
6221
+ console.log(chalk12.dim("\u2500".repeat(45)));
6171
6222
  try {
6172
6223
  const [limits, usage7Days, usageToday] = await Promise.all([
6173
6224
  service.getLimits(),
@@ -6177,7 +6228,7 @@ async function handleStatsCommand() {
6177
6228
  const today = (/* @__PURE__ */ new Date()).toLocaleDateString("en-CA", {
6178
6229
  timeZone: "Asia/Ho_Chi_Minh"
6179
6230
  });
6180
- console.log(chalk11.cyan("\n\u{1F4C5} Kho\u1EA3ng th\u1EDDi gian: 7 ng\xE0y qua\n"));
6231
+ console.log(chalk12.cyan("\n\u{1F4C5} Kho\u1EA3ng th\u1EDDi gian: 7 ng\xE0y qua\n"));
6181
6232
  const usageByModel = /* @__PURE__ */ new Map();
6182
6233
  let total7DaysRequests = 0;
6183
6234
  usage7Days.data?.forEach((record) => {
@@ -6197,16 +6248,16 @@ async function handleStatsCommand() {
6197
6248
  modelData.today = record.count;
6198
6249
  }
6199
6250
  });
6200
- console.log(chalk11.bold("\u{1F4C8} T\u1ED5ng quan s\u1EED d\u1EE5ng"));
6201
- console.log(` T\u1ED5ng s\u1ED1 y\xEAu c\u1EA7u (7 ng\xE0y): ${chalk11.green(total7DaysRequests)}
6251
+ console.log(chalk12.bold("\u{1F4C8} T\u1ED5ng quan s\u1EED d\u1EE5ng"));
6252
+ console.log(` T\u1ED5ng s\u1ED1 y\xEAu c\u1EA7u (7 ng\xE0y): ${chalk12.green(total7DaysRequests)}
6202
6253
  `);
6203
- console.log(chalk11.bold("\u{1F4E6} Th\u1ED1ng k\xEA theo model\n"));
6254
+ console.log(chalk12.bold("\u{1F4E6} Th\u1ED1ng k\xEA theo model\n"));
6204
6255
  const table = new Table2({
6205
6256
  head: [
6206
- chalk11.bold("Model"),
6207
- chalk11.bold("H\xF4m nay"),
6208
- chalk11.bold("Gi\u1EDBi h\u1EA1n"),
6209
- chalk11.bold("T\u1ED5ng 7 ng\xE0y")
6257
+ chalk12.bold("Model"),
6258
+ chalk12.bold("H\xF4m nay"),
6259
+ chalk12.bold("Gi\u1EDBi h\u1EA1n"),
6260
+ chalk12.bold("T\u1ED5ng 7 ng\xE0y")
6210
6261
  ],
6211
6262
  style: {
6212
6263
  head: ["cyan"],
@@ -6218,7 +6269,7 @@ async function handleStatsCommand() {
6218
6269
  const rateLimits = limits.effectiveRateLimits || {};
6219
6270
  if (allowedModels.length === 0) {
6220
6271
  table.push([
6221
- { colSpan: 4, content: chalk11.yellow("Kh\xF4ng c\xF3 model n\xE0o kh\u1EA3 d\u1EE5ng") }
6272
+ { colSpan: 4, content: chalk12.yellow("Kh\xF4ng c\xF3 model n\xE0o kh\u1EA3 d\u1EE5ng") }
6222
6273
  ]);
6223
6274
  } else {
6224
6275
  allowedModels.forEach((modelId) => {
@@ -6227,36 +6278,36 @@ async function handleStatsCommand() {
6227
6278
  const usagePercent = limit > 0 ? usage.today / limit : 0;
6228
6279
  let todayDisplay = `${usage.today}/${limit}`;
6229
6280
  if (usagePercent >= 0.9) {
6230
- todayDisplay = chalk11.red(todayDisplay);
6281
+ todayDisplay = chalk12.red(todayDisplay);
6231
6282
  } else if (usagePercent >= 0.7) {
6232
- todayDisplay = chalk11.yellow(todayDisplay);
6283
+ todayDisplay = chalk12.yellow(todayDisplay);
6233
6284
  } else {
6234
- todayDisplay = chalk11.green(todayDisplay);
6285
+ todayDisplay = chalk12.green(todayDisplay);
6235
6286
  }
6236
6287
  table.push([modelId, todayDisplay, `${limit}/ng\xE0y`, String(usage.total7Days)]);
6237
6288
  });
6238
6289
  }
6239
6290
  console.log(table.toString());
6240
6291
  console.log(
6241
- chalk11.dim('\n\u{1F4A1} M\u1EB9o: Ch\u1EA1y "jai1 openai-keys" \u0111\u1EC3 xem danh s\xE1ch model kh\u1EA3 d\u1EE5ng')
6292
+ chalk12.dim('\n\u{1F4A1} M\u1EB9o: Ch\u1EA1y "jai1 openai-keys" \u0111\u1EC3 xem danh s\xE1ch model kh\u1EA3 d\u1EE5ng')
6242
6293
  );
6243
6294
  } catch (error) {
6244
6295
  console.error(
6245
- chalk11.red("\n\u274C Kh\xF4ng th\u1EC3 l\u1EA5y th\u1ED1ng k\xEA:"),
6296
+ chalk12.red("\n\u274C Kh\xF4ng th\u1EC3 l\u1EA5y th\u1ED1ng k\xEA:"),
6246
6297
  error instanceof Error ? error.message : String(error)
6247
6298
  );
6248
- console.log(chalk11.dim('\n\u{1F4A1} Ki\u1EC3m tra k\u1EBFt n\u1ED1i API v\u1EDBi "jai1 status"'));
6299
+ console.log(chalk12.dim('\n\u{1F4A1} Ki\u1EC3m tra k\u1EBFt n\u1ED1i API v\u1EDBi "jai1 status"'));
6249
6300
  }
6250
6301
  }
6251
6302
  function createStatsCommand() {
6252
- const cmd = new Command16("stats").description("Hi\u1EC3n th\u1ECB th\u1ED1ng k\xEA s\u1EED d\u1EE5ng LLM v\xE0 gi\u1EDBi h\u1EA1n").action(async () => {
6303
+ const cmd = new Command17("stats").description("Hi\u1EC3n th\u1ECB th\u1ED1ng k\xEA s\u1EED d\u1EE5ng LLM v\xE0 gi\u1EDBi h\u1EA1n").action(async () => {
6253
6304
  await handleStatsCommand();
6254
6305
  });
6255
6306
  return cmd;
6256
6307
  }
6257
6308
 
6258
6309
  // src/commands/translate.ts
6259
- import { Command as Command17 } from "commander";
6310
+ import { Command as Command18 } from "commander";
6260
6311
 
6261
6312
  // src/services/translation.service.ts
6262
6313
  import { promises as fs12 } from "fs";
@@ -6604,18 +6655,18 @@ async function handleFolderTranslation(service, folderPath, options) {
6604
6655
  }
6605
6656
  }
6606
6657
  function createTranslateCommand() {
6607
- const cmd = new Command17("translate").description("D\u1ECBch v\u0103n b\u1EA3n, file ho\u1EB7c th\u01B0 m\u1EE5c b\u1EB1ng AI").argument("<input>", "Chu\u1ED7i v\u0103n b\u1EA3n, \u0111\u01B0\u1EDDng d\u1EABn file ho\u1EB7c th\u01B0 m\u1EE5c").option("--to <language>", "M\xE3 ng\xF4n ng\u1EEF \u0111\xEDch (m\u1EB7c \u0111\u1ECBnh: vi)", "vi").option("-o, --output <path>", "\u0110\u01B0\u1EDDng d\u1EABn output (file/th\u01B0 m\u1EE5c)").option("--dry-run", "Xem tr\u01B0\u1EDBc kh\xF4ng l\u01B0u file").option("--concurrency <number>", "S\u1ED1 file x\u1EED l\xFD song song (m\u1EB7c \u0111\u1ECBnh: 3)", "3").option("--model <model>", "Model LLM (m\u1EB7c \u0111\u1ECBnh: gpt-5.1-codex-mini)").option("--json", "Xu\u1EA5t k\u1EBFt qu\u1EA3 d\u1EA1ng JSON").action(async (input5, options) => {
6658
+ const cmd = new Command18("translate").description("D\u1ECBch v\u0103n b\u1EA3n, file ho\u1EB7c th\u01B0 m\u1EE5c b\u1EB1ng AI").argument("<input>", "Chu\u1ED7i v\u0103n b\u1EA3n, \u0111\u01B0\u1EDDng d\u1EABn file ho\u1EB7c th\u01B0 m\u1EE5c").option("--to <language>", "M\xE3 ng\xF4n ng\u1EEF \u0111\xEDch (m\u1EB7c \u0111\u1ECBnh: vi)", "vi").option("-o, --output <path>", "\u0110\u01B0\u1EDDng d\u1EABn output (file/th\u01B0 m\u1EE5c)").option("--dry-run", "Xem tr\u01B0\u1EDBc kh\xF4ng l\u01B0u file").option("--concurrency <number>", "S\u1ED1 file x\u1EED l\xFD song song (m\u1EB7c \u0111\u1ECBnh: 3)", "3").option("--model <model>", "Model LLM (m\u1EB7c \u0111\u1ECBnh: gpt-5.1-codex-mini)").option("--json", "Xu\u1EA5t k\u1EBFt qu\u1EA3 d\u1EA1ng JSON").action(async (input5, options) => {
6608
6659
  await handleTranslate(input5, options);
6609
6660
  });
6610
6661
  return cmd;
6611
6662
  }
6612
6663
 
6613
6664
  // src/commands/image/index.ts
6614
- import { Command as Command22 } from "commander";
6615
- import chalk12 from "chalk";
6665
+ import { Command as Command23 } from "commander";
6666
+ import chalk13 from "chalk";
6616
6667
 
6617
6668
  // src/commands/image/gen.ts
6618
- import { Command as Command18 } from "commander";
6669
+ import { Command as Command19 } from "commander";
6619
6670
 
6620
6671
  // src/services/image.service.ts
6621
6672
  var ImageService = class {
@@ -6720,7 +6771,7 @@ var SUPPORTED_SIZES = [
6720
6771
  // 3:4 (portrait)
6721
6772
  ];
6722
6773
  function createImageGenCommand() {
6723
- return new Command18("gen").description("Generate an image from text prompt").argument("<prompt>", "Image description prompt").option("-m, --model <model>", "Model to use", "gemini-3-pro-image-preview").option("-s, --size <size>", `Image size: ${SUPPORTED_SIZES.join(", ")}`, "1024x1024").option("-q, --quality <quality>", "Image quality: standard, hd", "hd").option("--no-display", "Don't display image in terminal").action(async (prompt, options) => {
6774
+ return new Command19("gen").description("Generate an image from text prompt").argument("<prompt>", "Image description prompt").option("-m, --model <model>", "Model to use", "gemini-3-pro-image-preview").option("-s, --size <size>", `Image size: ${SUPPORTED_SIZES.join(", ")}`, "1024x1024").option("-q, --quality <quality>", "Image quality: standard, hd", "hd").option("--no-display", "Don't display image in terminal").action(async (prompt, options) => {
6724
6775
  const configService = new ConfigService();
6725
6776
  const config = await configService.load();
6726
6777
  if (!config) {
@@ -6786,9 +6837,9 @@ function createImageGenCommand() {
6786
6837
  }
6787
6838
 
6788
6839
  // src/commands/image/list.ts
6789
- import { Command as Command19 } from "commander";
6840
+ import { Command as Command20 } from "commander";
6790
6841
  function createImageListCommand() {
6791
- return new Command19("list").description("List generated images").option("-m, --model <model>", "Filter by model").option("-l, --limit <number>", "Number of results", "20").option("-o, --offset <number>", "Offset for pagination", "0").action(async (options) => {
6842
+ return new Command20("list").description("List generated images").option("-m, --model <model>", "Filter by model").option("-l, --limit <number>", "Number of results", "20").option("-o, --offset <number>", "Offset for pagination", "0").action(async (options) => {
6792
6843
  const configService = new ConfigService();
6793
6844
  const config = await configService.load();
6794
6845
  if (!config) {
@@ -6824,9 +6875,9 @@ function createImageListCommand() {
6824
6875
  }
6825
6876
 
6826
6877
  // src/commands/image/info.ts
6827
- import { Command as Command20 } from "commander";
6878
+ import { Command as Command21 } from "commander";
6828
6879
  function createImageInfoCommand() {
6829
- return new Command20("info").description("Get detailed info about an image").argument("<id>", "Image ID").action(async (id) => {
6880
+ return new Command21("info").description("Get detailed info about an image").argument("<id>", "Image ID").action(async (id) => {
6830
6881
  const configService = new ConfigService();
6831
6882
  const config = await configService.load();
6832
6883
  if (!config) {
@@ -6860,10 +6911,10 @@ function createImageInfoCommand() {
6860
6911
  }
6861
6912
 
6862
6913
  // src/commands/image/delete.ts
6863
- import { Command as Command21 } from "commander";
6914
+ import { Command as Command22 } from "commander";
6864
6915
  import { confirm as confirm4 } from "@inquirer/prompts";
6865
6916
  function createImageDeleteCommand() {
6866
- return new Command21("delete").description("Delete a generated image").argument("<id>", "Image ID").option("-y, --yes", "Skip confirmation").action(async (id, options) => {
6917
+ return new Command22("delete").description("Delete a generated image").argument("<id>", "Image ID").option("-y, --yes", "Skip confirmation").action(async (id, options) => {
6867
6918
  const configService = new ConfigService();
6868
6919
  const config = await configService.load();
6869
6920
  if (!config) {
@@ -6887,25 +6938,25 @@ function createImageDeleteCommand() {
6887
6938
 
6888
6939
  // src/commands/image/index.ts
6889
6940
  function showImageHelp() {
6890
- console.log(chalk12.bold.cyan("\u{1F3A8} jai1 image") + chalk12.dim(" - Image generation commands"));
6941
+ console.log(chalk13.bold.cyan("\u{1F3A8} jai1 image") + chalk13.dim(" - Image generation commands"));
6891
6942
  console.log();
6892
- console.log(chalk12.yellow("\u26A0\uFE0F Coming Soon - T\xEDnh n\u0103ng \u0111ang ph\xE1t tri\u1EC3n"));
6943
+ console.log(chalk13.yellow("\u26A0\uFE0F Coming Soon - T\xEDnh n\u0103ng \u0111ang ph\xE1t tri\u1EC3n"));
6893
6944
  console.log();
6894
- console.log(chalk12.bold("C\xE1c l\u1EC7nh:"));
6895
- console.log(` ${chalk12.cyan("gen")} T\u1EA1o \u1EA3nh t\u1EEB prompt`);
6896
- console.log(` ${chalk12.cyan("list")} Li\u1EC7t k\xEA c\xE1c \u1EA3nh \u0111\xE3 t\u1EA1o`);
6897
- console.log(` ${chalk12.cyan("info")} Xem th\xF4ng tin \u1EA3nh`);
6898
- console.log(` ${chalk12.cyan("delete")} X\xF3a \u1EA3nh`);
6945
+ console.log(chalk13.bold("C\xE1c l\u1EC7nh:"));
6946
+ console.log(` ${chalk13.cyan("gen")} T\u1EA1o \u1EA3nh t\u1EEB prompt`);
6947
+ console.log(` ${chalk13.cyan("list")} Li\u1EC7t k\xEA c\xE1c \u1EA3nh \u0111\xE3 t\u1EA1o`);
6948
+ console.log(` ${chalk13.cyan("info")} Xem th\xF4ng tin \u1EA3nh`);
6949
+ console.log(` ${chalk13.cyan("delete")} X\xF3a \u1EA3nh`);
6899
6950
  console.log();
6900
- console.log(chalk12.bold("V\xED d\u1EE5:"));
6901
- console.log(chalk12.dim(' $ jai1 image gen "a cute cat"'));
6902
- console.log(chalk12.dim(" $ jai1 image list"));
6903
- console.log(chalk12.dim(" $ jai1 image info <image-id>"));
6951
+ console.log(chalk13.bold("V\xED d\u1EE5:"));
6952
+ console.log(chalk13.dim(' $ jai1 image gen "a cute cat"'));
6953
+ console.log(chalk13.dim(" $ jai1 image list"));
6954
+ console.log(chalk13.dim(" $ jai1 image info <image-id>"));
6904
6955
  console.log();
6905
- console.log(chalk12.dim('Ch\u1EA1y "jai1 image <l\u1EC7nh> --help" \u0111\u1EC3 xem chi ti\u1EBFt'));
6956
+ console.log(chalk13.dim('Ch\u1EA1y "jai1 image <l\u1EC7nh> --help" \u0111\u1EC3 xem chi ti\u1EBFt'));
6906
6957
  }
6907
6958
  function createImageCommand() {
6908
- const cmd = new Command22("image").description("Image generation commands (Coming Soon)").action(() => {
6959
+ const cmd = new Command23("image").description("Image generation commands (Coming Soon)").action(() => {
6909
6960
  showImageHelp();
6910
6961
  });
6911
6962
  cmd.addCommand(createImageGenCommand());
@@ -6916,7 +6967,7 @@ function createImageCommand() {
6916
6967
  }
6917
6968
 
6918
6969
  // src/commands/feedback.ts
6919
- import { Command as Command23 } from "commander";
6970
+ import { Command as Command24 } from "commander";
6920
6971
  import { select as select2, input, confirm as confirm5 } from "@inquirer/prompts";
6921
6972
  import os from "os";
6922
6973
  import { promises as fs13 } from "fs";
@@ -7125,21 +7176,21 @@ async function handleFeedbackCommand(options) {
7125
7176
  }
7126
7177
  }
7127
7178
  function createFeedbackCommand() {
7128
- const cmd = new Command23("feedback").alias("report").description("Submit bug reports, feature requests, or suggestions").option("--type <type>", "Feedback type: bug, feature, suggestion").option("--title <title>", "Feedback title (max 200 chars)").option("--message <message>", "Feedback message (max 4000 chars)").option("--context <json>", "Additional context as JSON").option("--no-context", "Do not include automatic context").option("--json", "Output JSON format").action(async (options) => {
7179
+ const cmd = new Command24("feedback").alias("report").description("Submit bug reports, feature requests, or suggestions").option("--type <type>", "Feedback type: bug, feature, suggestion").option("--title <title>", "Feedback title (max 200 chars)").option("--message <message>", "Feedback message (max 4000 chars)").option("--context <json>", "Additional context as JSON").option("--no-context", "Do not include automatic context").option("--json", "Output JSON format").action(async (options) => {
7129
7180
  await handleFeedbackCommand(options);
7130
7181
  });
7131
7182
  return cmd;
7132
7183
  }
7133
7184
 
7134
7185
  // src/commands/client-info.ts
7135
- import { Command as Command24 } from "commander";
7186
+ import { Command as Command25 } from "commander";
7136
7187
  import { confirm as confirm6 } from "@inquirer/prompts";
7137
7188
  import os2 from "os";
7138
7189
  import { promises as fs14 } from "fs";
7139
7190
  import { basename as basename2, join as join8 } from "path";
7140
7191
  import { version as nodeVersion2 } from "process";
7141
7192
  function createClientInfoCommand() {
7142
- const cmd = new Command24("client-info").description("T\u1EA1o th\xF4ng tin client \u0111\u1EC3 g\u1EEDi \u0111\u1ED9i ph\xE1t tri\u1EC3n jai1").option("--json", "Output as JSON").option("--full", "Include component list (top 20)").option("--submit", "Submit client info to Jai1 feedback endpoint").option("--message <text>", "Additional message when submitting").option("--show-paths", "Include full project path").action(async (options) => {
7193
+ const cmd = new Command25("client-info").description("T\u1EA1o th\xF4ng tin client \u0111\u1EC3 g\u1EEDi \u0111\u1ED9i ph\xE1t tri\u1EC3n jai1").option("--json", "Output as JSON").option("--full", "Include component list (top 20)").option("--submit", "Submit client info to Jai1 feedback endpoint").option("--message <text>", "Additional message when submitting").option("--show-paths", "Include full project path").action(async (options) => {
7143
7194
  await handleClientInfo(options);
7144
7195
  });
7145
7196
  return cmd;
@@ -7402,15 +7453,15 @@ async function confirmSubmit(summary, jsonMode) {
7402
7453
  }
7403
7454
 
7404
7455
  // src/commands/errors/index.ts
7405
- import { Command as Command28 } from "commander";
7406
- import chalk14 from "chalk";
7456
+ import { Command as Command29 } from "commander";
7457
+ import chalk15 from "chalk";
7407
7458
 
7408
7459
  // src/commands/errors/list.ts
7409
- import { Command as Command25 } from "commander";
7410
- import chalk13 from "chalk";
7460
+ import { Command as Command26 } from "commander";
7461
+ import chalk14 from "chalk";
7411
7462
  import Table3 from "cli-table3";
7412
7463
  function createErrorsListSubcommand() {
7413
- return new Command25("list").description("Danh s\xE1ch error logs").option("--json", "Output JSON format").action(async (options) => {
7464
+ return new Command26("list").description("Danh s\xE1ch error logs").option("--json", "Output JSON format").action(async (options) => {
7414
7465
  const service = new ErrorLogService();
7415
7466
  const paths = await service.list();
7416
7467
  if (paths.length === 0) {
@@ -7444,7 +7495,7 @@ function createErrorsListSubcommand() {
7444
7495
  });
7445
7496
  for (const log of logs) {
7446
7497
  table.push([
7447
- chalk13.cyan(log.id),
7498
+ chalk14.cyan(log.id),
7448
7499
  log.timestamp || "-",
7449
7500
  log.command || "-",
7450
7501
  log.message || "-"
@@ -7455,9 +7506,9 @@ function createErrorsListSubcommand() {
7455
7506
  }
7456
7507
 
7457
7508
  // src/commands/errors/show.ts
7458
- import { Command as Command26 } from "commander";
7509
+ import { Command as Command27 } from "commander";
7459
7510
  function createErrorsShowSubcommand() {
7460
- return new Command26("show").description("Xem chi ti\u1EBFt error log").argument("[id]", "Error log id (default: latest)").option("--json", "Output JSON format").action(async (id, options) => {
7511
+ return new Command27("show").description("Xem chi ti\u1EBFt error log").argument("[id]", "Error log id (default: latest)").option("--json", "Output JSON format").action(async (id, options) => {
7461
7512
  const service = new ErrorLogService();
7462
7513
  const paths = await service.list();
7463
7514
  if (paths.length === 0) {
@@ -7484,10 +7535,10 @@ function createErrorsShowSubcommand() {
7484
7535
  }
7485
7536
 
7486
7537
  // src/commands/errors/clear.ts
7487
- import { Command as Command27 } from "commander";
7538
+ import { Command as Command28 } from "commander";
7488
7539
  import { confirm as confirm7 } from "@inquirer/prompts";
7489
7540
  function createErrorsClearSubcommand() {
7490
- return new Command27("clear").description("Xo\xE1 error logs").option("--all", "Delete all error logs").option("--id <id>", "Delete one error log by id").option("-y, --yes", "Skip confirmation").action(async (options) => {
7541
+ return new Command28("clear").description("Xo\xE1 error logs").option("--all", "Delete all error logs").option("--id <id>", "Delete one error log by id").option("-y, --yes", "Skip confirmation").action(async (options) => {
7491
7542
  const service = new ErrorLogService();
7492
7543
  const paths = await service.list();
7493
7544
  if (paths.length === 0) {
@@ -7523,22 +7574,22 @@ function createErrorsClearSubcommand() {
7523
7574
 
7524
7575
  // src/commands/errors/index.ts
7525
7576
  function showErrorsHelp() {
7526
- console.log(chalk14.bold.cyan("\u{1F9FE} jai1 errors") + chalk14.dim(" - Qu\u1EA3n l\xFD error logs c\u1EE5c b\u1ED9"));
7577
+ console.log(chalk15.bold.cyan("\u{1F9FE} jai1 errors") + chalk15.dim(" - Qu\u1EA3n l\xFD error logs c\u1EE5c b\u1ED9"));
7527
7578
  console.log();
7528
- console.log(chalk14.bold("C\xE1c l\u1EC7nh:"));
7529
- console.log(` ${chalk14.cyan("list")} Danh s\xE1ch error logs`);
7530
- console.log(` ${chalk14.cyan("show")} Xem chi ti\u1EBFt error log`);
7531
- console.log(` ${chalk14.cyan("clear")} Xo\xE1 error logs`);
7579
+ console.log(chalk15.bold("C\xE1c l\u1EC7nh:"));
7580
+ console.log(` ${chalk15.cyan("list")} Danh s\xE1ch error logs`);
7581
+ console.log(` ${chalk15.cyan("show")} Xem chi ti\u1EBFt error log`);
7582
+ console.log(` ${chalk15.cyan("clear")} Xo\xE1 error logs`);
7532
7583
  console.log();
7533
- console.log(chalk14.bold("V\xED d\u1EE5:"));
7534
- console.log(chalk14.dim(" $ jai1 errors list"));
7535
- console.log(chalk14.dim(" $ jai1 errors show <id>"));
7536
- console.log(chalk14.dim(" $ jai1 errors clear --all"));
7584
+ console.log(chalk15.bold("V\xED d\u1EE5:"));
7585
+ console.log(chalk15.dim(" $ jai1 errors list"));
7586
+ console.log(chalk15.dim(" $ jai1 errors show <id>"));
7587
+ console.log(chalk15.dim(" $ jai1 errors clear --all"));
7537
7588
  console.log();
7538
- console.log(chalk14.dim('Ch\u1EA1y "jai1 errors <l\u1EC7nh> --help" \u0111\u1EC3 xem chi ti\u1EBFt'));
7589
+ console.log(chalk15.dim('Ch\u1EA1y "jai1 errors <l\u1EC7nh> --help" \u0111\u1EC3 xem chi ti\u1EBFt'));
7539
7590
  }
7540
7591
  function createErrorsCommand() {
7541
- const errorsCommand = new Command28("errors").description("Manage local error logs").action(() => {
7592
+ const errorsCommand = new Command29("errors").description("Manage local error logs").action(() => {
7542
7593
  showErrorsHelp();
7543
7594
  });
7544
7595
  errorsCommand.addCommand(createErrorsListSubcommand());
@@ -7548,11 +7599,11 @@ function createErrorsCommand() {
7548
7599
  }
7549
7600
 
7550
7601
  // src/commands/utils/index.ts
7551
- import { Command as Command42 } from "commander";
7552
- import chalk15 from "chalk";
7602
+ import { Command as Command43 } from "commander";
7603
+ import chalk16 from "chalk";
7553
7604
 
7554
7605
  // src/commands/utils/password.ts
7555
- import { Command as Command29 } from "commander";
7606
+ import { Command as Command30 } from "commander";
7556
7607
 
7557
7608
  // src/services/utils.service.ts
7558
7609
  import crypto2 from "crypto";
@@ -7821,7 +7872,7 @@ async function handlePasswordGeneration(options) {
7821
7872
  }
7822
7873
  }
7823
7874
  function createPasswordCommand() {
7824
- const cmd = new Command29("password").description("Generate secure random password").option("-l, --length <number>", "Password length", "16").option("--no-lowercase", "Exclude lowercase letters").option("--no-uppercase", "Exclude uppercase letters").option("--no-digits", "Exclude digits").option("--no-symbols", "Exclude symbols").option("--symbol-chars <chars>", "Custom symbol characters").option("-c, --count <number>", "Number of passwords to generate", "1").addHelpText("after", `
7875
+ const cmd = new Command30("password").description("Generate secure random password").option("-l, --length <number>", "Password length", "16").option("--no-lowercase", "Exclude lowercase letters").option("--no-uppercase", "Exclude uppercase letters").option("--no-digits", "Exclude digits").option("--no-symbols", "Exclude symbols").option("--symbol-chars <chars>", "Custom symbol characters").option("-c, --count <number>", "Number of passwords to generate", "1").addHelpText("after", `
7825
7876
  Examples:
7826
7877
  $ jai1 utils password
7827
7878
  $ jai1 utils password --length 24
@@ -7839,7 +7890,7 @@ Examples:
7839
7890
  }
7840
7891
 
7841
7892
  // src/commands/utils/uuid.ts
7842
- import { Command as Command30 } from "commander";
7893
+ import { Command as Command31 } from "commander";
7843
7894
  async function handleUuidGeneration(options) {
7844
7895
  const service = new UtilsService();
7845
7896
  try {
@@ -7867,7 +7918,7 @@ async function handleUuidGeneration(options) {
7867
7918
  }
7868
7919
  }
7869
7920
  function createUuidCommand() {
7870
- const cmd = new Command30("uuid").description("Generate UUID v4 identifier").option("-c, --count <number>", "Number of UUIDs to generate", "1").option("--uppercase", "Output in uppercase").option("--no-hyphens", "Remove hyphens from output").addHelpText("after", `
7921
+ const cmd = new Command31("uuid").description("Generate UUID v4 identifier").option("-c, --count <number>", "Number of UUIDs to generate", "1").option("--uppercase", "Output in uppercase").option("--no-hyphens", "Remove hyphens from output").addHelpText("after", `
7871
7922
  Examples:
7872
7923
  $ jai1 utils uuid
7873
7924
  $ jai1 utils uuid --count 10
@@ -7884,7 +7935,7 @@ Examples:
7884
7935
  }
7885
7936
 
7886
7937
  // src/commands/utils/hash.ts
7887
- import { Command as Command31 } from "commander";
7938
+ import { Command as Command32 } from "commander";
7888
7939
  async function handleHashGeneration(input5, options) {
7889
7940
  const service = new UtilsService();
7890
7941
  try {
@@ -7924,7 +7975,7 @@ async function handleHashGeneration(input5, options) {
7924
7975
  }
7925
7976
  }
7926
7977
  function createHashCommand() {
7927
- const cmd = new Command31("hash").description("Generate hash (MD5, SHA, bcrypt)").argument("[input]", "Text to hash").option(
7978
+ const cmd = new Command32("hash").description("Generate hash (MD5, SHA, bcrypt)").argument("[input]", "Text to hash").option(
7928
7979
  "-a, --algorithm <algorithm>",
7929
7980
  "Hash algorithm (md5, sha1, sha256, sha512, bcrypt)",
7930
7981
  "sha256"
@@ -7946,7 +7997,7 @@ Examples:
7946
7997
  }
7947
7998
 
7948
7999
  // src/commands/utils/base64-encode.ts
7949
- import { Command as Command32 } from "commander";
8000
+ import { Command as Command33 } from "commander";
7950
8001
  import { readFile as readFile2 } from "fs/promises";
7951
8002
  async function handleBase64Encode(input5, options) {
7952
8003
  const service = new UtilsService();
@@ -7979,7 +8030,7 @@ async function handleBase64Encode(input5, options) {
7979
8030
  }
7980
8031
  }
7981
8032
  function createBase64EncodeCommand() {
7982
- const cmd = new Command32("base64-encode").description("Encode text or file to Base64").argument("[input]", "Text to encode").option("-f, --file <path>", "Encode file contents").option("--url-safe", "Use URL-safe Base64 encoding").addHelpText("after", `
8033
+ const cmd = new Command33("base64-encode").description("Encode text or file to Base64").argument("[input]", "Text to encode").option("-f, --file <path>", "Encode file contents").option("--url-safe", "Use URL-safe Base64 encoding").addHelpText("after", `
7983
8034
  Examples:
7984
8035
  $ jai1 utils base64-encode "hello world"
7985
8036
  $ jai1 utils base64-encode "hello world" --url-safe
@@ -7992,7 +8043,7 @@ Examples:
7992
8043
  }
7993
8044
 
7994
8045
  // src/commands/utils/base64-decode.ts
7995
- import { Command as Command33 } from "commander";
8046
+ import { Command as Command34 } from "commander";
7996
8047
  import { readFile as readFile3, writeFile } from "fs/promises";
7997
8048
  async function handleBase64Decode(input5, options) {
7998
8049
  const service = new UtilsService();
@@ -8024,7 +8075,7 @@ async function handleBase64Decode(input5, options) {
8024
8075
  }
8025
8076
  }
8026
8077
  function createBase64DecodeCommand() {
8027
- const cmd = new Command33("base64-decode").description("Decode Base64 string").argument("[input]", "Base64 string to decode").option("-f, --file <path>", "Decode from file").option("-o, --output <path>", "Write decoded output to file").addHelpText("after", `
8078
+ const cmd = new Command34("base64-decode").description("Decode Base64 string").argument("[input]", "Base64 string to decode").option("-f, --file <path>", "Decode from file").option("-o, --output <path>", "Write decoded output to file").addHelpText("after", `
8028
8079
  Examples:
8029
8080
  $ jai1 utils base64-decode "aGVsbG8gd29ybGQ="
8030
8081
  $ jai1 utils base64-decode --file ./encoded.txt
@@ -8037,7 +8088,7 @@ Examples:
8037
8088
  }
8038
8089
 
8039
8090
  // src/commands/utils/http.ts
8040
- import { Command as Command34 } from "commander";
8091
+ import { Command as Command35 } from "commander";
8041
8092
  import { readFile as readFile4 } from "fs/promises";
8042
8093
  async function handleHttpRequest(url, options) {
8043
8094
  const service = new UtilsService();
@@ -8103,7 +8154,7 @@ async function handleHttpRequest(url, options) {
8103
8154
  }
8104
8155
  }
8105
8156
  function createHttpCommand() {
8106
- const cmd = new Command34("http").description("Make HTTP request with formatted output").argument("<url>", "Target URL").option("-X, --method <method>", "HTTP method", "GET").option("-H, --header <header...>", "Request headers (repeatable)").option("-d, --data <data>", "Request body (JSON string)").option("--file <path>", "Read body from file").option("--timeout <ms>", "Request timeout in milliseconds", "30000").option("--no-follow", "Do not follow redirects").option("--only-headers", "Show only response headers").option("--only-body", "Show only response body").addHelpText("after", `
8157
+ const cmd = new Command35("http").description("Make HTTP request with formatted output").argument("<url>", "Target URL").option("-X, --method <method>", "HTTP method", "GET").option("-H, --header <header...>", "Request headers (repeatable)").option("-d, --data <data>", "Request body (JSON string)").option("--file <path>", "Read body from file").option("--timeout <ms>", "Request timeout in milliseconds", "30000").option("--no-follow", "Do not follow redirects").option("--only-headers", "Show only response headers").option("--only-body", "Show only response body").addHelpText("after", `
8107
8158
  Examples:
8108
8159
  $ jai1 utils http https://api.example.com/users
8109
8160
  $ jai1 utils http https://api.example.com/users -X POST -d '{"name":"John"}'
@@ -8121,7 +8172,7 @@ Examples:
8121
8172
  }
8122
8173
 
8123
8174
  // src/commands/utils/jwt.ts
8124
- import { Command as Command35 } from "commander";
8175
+ import { Command as Command36 } from "commander";
8125
8176
  async function handleJwtDecode(token) {
8126
8177
  const service = new UtilsService();
8127
8178
  try {
@@ -8160,7 +8211,7 @@ async function handleJwtEncode(options) {
8160
8211
  }
8161
8212
  }
8162
8213
  function createJwtCommand() {
8163
- const jwtCommand = new Command35("jwt").description("Decode and encode JWT tokens");
8214
+ const jwtCommand = new Command36("jwt").description("Decode and encode JWT tokens");
8164
8215
  jwtCommand.command("decode").description("Decode JWT token").argument("<token>", "JWT token to decode").addHelpText("after", `
8165
8216
  Examples:
8166
8217
  $ jai1 utils jwt decode "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
@@ -8181,7 +8232,7 @@ Examples:
8181
8232
  }
8182
8233
 
8183
8234
  // src/commands/utils/unix-time.ts
8184
- import { Command as Command36 } from "commander";
8235
+ import { Command as Command37 } from "commander";
8185
8236
  async function handleUnixTime(input5, options) {
8186
8237
  const service = new UtilsService();
8187
8238
  try {
@@ -8229,7 +8280,7 @@ async function handleUnixTime(input5, options) {
8229
8280
  }
8230
8281
  }
8231
8282
  function createUnixTimeCommand() {
8232
- const cmd = new Command36("unix-time").description("Convert unix timestamps to/from dates").argument("[input]", "Unix timestamp or date string").option("-f, --format <format>", "Output format (iso, local, utc)", "iso").option("--ms", "Use milliseconds instead of seconds").addHelpText("after", `
8283
+ const cmd = new Command37("unix-time").description("Convert unix timestamps to/from dates").argument("[input]", "Unix timestamp or date string").option("-f, --format <format>", "Output format (iso, local, utc)", "iso").option("--ms", "Use milliseconds instead of seconds").addHelpText("after", `
8233
8284
  Examples:
8234
8285
  $ jai1 utils unix-time
8235
8286
  $ jai1 utils unix-time 1702550400
@@ -8244,7 +8295,7 @@ Examples:
8244
8295
  }
8245
8296
 
8246
8297
  // src/commands/utils/timezone.ts
8247
- import { Command as Command37 } from "commander";
8298
+ import { Command as Command38 } from "commander";
8248
8299
  async function handleTimezoneConversion(time, options) {
8249
8300
  const service = new UtilsService();
8250
8301
  try {
@@ -8281,7 +8332,7 @@ async function handleTimezoneConversion(time, options) {
8281
8332
  }
8282
8333
  }
8283
8334
  function createTimezoneCommand() {
8284
- const cmd = new Command37("timezone").description("Convert time between timezones").argument("[time]", 'Time to convert (e.g., "2024-01-15 10:00")').option("--from <timezone>", "Source timezone").option("--to <timezone>", "Target timezone").option("--list", "Show available timezones").addHelpText("after", `
8335
+ const cmd = new Command38("timezone").description("Convert time between timezones").argument("[time]", 'Time to convert (e.g., "2024-01-15 10:00")').option("--from <timezone>", "Source timezone").option("--to <timezone>", "Target timezone").option("--list", "Show available timezones").addHelpText("after", `
8285
8336
  Examples:
8286
8337
  $ jai1 utils timezone --list
8287
8338
  $ jai1 utils timezone "2024-01-15 10:00" --from "America/New_York" --to "Asia/Tokyo"
@@ -8294,7 +8345,7 @@ Examples:
8294
8345
  }
8295
8346
 
8296
8347
  // src/commands/utils/url-encode.ts
8297
- import { Command as Command38 } from "commander";
8348
+ import { Command as Command39 } from "commander";
8298
8349
  async function handleUrlEncode(input5, options) {
8299
8350
  const service = new UtilsService();
8300
8351
  try {
@@ -8315,7 +8366,7 @@ async function handleUrlEncode(input5, options) {
8315
8366
  }
8316
8367
  }
8317
8368
  function createUrlEncodeCommand() {
8318
- const cmd = new Command38("url-encode").description("Encode URL component or full URL").argument("<input>", "Text to encode").option("--full", "Encode full URL (use encodeURI instead of encodeURIComponent)").addHelpText("after", `
8369
+ const cmd = new Command39("url-encode").description("Encode URL component or full URL").argument("<input>", "Text to encode").option("--full", "Encode full URL (use encodeURI instead of encodeURIComponent)").addHelpText("after", `
8319
8370
  Examples:
8320
8371
  $ jai1 utils url-encode "hello world"
8321
8372
  $ jai1 utils url-encode "hello world & test"
@@ -8328,7 +8379,7 @@ Examples:
8328
8379
  }
8329
8380
 
8330
8381
  // src/commands/utils/url-decode.ts
8331
- import { Command as Command39 } from "commander";
8382
+ import { Command as Command40 } from "commander";
8332
8383
  async function handleUrlDecode(input5, options) {
8333
8384
  const service = new UtilsService();
8334
8385
  try {
@@ -8349,7 +8400,7 @@ async function handleUrlDecode(input5, options) {
8349
8400
  }
8350
8401
  }
8351
8402
  function createUrlDecodeCommand() {
8352
- const cmd = new Command39("url-decode").description("Decode URL-encoded string").argument("<input>", "Text to decode").option("--full", "Decode full URL (use decodeURI instead of decodeURIComponent)").addHelpText("after", `
8403
+ const cmd = new Command40("url-decode").description("Decode URL-encoded string").argument("<input>", "Text to decode").option("--full", "Decode full URL (use decodeURI instead of decodeURIComponent)").addHelpText("after", `
8353
8404
  Examples:
8354
8405
  $ jai1 utils url-decode "hello%20world"
8355
8406
  $ jai1 utils url-decode "hello%20world%20%26%20test"
@@ -8362,7 +8413,7 @@ Examples:
8362
8413
  }
8363
8414
 
8364
8415
  // src/commands/utils/cron.ts
8365
- import { Command as Command40 } from "commander";
8416
+ import { Command as Command41 } from "commander";
8366
8417
  import cronstrue from "cronstrue";
8367
8418
  async function handleCronParse(expression) {
8368
8419
  try {
@@ -8405,7 +8456,7 @@ async function handleCronParse(expression) {
8405
8456
  }
8406
8457
  }
8407
8458
  function createCronCommand() {
8408
- const cmd = new Command40("cron").description("Parse and explain cron expression").argument("<expression>", 'Cron expression (e.g., "0 5 * * *")').addHelpText("after", `
8459
+ const cmd = new Command41("cron").description("Parse and explain cron expression").argument("<expression>", 'Cron expression (e.g., "0 5 * * *")').addHelpText("after", `
8409
8460
  Examples:
8410
8461
  $ jai1 utils cron "0 5 * * *"
8411
8462
  $ jai1 utils cron "*/15 * * * *"
@@ -8419,7 +8470,7 @@ Examples:
8419
8470
  }
8420
8471
 
8421
8472
  // src/commands/utils/markdown-preview.ts
8422
- import { Command as Command41 } from "commander";
8473
+ import { Command as Command42 } from "commander";
8423
8474
  import { readFile as readFile5 } from "fs/promises";
8424
8475
  import { marked } from "marked";
8425
8476
  import TerminalRenderer from "marked-terminal";
@@ -8458,7 +8509,7 @@ ${code.trim()}
8458
8509
  }
8459
8510
  }
8460
8511
  function createMarkdownPreviewCommand() {
8461
- const cmd = new Command41("markdown-preview").description("Preview markdown file in terminal").argument("<file>", "Markdown file path").option("--raw", "Show raw markdown instead of rendered").addHelpText("after", `
8512
+ const cmd = new Command42("markdown-preview").description("Preview markdown file in terminal").argument("<file>", "Markdown file path").option("--raw", "Show raw markdown instead of rendered").addHelpText("after", `
8462
8513
  Examples:
8463
8514
  $ jai1 utils markdown-preview README.md
8464
8515
  $ jai1 utils markdown-preview ./docs/guide.md
@@ -9867,43 +9918,43 @@ async function runInteractiveMode() {
9867
9918
 
9868
9919
  // src/commands/utils/index.ts
9869
9920
  function showUtilsHelp() {
9870
- console.log(chalk15.bold.cyan("\u{1F6E0}\uFE0F jai1 utils") + chalk15.dim(" - Developer utilities"));
9921
+ console.log(chalk16.bold.cyan("\u{1F6E0}\uFE0F jai1 utils") + chalk16.dim(" - Developer utilities"));
9871
9922
  console.log();
9872
- console.log(chalk15.bold("M\xE3 h\xF3a & B\u1EA3o m\u1EADt:"));
9873
- console.log(` ${chalk15.cyan("password")} T\u1EA1o m\u1EADt kh\u1EA9u ng\u1EABu nhi\xEAn`);
9874
- console.log(` ${chalk15.cyan("uuid")} T\u1EA1o UUID v4`);
9875
- console.log(` ${chalk15.cyan("hash")} Hash text (MD5/SHA/bcrypt)`);
9876
- console.log(` ${chalk15.cyan("jwt")} Decode/encode JWT tokens`);
9923
+ console.log(chalk16.bold("M\xE3 h\xF3a & B\u1EA3o m\u1EADt:"));
9924
+ console.log(` ${chalk16.cyan("password")} T\u1EA1o m\u1EADt kh\u1EA9u ng\u1EABu nhi\xEAn`);
9925
+ console.log(` ${chalk16.cyan("uuid")} T\u1EA1o UUID v4`);
9926
+ console.log(` ${chalk16.cyan("hash")} Hash text (MD5/SHA/bcrypt)`);
9927
+ console.log(` ${chalk16.cyan("jwt")} Decode/encode JWT tokens`);
9877
9928
  console.log();
9878
- console.log(chalk15.bold("Encoding:"));
9879
- console.log(` ${chalk15.cyan("base64-encode")} Encode sang Base64`);
9880
- console.log(` ${chalk15.cyan("base64-decode")} Decode t\u1EEB Base64`);
9881
- console.log(` ${chalk15.cyan("url-encode")} Encode URL components`);
9882
- console.log(` ${chalk15.cyan("url-decode")} Decode URL components`);
9929
+ console.log(chalk16.bold("Encoding:"));
9930
+ console.log(` ${chalk16.cyan("base64-encode")} Encode sang Base64`);
9931
+ console.log(` ${chalk16.cyan("base64-decode")} Decode t\u1EEB Base64`);
9932
+ console.log(` ${chalk16.cyan("url-encode")} Encode URL components`);
9933
+ console.log(` ${chalk16.cyan("url-decode")} Decode URL components`);
9883
9934
  console.log();
9884
- console.log(chalk15.bold("Th\u1EDDi gian:"));
9885
- console.log(` ${chalk15.cyan("unix-time")} Chuy\u1EC3n \u0111\u1ED5i unix timestamp`);
9886
- console.log(` ${chalk15.cyan("timezone")} Chuy\u1EC3n \u0111\u1ED5i m\xFAi gi\u1EDD`);
9887
- console.log(` ${chalk15.cyan("cron")} Parse cron expressions`);
9935
+ console.log(chalk16.bold("Th\u1EDDi gian:"));
9936
+ console.log(` ${chalk16.cyan("unix-time")} Chuy\u1EC3n \u0111\u1ED5i unix timestamp`);
9937
+ console.log(` ${chalk16.cyan("timezone")} Chuy\u1EC3n \u0111\u1ED5i m\xFAi gi\u1EDD`);
9938
+ console.log(` ${chalk16.cyan("cron")} Parse cron expressions`);
9888
9939
  console.log();
9889
- console.log(chalk15.bold("Kh\xE1c:"));
9890
- console.log(` ${chalk15.cyan("http")} G\u1EEDi HTTP requests`);
9891
- console.log(` ${chalk15.cyan("markdown-preview")} Xem tr\u01B0\u1EDBc file markdown`);
9940
+ console.log(chalk16.bold("Kh\xE1c:"));
9941
+ console.log(` ${chalk16.cyan("http")} G\u1EEDi HTTP requests`);
9942
+ console.log(` ${chalk16.cyan("markdown-preview")} Xem tr\u01B0\u1EDBc file markdown`);
9892
9943
  console.log();
9893
- console.log(chalk15.bold("Ch\u1EBF \u0111\u1ED9 Interactive:"));
9894
- console.log(chalk15.dim(" $ jai1 utils -i"));
9895
- console.log(chalk15.dim(" $ jai1 utils --interactive"));
9944
+ console.log(chalk16.bold("Ch\u1EBF \u0111\u1ED9 Interactive:"));
9945
+ console.log(chalk16.dim(" $ jai1 utils -i"));
9946
+ console.log(chalk16.dim(" $ jai1 utils --interactive"));
9896
9947
  console.log();
9897
- console.log(chalk15.bold("V\xED d\u1EE5:"));
9898
- console.log(chalk15.dim(" $ jai1 utils password --length 24"));
9899
- console.log(chalk15.dim(" $ jai1 utils uuid --count 5"));
9900
- console.log(chalk15.dim(' $ jai1 utils hash "text" --algorithm sha256'));
9901
- console.log(chalk15.dim(" $ jai1 utils http https://api.example.com"));
9948
+ console.log(chalk16.bold("V\xED d\u1EE5:"));
9949
+ console.log(chalk16.dim(" $ jai1 utils password --length 24"));
9950
+ console.log(chalk16.dim(" $ jai1 utils uuid --count 5"));
9951
+ console.log(chalk16.dim(' $ jai1 utils hash "text" --algorithm sha256'));
9952
+ console.log(chalk16.dim(" $ jai1 utils http https://api.example.com"));
9902
9953
  console.log();
9903
- console.log(chalk15.dim('Ch\u1EA1y "jai1 utils <l\u1EC7nh> --help" \u0111\u1EC3 xem chi ti\u1EBFt'));
9954
+ console.log(chalk16.dim('Ch\u1EA1y "jai1 utils <l\u1EC7nh> --help" \u0111\u1EC3 xem chi ti\u1EBFt'));
9904
9955
  }
9905
9956
  function createUtilsCommand() {
9906
- const utilsCommand = new Command42("utils").description("Developer utilities for common tasks").option("-i, --interactive", "Run in interactive mode");
9957
+ const utilsCommand = new Command43("utils").description("Developer utilities for common tasks").option("-i, --interactive", "Run in interactive mode");
9907
9958
  utilsCommand.addCommand(createPasswordCommand());
9908
9959
  utilsCommand.addCommand(createUuidCommand());
9909
9960
  utilsCommand.addCommand(createHashCommand());
@@ -9928,12 +9979,12 @@ function createUtilsCommand() {
9928
9979
  }
9929
9980
 
9930
9981
  // src/commands/deps/index.ts
9931
- import { Command as Command45 } from "commander";
9932
- import chalk18 from "chalk";
9982
+ import { Command as Command46 } from "commander";
9983
+ import chalk19 from "chalk";
9933
9984
 
9934
9985
  // src/commands/deps/check.ts
9935
- import { Command as Command43 } from "commander";
9936
- import chalk16 from "chalk";
9986
+ import { Command as Command44 } from "commander";
9987
+ import chalk17 from "chalk";
9937
9988
  import Table4 from "cli-table3";
9938
9989
  import ora from "ora";
9939
9990
 
@@ -10528,7 +10579,7 @@ var DepsPythonService = class {
10528
10579
 
10529
10580
  // src/commands/deps/check.ts
10530
10581
  function createDepsCheckCommand() {
10531
- const checkCommand = new Command43("check").description("Ki\u1EC3m tra c\xE1c packages c\u1EA7n upgrade").action(async () => {
10582
+ const checkCommand = new Command44("check").description("Ki\u1EC3m tra c\xE1c packages c\u1EA7n upgrade").action(async () => {
10532
10583
  const cwd = process.cwd();
10533
10584
  const detector = new DepsDetectorService();
10534
10585
  const spinner = ora("\u0110ang ph\xE1t hi\u1EC7n lo\u1EA1i project...").start();
@@ -10536,7 +10587,7 @@ function createDepsCheckCommand() {
10536
10587
  if (projects.length === 0) {
10537
10588
  spinner.fail("Kh\xF4ng t\xECm th\u1EA5y project n\xE0o \u0111\u01B0\u1EE3c h\u1ED7 tr\u1EE3");
10538
10589
  console.log();
10539
- console.log(chalk16.dim("H\u1ED7 tr\u1EE3: Node.js (package.json), PHP (composer.json), Python (requirements.txt/Pipfile)"));
10590
+ console.log(chalk17.dim("H\u1ED7 tr\u1EE3: Node.js (package.json), PHP (composer.json), Python (requirements.txt/Pipfile)"));
10540
10591
  process.exit(1);
10541
10592
  }
10542
10593
  spinner.succeed(`Ph\xE1t hi\u1EC7n ${projects.length} project:`);
@@ -10550,7 +10601,7 @@ function createDepsCheckCommand() {
10550
10601
  await checkEcosystem(project.ecosystem, project.manager, cwd);
10551
10602
  }
10552
10603
  console.log();
10553
- console.log(chalk16.dim('\u{1F4A1} Ch\u1EA1y "jai1 deps upgrade" \u0111\u1EC3 n\xE2ng c\u1EA5p packages.'));
10604
+ console.log(chalk17.dim('\u{1F4A1} Ch\u1EA1y "jai1 deps upgrade" \u0111\u1EC3 n\xE2ng c\u1EA5p packages.'));
10554
10605
  });
10555
10606
  return checkCommand;
10556
10607
  }
@@ -10583,7 +10634,7 @@ async function checkEcosystem(ecosystem, manager, cwd) {
10583
10634
  });
10584
10635
  } catch (error) {
10585
10636
  spinner.fail(`L\u1ED7i ki\u1EC3m tra ${label}`);
10586
- console.log(chalk16.red(error.message));
10637
+ console.log(chalk17.red(error.message));
10587
10638
  console.log();
10588
10639
  return;
10589
10640
  }
@@ -10596,10 +10647,10 @@ async function checkEcosystem(ecosystem, manager, cwd) {
10596
10647
  console.log();
10597
10648
  const table = new Table4({
10598
10649
  head: [
10599
- chalk16.cyan("Package"),
10600
- chalk16.cyan("Hi\u1EC7n t\u1EA1i"),
10601
- chalk16.cyan("M\u1EDBi nh\u1EA5t"),
10602
- chalk16.cyan("Lo\u1EA1i")
10650
+ chalk17.cyan("Package"),
10651
+ chalk17.cyan("Hi\u1EC7n t\u1EA1i"),
10652
+ chalk17.cyan("M\u1EDBi nh\u1EA5t"),
10653
+ chalk17.cyan("Lo\u1EA1i")
10603
10654
  ],
10604
10655
  style: {
10605
10656
  head: [],
@@ -10610,9 +10661,9 @@ async function checkEcosystem(ecosystem, manager, cwd) {
10610
10661
  const upgradeIcon = pkg.upgradeType === "major" ? "\u{1F534}" : pkg.upgradeType === "minor" ? "\u{1F7E1}" : "\u{1F7E2}";
10611
10662
  table.push([
10612
10663
  `${upgradeIcon} ${pkg.name}`,
10613
- chalk16.dim(pkg.current),
10614
- chalk16.green(pkg.latest),
10615
- pkg.type === "dev" ? chalk16.dim("dev") : "dep"
10664
+ chalk17.dim(pkg.current),
10665
+ chalk17.green(pkg.latest),
10666
+ pkg.type === "dev" ? chalk17.dim("dev") : "dep"
10616
10667
  ]);
10617
10668
  }
10618
10669
  console.log(table.toString());
@@ -10620,26 +10671,26 @@ async function checkEcosystem(ecosystem, manager, cwd) {
10620
10671
  if (result.isLaravel) {
10621
10672
  const blockedPackages = result.packages.filter((p) => p.blockedReason);
10622
10673
  if (blockedPackages.length > 0) {
10623
- console.log(chalk16.yellow("\u26A0\uFE0F Laravel major version upgrades blocked (nguy hi\u1EC3m):"));
10674
+ console.log(chalk17.yellow("\u26A0\uFE0F Laravel major version upgrades blocked (nguy hi\u1EC3m):"));
10624
10675
  for (const pkg of blockedPackages) {
10625
- console.log(chalk16.dim(` - ${pkg.name}: ${pkg.current} \u2192 ${pkg.latest}`));
10676
+ console.log(chalk17.dim(` - ${pkg.name}: ${pkg.current} \u2192 ${pkg.latest}`));
10626
10677
  }
10627
10678
  console.log();
10628
- console.log(chalk16.dim("\u{1F4A1} \u0110\u1EC3 n\xE2ng c\u1EA5p Laravel major version, ch\u1EA1y th\u1EE7 c\xF4ng:"));
10629
- console.log(chalk16.dim(` composer require ${blockedPackages[0].name}:^${blockedPackages[0].latest}`));
10679
+ console.log(chalk17.dim("\u{1F4A1} \u0110\u1EC3 n\xE2ng c\u1EA5p Laravel major version, ch\u1EA1y th\u1EE7 c\xF4ng:"));
10680
+ console.log(chalk17.dim(` composer require ${blockedPackages[0].name}:^${blockedPackages[0].latest}`));
10630
10681
  console.log();
10631
10682
  }
10632
10683
  }
10633
10684
  }
10634
10685
 
10635
10686
  // src/commands/deps/upgrade.ts
10636
- import { Command as Command44 } from "commander";
10687
+ import { Command as Command45 } from "commander";
10637
10688
  import { checkbox as checkbox3, confirm as confirm8 } from "@inquirer/prompts";
10638
- import chalk17 from "chalk";
10689
+ import chalk18 from "chalk";
10639
10690
  import ora2 from "ora";
10640
10691
  import Table5 from "cli-table3";
10641
10692
  function createDepsUpgradeCommand() {
10642
- return new Command44("upgrade").description("Upgrade packages l\xEAn version m\u1EDBi nh\u1EA5t").option("--all", "Upgrade t\u1EA5t c\u1EA3 kh\xF4ng c\u1EA7n ch\u1ECDn").action(async (options) => {
10693
+ return new Command45("upgrade").description("Upgrade packages l\xEAn version m\u1EDBi nh\u1EA5t").option("--all", "Upgrade t\u1EA5t c\u1EA3 kh\xF4ng c\u1EA7n ch\u1ECDn").action(async (options) => {
10643
10694
  await handleDepsUpgrade(options);
10644
10695
  });
10645
10696
  }
@@ -10652,7 +10703,7 @@ async function handleDepsUpgrade(options) {
10652
10703
  if (projects.length === 0) {
10653
10704
  spinner.fail("Kh\xF4ng t\xECm th\u1EA5y project n\xE0o \u0111\u01B0\u1EE3c h\u1ED7 tr\u1EE3");
10654
10705
  console.log();
10655
- console.log(chalk17.dim("H\u1ED7 tr\u1EE3: Node.js (package.json), PHP (composer.json), Python (requirements.txt/Pipfile)"));
10706
+ console.log(chalk18.dim("H\u1ED7 tr\u1EE3: Node.js (package.json), PHP (composer.json), Python (requirements.txt/Pipfile)"));
10656
10707
  process.exit(1);
10657
10708
  }
10658
10709
  spinner.succeed(`Ph\xE1t hi\u1EC7n ${projects.length} project:`);
@@ -10666,9 +10717,9 @@ async function handleDepsUpgrade(options) {
10666
10717
  await upgradeEcosystem(project, cwd, options);
10667
10718
  }
10668
10719
  console.log();
10669
- console.log(chalk17.green("\u2705 Ho\xE0n th\xE0nh!"));
10720
+ console.log(chalk18.green("\u2705 Ho\xE0n th\xE0nh!"));
10670
10721
  } catch (error) {
10671
- console.error(chalk17.red(`
10722
+ console.error(chalk18.red(`
10672
10723
  \u274C ${error.message}
10673
10724
  `));
10674
10725
  process.exit(1);
@@ -10677,10 +10728,10 @@ async function handleDepsUpgrade(options) {
10677
10728
  async function upgradeEcosystem(project, cwd, options) {
10678
10729
  const service = getService(project.ecosystem);
10679
10730
  const label = `${getEcosystemIcon(project.ecosystem)} ${getEcosystemLabel(project.ecosystem)}`;
10680
- console.log(chalk17.bold.cyan(`
10731
+ console.log(chalk18.bold.cyan(`
10681
10732
  ${"\u2501".repeat(80)}`));
10682
- console.log(chalk17.bold.cyan(`${label}`));
10683
- console.log(chalk17.bold.cyan("\u2501".repeat(80)));
10733
+ console.log(chalk18.bold.cyan(`${label}`));
10734
+ console.log(chalk18.bold.cyan("\u2501".repeat(80)));
10684
10735
  console.log();
10685
10736
  const spinner = ora2("\u0110ang ki\u1EC3m tra packages...").start();
10686
10737
  let packages;
@@ -10691,7 +10742,7 @@ ${"\u2501".repeat(80)}`));
10691
10742
  packages = result.packages;
10692
10743
  } catch (error) {
10693
10744
  spinner.fail("L\u1ED7i ki\u1EC3m tra packages");
10694
- console.log(chalk17.red(error.message));
10745
+ console.log(chalk18.red(error.message));
10695
10746
  return;
10696
10747
  }
10697
10748
  if (packages.length === 0) {
@@ -10704,7 +10755,7 @@ ${"\u2501".repeat(80)}`));
10704
10755
  let selectedPackages;
10705
10756
  if (options.all) {
10706
10757
  selectedPackages = packages;
10707
- console.log(chalk17.cyan(`\u{1F4CB} \u0110\xE3 ch\u1ECDn t\u1EA5t c\u1EA3 ${selectedPackages.length} packages
10758
+ console.log(chalk18.cyan(`\u{1F4CB} \u0110\xE3 ch\u1ECDn t\u1EA5t c\u1EA3 ${selectedPackages.length} packages
10708
10759
  `));
10709
10760
  } else {
10710
10761
  try {
@@ -10722,12 +10773,12 @@ ${"\u2501".repeat(80)}`));
10722
10773
  theme: checkboxTheme
10723
10774
  });
10724
10775
  if (selected.length === 0) {
10725
- console.log(chalk17.yellow("\u23F8\uFE0F Kh\xF4ng c\xF3 packages n\xE0o \u0111\u01B0\u1EE3c ch\u1ECDn\n"));
10776
+ console.log(chalk18.yellow("\u23F8\uFE0F Kh\xF4ng c\xF3 packages n\xE0o \u0111\u01B0\u1EE3c ch\u1ECDn\n"));
10726
10777
  return;
10727
10778
  }
10728
10779
  selectedPackages = packages.filter((p) => selected.includes(p.name));
10729
10780
  } catch {
10730
- console.log(chalk17.yellow("\n\u23F8\uFE0F \u0110\xE3 h\u1EE7y\n"));
10781
+ console.log(chalk18.yellow("\n\u23F8\uFE0F \u0110\xE3 h\u1EE7y\n"));
10731
10782
  return;
10732
10783
  }
10733
10784
  }
@@ -10738,35 +10789,35 @@ ${"\u2501".repeat(80)}`));
10738
10789
  default: true
10739
10790
  });
10740
10791
  } catch {
10741
- console.log(chalk17.yellow("\n\u23F8\uFE0F \u0110\xE3 h\u1EE7y\n"));
10792
+ console.log(chalk18.yellow("\n\u23F8\uFE0F \u0110\xE3 h\u1EE7y\n"));
10742
10793
  return;
10743
10794
  }
10744
10795
  if (!shouldProceed) {
10745
- console.log(chalk17.yellow("\u23F8\uFE0F Upgrade \u0111\xE3 h\u1EE7y\n"));
10796
+ console.log(chalk18.yellow("\u23F8\uFE0F Upgrade \u0111\xE3 h\u1EE7y\n"));
10746
10797
  return;
10747
10798
  }
10748
10799
  console.log();
10749
- console.log(chalk17.cyan(`\u{1F527} Package manager: ${project.manager}`));
10750
- console.log(chalk17.cyan("\u{1F4E5} \u0110ang upgrade...\n"));
10800
+ console.log(chalk18.cyan(`\u{1F527} Package manager: ${project.manager}`));
10801
+ console.log(chalk18.cyan("\u{1F4E5} \u0110ang upgrade...\n"));
10751
10802
  const commands = service.getUpgradeCommands(selectedPackages);
10752
10803
  try {
10753
10804
  if (commands.deps) {
10754
- console.log(chalk17.dim(`$ ${commands.deps}
10805
+ console.log(chalk18.dim(`$ ${commands.deps}
10755
10806
  `));
10756
10807
  }
10757
10808
  if (commands.devDeps) {
10758
- console.log(chalk17.dim(`$ ${commands.devDeps}
10809
+ console.log(chalk18.dim(`$ ${commands.devDeps}
10759
10810
  `));
10760
10811
  }
10761
10812
  await service.upgrade(cwd, { packages: selectedPackages });
10762
- console.log(chalk17.green(`
10813
+ console.log(chalk18.green(`
10763
10814
  \u2705 \u0110\xE3 upgrade ${selectedPackages.length} packages th\xE0nh c\xF4ng!`));
10764
10815
  } catch (error) {
10765
- console.error(chalk17.red("\n\u274C L\u1ED7i khi upgrade:"));
10766
- console.error(chalk17.red(error.message));
10767
- console.log(chalk17.yellow("\n\u{1F4A1} B\u1EA1n c\xF3 th\u1EC3 th\u1EED upgrade th\u1EE7 c\xF4ng:"));
10768
- if (commands.deps) console.log(chalk17.cyan(` ${commands.deps}`));
10769
- if (commands.devDeps) console.log(chalk17.cyan(` ${commands.devDeps}`));
10816
+ console.error(chalk18.red("\n\u274C L\u1ED7i khi upgrade:"));
10817
+ console.error(chalk18.red(error.message));
10818
+ console.log(chalk18.yellow("\n\u{1F4A1} B\u1EA1n c\xF3 th\u1EC3 th\u1EED upgrade th\u1EE7 c\xF4ng:"));
10819
+ if (commands.deps) console.log(chalk18.cyan(` ${commands.deps}`));
10820
+ if (commands.devDeps) console.log(chalk18.cyan(` ${commands.devDeps}`));
10770
10821
  console.log();
10771
10822
  throw error;
10772
10823
  }
@@ -10774,10 +10825,10 @@ ${"\u2501".repeat(80)}`));
10774
10825
  function displayUpgradeTable(packages) {
10775
10826
  const table = new Table5({
10776
10827
  head: [
10777
- chalk17.cyan("Package"),
10778
- chalk17.cyan("Hi\u1EC7n t\u1EA1i"),
10779
- chalk17.cyan("M\u1EDBi nh\u1EA5t"),
10780
- chalk17.cyan("Lo\u1EA1i")
10828
+ chalk18.cyan("Package"),
10829
+ chalk18.cyan("Hi\u1EC7n t\u1EA1i"),
10830
+ chalk18.cyan("M\u1EDBi nh\u1EA5t"),
10831
+ chalk18.cyan("Lo\u1EA1i")
10781
10832
  ],
10782
10833
  style: {
10783
10834
  head: [],
@@ -10788,9 +10839,9 @@ function displayUpgradeTable(packages) {
10788
10839
  const upgradeIcon = pkg.upgradeType === "major" ? "\u{1F534}" : pkg.upgradeType === "minor" ? "\u{1F7E1}" : "\u{1F7E2}";
10789
10840
  table.push([
10790
10841
  `${upgradeIcon} ${pkg.name}`,
10791
- chalk17.dim(pkg.current),
10792
- chalk17.green(pkg.latest),
10793
- pkg.type === "dev" ? chalk17.dim("dev") : "dep"
10842
+ chalk18.dim(pkg.current),
10843
+ chalk18.green(pkg.latest),
10844
+ pkg.type === "dev" ? chalk18.dim("dev") : "dep"
10794
10845
  ]);
10795
10846
  }
10796
10847
  console.log(table.toString());
@@ -10833,26 +10884,26 @@ function getEcosystemLabel(ecosystem) {
10833
10884
 
10834
10885
  // src/commands/deps/index.ts
10835
10886
  function showDepsHelp() {
10836
- console.log(chalk18.bold.cyan("\u{1F4E6} jai1 deps") + chalk18.dim(" - Qu\u1EA3n l\xFD dependencies trong project"));
10887
+ console.log(chalk19.bold.cyan("\u{1F4E6} jai1 deps") + chalk19.dim(" - Qu\u1EA3n l\xFD dependencies trong project"));
10837
10888
  console.log();
10838
- console.log(chalk18.bold("C\xE1c l\u1EC7nh:"));
10839
- console.log(` ${chalk18.cyan("check")} Ki\u1EC3m tra c\xE1c packages c\u1EA7n upgrade`);
10840
- console.log(` ${chalk18.cyan("upgrade")} N\xE2ng c\u1EA5p dependencies l\xEAn phi\xEAn b\u1EA3n m\u1EDBi nh\u1EA5t`);
10889
+ console.log(chalk19.bold("C\xE1c l\u1EC7nh:"));
10890
+ console.log(` ${chalk19.cyan("check")} Ki\u1EC3m tra c\xE1c packages c\u1EA7n upgrade`);
10891
+ console.log(` ${chalk19.cyan("upgrade")} N\xE2ng c\u1EA5p dependencies l\xEAn phi\xEAn b\u1EA3n m\u1EDBi nh\u1EA5t`);
10841
10892
  console.log();
10842
- console.log(chalk18.bold("H\u1ED7 tr\u1EE3:"));
10843
- console.log(chalk18.dim(" \u2022 Node.js (npm, pnpm, yarn, bun)"));
10844
- console.log(chalk18.dim(" \u2022 PHP/Composer (v\u1EDBi b\u1EA3o v\u1EC7 Laravel major version)"));
10845
- console.log(chalk18.dim(" \u2022 Python (pip, pipenv)"));
10893
+ console.log(chalk19.bold("H\u1ED7 tr\u1EE3:"));
10894
+ console.log(chalk19.dim(" \u2022 Node.js (npm, pnpm, yarn, bun)"));
10895
+ console.log(chalk19.dim(" \u2022 PHP/Composer (v\u1EDBi b\u1EA3o v\u1EC7 Laravel major version)"));
10896
+ console.log(chalk19.dim(" \u2022 Python (pip, pipenv)"));
10846
10897
  console.log();
10847
- console.log(chalk18.bold("V\xED d\u1EE5:"));
10848
- console.log(chalk18.dim(" $ jai1 deps check"));
10849
- console.log(chalk18.dim(" $ jai1 deps upgrade"));
10850
- console.log(chalk18.dim(" $ jai1 deps upgrade --all"));
10898
+ console.log(chalk19.bold("V\xED d\u1EE5:"));
10899
+ console.log(chalk19.dim(" $ jai1 deps check"));
10900
+ console.log(chalk19.dim(" $ jai1 deps upgrade"));
10901
+ console.log(chalk19.dim(" $ jai1 deps upgrade --all"));
10851
10902
  console.log();
10852
- console.log(chalk18.dim('Ch\u1EA1y "jai1 deps <l\u1EC7nh> --help" \u0111\u1EC3 xem chi ti\u1EBFt'));
10903
+ console.log(chalk19.dim('Ch\u1EA1y "jai1 deps <l\u1EC7nh> --help" \u0111\u1EC3 xem chi ti\u1EBFt'));
10853
10904
  }
10854
10905
  function createDepsCommand() {
10855
- const depsCommand = new Command45("deps").description("Qu\u1EA3n l\xFD dependencies trong project").action(() => {
10906
+ const depsCommand = new Command46("deps").description("Qu\u1EA3n l\xFD dependencies trong project").action(() => {
10856
10907
  showDepsHelp();
10857
10908
  });
10858
10909
  depsCommand.addCommand(createDepsCheckCommand());
@@ -10861,17 +10912,17 @@ function createDepsCommand() {
10861
10912
  }
10862
10913
 
10863
10914
  // src/commands/tasks/index.ts
10864
- import { Command as Command56 } from "commander";
10915
+ import { Command as Command57 } from "commander";
10865
10916
 
10866
10917
  // src/commands/tasks/add.ts
10867
- import { Command as Command46 } from "commander";
10868
- import chalk19 from "chalk";
10918
+ import { Command as Command47 } from "commander";
10919
+ import chalk20 from "chalk";
10869
10920
  function createTaskAddCommand() {
10870
- return new Command46("add").description("Add a new task").argument("<title>", "Task title").option("-p, --priority <n>", "Priority: 0=critical, 1=high, 2=medium, 3=low", "2").option("-P, --parent <parent>", "Parent: feature/xxx, plan/xxx, bug/xxx").option("-t, --tags <tags>", "Comma-separated tags").option("-j, --json", "Output JSON").action(async (title, options) => {
10921
+ return new Command47("add").description("Add a new task").argument("<title>", "Task title").option("-p, --priority <n>", "Priority: 0=critical, 1=high, 2=medium, 3=low", "2").option("-P, --parent <parent>", "Parent: feature/xxx, plan/xxx, bug/xxx").option("-t, --tags <tags>", "Comma-separated tags").option("-j, --json", "Output JSON").action(async (title, options) => {
10871
10922
  const service = new TaskService();
10872
10923
  const priority = Number(options.priority ?? 2);
10873
10924
  if (priority < 0 || priority > 3) {
10874
- console.error(chalk19.red("\u274C Priority must be 0-3"));
10925
+ console.error(chalk20.red("\u274C Priority must be 0-3"));
10875
10926
  process.exit(1);
10876
10927
  }
10877
10928
  const tags = options.tags ? options.tags.split(",").map((t) => t.trim()) : [];
@@ -10887,23 +10938,23 @@ function createTaskAddCommand() {
10887
10938
  }
10888
10939
  const icon = PRIORITY_ICONS[task.priority] || "\u{1F7E1}";
10889
10940
  const label = PRIORITY_LABELS[task.priority] || "Medium";
10890
- console.log(chalk19.green(`\u2705 Task added: ${chalk19.bold(task.id)}`));
10891
- console.log(` ${chalk19.dim("Title:")} ${task.title}`);
10892
- console.log(` ${chalk19.dim("Priority:")} ${icon} ${label}`);
10941
+ console.log(chalk20.green(`\u2705 Task added: ${chalk20.bold(task.id)}`));
10942
+ console.log(` ${chalk20.dim("Title:")} ${task.title}`);
10943
+ console.log(` ${chalk20.dim("Priority:")} ${icon} ${label}`);
10893
10944
  if (task.parent) {
10894
- console.log(` ${chalk19.dim("Parent:")} ${task.parent}`);
10945
+ console.log(` ${chalk20.dim("Parent:")} ${task.parent}`);
10895
10946
  }
10896
10947
  if (task.tags.length > 0) {
10897
- console.log(` ${chalk19.dim("Tags:")} ${task.tags.join(", ")}`);
10948
+ console.log(` ${chalk20.dim("Tags:")} ${task.tags.join(", ")}`);
10898
10949
  }
10899
10950
  });
10900
10951
  }
10901
10952
 
10902
10953
  // src/commands/tasks/list.ts
10903
- import { Command as Command47 } from "commander";
10904
- import chalk20 from "chalk";
10954
+ import { Command as Command48 } from "commander";
10955
+ import chalk21 from "chalk";
10905
10956
  function createTaskListCommand() {
10906
- return new Command47("list").alias("ls").description("List tasks").option("-s, --status <status>", "Filter by status: todo, in_progress, done, cancelled").option("-P, --parent <parent>", "Filter by parent: feature/xxx, plan/xxx").option("-j, --json", "Output JSON").action(async (options) => {
10957
+ return new Command48("list").alias("ls").description("List tasks").option("-s, --status <status>", "Filter by status: todo, in_progress, done, cancelled").option("-P, --parent <parent>", "Filter by parent: feature/xxx, plan/xxx").option("-j, --json", "Output JSON").action(async (options) => {
10907
10958
  await handleTaskList(options);
10908
10959
  });
10909
10960
  }
@@ -10922,12 +10973,12 @@ async function handleTaskList(options) {
10922
10973
  return;
10923
10974
  }
10924
10975
  if (tasks.length === 0) {
10925
- console.log(chalk20.dim("No tasks found."));
10976
+ console.log(chalk21.dim("No tasks found."));
10926
10977
  return;
10927
10978
  }
10928
10979
  const doneIds = new Set(allTasks.filter((t) => t.status === "done").map((t) => t.id));
10929
10980
  const header = options.parent ? `\u{1F4CB} ${options.parent} (${tasks.length} tasks)` : `\u{1F4CB} All tasks (${tasks.length})`;
10930
- console.log(chalk20.bold(header));
10981
+ console.log(chalk21.bold(header));
10931
10982
  console.log();
10932
10983
  for (const task of tasks) {
10933
10984
  printTaskLine(task, doneIds);
@@ -10937,25 +10988,25 @@ function printTaskLine(task, doneIds) {
10937
10988
  const isBlocked = task.status === "todo" && task.depends_on.length > 0 && !task.depends_on.every((id) => doneIds.has(id));
10938
10989
  const statusIcon = isBlocked ? BLOCKED_ICON : STATUS_ICONS[task.status] || "\u{1F4CB}";
10939
10990
  const priorityIcon = PRIORITY_ICONS[task.priority] || "\u{1F7E1}";
10940
- let line = ` ${statusIcon} ${chalk20.dim(task.id)} P${task.priority}${priorityIcon} ${task.title}`;
10991
+ let line = ` ${statusIcon} ${chalk21.dim(task.id)} P${task.priority}${priorityIcon} ${task.title}`;
10941
10992
  if (task.status === "in_progress" && task.assigned_to) {
10942
- line += chalk20.cyan(` @${task.assigned_to}`);
10993
+ line += chalk21.cyan(` @${task.assigned_to}`);
10943
10994
  }
10944
10995
  if (isBlocked) {
10945
10996
  const blockedBy = task.depends_on.filter((id) => !doneIds.has(id));
10946
- line += chalk20.red(` (blocked: ${blockedBy.join(", ")})`);
10997
+ line += chalk21.red(` (blocked: ${blockedBy.join(", ")})`);
10947
10998
  }
10948
10999
  if (task.parent) {
10949
- line += chalk20.dim(` [${task.parent}]`);
11000
+ line += chalk21.dim(` [${task.parent}]`);
10950
11001
  }
10951
11002
  console.log(line);
10952
11003
  }
10953
11004
 
10954
11005
  // src/commands/tasks/ready.ts
10955
- import { Command as Command48 } from "commander";
10956
- import chalk21 from "chalk";
11006
+ import { Command as Command49 } from "commander";
11007
+ import chalk22 from "chalk";
10957
11008
  function createTaskReadyCommand() {
10958
- return new Command48("ready").description("Show tasks ready to pick (not blocked, not assigned)").option("-P, --parent <parent>", "Filter by parent").option("-j, --json", "Output JSON").action(async (options) => {
11009
+ return new Command49("ready").description("Show tasks ready to pick (not blocked, not assigned)").option("-P, --parent <parent>", "Filter by parent").option("-j, --json", "Output JSON").action(async (options) => {
10959
11010
  const service = new TaskService();
10960
11011
  const tasks = await service.getReady(options.parent);
10961
11012
  if (options.json) {
@@ -10963,37 +11014,37 @@ function createTaskReadyCommand() {
10963
11014
  return;
10964
11015
  }
10965
11016
  if (tasks.length === 0) {
10966
- console.log(chalk21.dim("No tasks ready to pick."));
10967
- console.log(chalk21.dim("\u{1F4A1} Check blocked tasks: jai1 t list -s todo"));
11017
+ console.log(chalk22.dim("No tasks ready to pick."));
11018
+ console.log(chalk22.dim("\u{1F4A1} Check blocked tasks: jai1 t list -s todo"));
10968
11019
  return;
10969
11020
  }
10970
- console.log(chalk21.bold(`\u{1F4CB} Ready to pick (${tasks.length} tasks):`));
11021
+ console.log(chalk22.bold(`\u{1F4CB} Ready to pick (${tasks.length} tasks):`));
10971
11022
  console.log();
10972
11023
  for (const task of tasks) {
10973
11024
  const icon = PRIORITY_ICONS[task.priority] || "\u{1F7E1}";
10974
- let line = ` P${task.priority}${icon} ${chalk21.dim(task.id)} ${task.title}`;
11025
+ let line = ` P${task.priority}${icon} ${chalk22.dim(task.id)} ${task.title}`;
10975
11026
  if (task.parent) {
10976
- line += chalk21.dim(` [${task.parent}]`);
11027
+ line += chalk22.dim(` [${task.parent}]`);
10977
11028
  }
10978
11029
  console.log(line);
10979
11030
  }
10980
11031
  console.log();
10981
- console.log(chalk21.dim("\u{1F4A1} Run: jai1 t pick"));
11032
+ console.log(chalk22.dim("\u{1F4A1} Run: jai1 t pick"));
10982
11033
  });
10983
11034
  }
10984
11035
 
10985
11036
  // src/commands/tasks/update.ts
10986
- import { Command as Command49 } from "commander";
10987
- import chalk22 from "chalk";
11037
+ import { Command as Command50 } from "commander";
11038
+ import chalk23 from "chalk";
10988
11039
  var VALID_STATUSES = ["todo", "in_progress", "done", "cancelled"];
10989
11040
  function createTaskUpdateCommand() {
10990
- return new Command49("update").description("Update task status and/or notes").argument("<id>", "Task ID (e.g. T-001)").option("-s, --status <status>", "New status: todo, in_progress, done, cancelled").option("-n, --notes <notes>", 'Task notes (e.g. "files: a.ts, b.ts")').option("-j, --json", "Output JSON").action(async (id, options) => {
11041
+ return new Command50("update").description("Update task status and/or notes").argument("<id>", "Task ID (e.g. T-001)").option("-s, --status <status>", "New status: todo, in_progress, done, cancelled").option("-n, --notes <notes>", 'Task notes (e.g. "files: a.ts, b.ts")').option("-j, --json", "Output JSON").action(async (id, options) => {
10991
11042
  if (!options.status && !options.notes) {
10992
- console.error(chalk22.red("\u274C At least one of --status or --notes is required"));
11043
+ console.error(chalk23.red("\u274C At least one of --status or --notes is required"));
10993
11044
  process.exit(1);
10994
11045
  }
10995
11046
  if (options.status && !VALID_STATUSES.includes(options.status)) {
10996
- console.error(chalk22.red(`\u274C Invalid status. Must be: ${VALID_STATUSES.join(", ")}`));
11047
+ console.error(chalk23.red(`\u274C Invalid status. Must be: ${VALID_STATUSES.join(", ")}`));
10997
11048
  process.exit(1);
10998
11049
  }
10999
11050
  const service = new TaskService();
@@ -11014,24 +11065,24 @@ function createTaskUpdateCommand() {
11014
11065
  if (options.notes) {
11015
11066
  parts.push(`\u{1F4DD} notes updated`);
11016
11067
  }
11017
- console.log(chalk22.green(`\u2705 ${task.id} \u2192 ${parts.join(" | ")}`));
11068
+ console.log(chalk23.green(`\u2705 ${task.id} \u2192 ${parts.join(" | ")}`));
11018
11069
  } catch (error) {
11019
- console.error(chalk22.red(`\u274C ${error instanceof Error ? error.message : String(error)}`));
11070
+ console.error(chalk23.red(`\u274C ${error instanceof Error ? error.message : String(error)}`));
11020
11071
  process.exit(1);
11021
11072
  }
11022
11073
  });
11023
11074
  }
11024
11075
 
11025
11076
  // src/commands/tasks/show.ts
11026
- import { Command as Command50 } from "commander";
11027
- import chalk23 from "chalk";
11077
+ import { Command as Command51 } from "commander";
11078
+ import chalk24 from "chalk";
11028
11079
  function createTaskShowCommand() {
11029
- return new Command50("show").description("Show task detail or all tasks under a parent").argument("<query>", "Task ID (T-001) or parent (feature/xxx)").option("-j, --json", "Output JSON").action(async (query, options) => {
11080
+ return new Command51("show").description("Show task detail or all tasks under a parent").argument("<query>", "Task ID (T-001) or parent (feature/xxx)").option("-j, --json", "Output JSON").action(async (query, options) => {
11030
11081
  const service = new TaskService();
11031
11082
  if (query.startsWith("T-")) {
11032
11083
  const task = await service.findById(query);
11033
11084
  if (!task) {
11034
- console.error(chalk23.red(`\u274C Task ${query} not found`));
11085
+ console.error(chalk24.red(`\u274C Task ${query} not found`));
11035
11086
  process.exit(1);
11036
11087
  }
11037
11088
  if (options.json) {
@@ -11042,34 +11093,34 @@ function createTaskShowCommand() {
11042
11093
  const statusIcon = blocked ? BLOCKED_ICON : STATUS_ICONS[task.status] || "\u{1F4CB}";
11043
11094
  const priIcon = PRIORITY_ICONS[task.priority] || "\u{1F7E1}";
11044
11095
  const priLabel = PRIORITY_LABELS[task.priority] || "Medium";
11045
- console.log(chalk23.bold(`
11096
+ console.log(chalk24.bold(`
11046
11097
  \u{1F4CC} ${task.id}: ${task.title}
11047
11098
  `));
11048
- console.log(` ${chalk23.dim("Status:")} ${statusIcon} ${task.status}${blocked ? chalk23.red(" (BLOCKED)") : ""}`);
11049
- console.log(` ${chalk23.dim("Priority:")} ${priIcon} P${task.priority} ${priLabel}`);
11099
+ console.log(` ${chalk24.dim("Status:")} ${statusIcon} ${task.status}${blocked ? chalk24.red(" (BLOCKED)") : ""}`);
11100
+ console.log(` ${chalk24.dim("Priority:")} ${priIcon} P${task.priority} ${priLabel}`);
11050
11101
  if (task.parent) {
11051
- console.log(` ${chalk23.dim("Parent:")} ${task.parent}`);
11102
+ console.log(` ${chalk24.dim("Parent:")} ${task.parent}`);
11052
11103
  }
11053
11104
  if (task.assigned_to) {
11054
- console.log(` ${chalk23.dim("Assigned:")} @${task.assigned_to} (${task.claimed_at})`);
11105
+ console.log(` ${chalk24.dim("Assigned:")} @${task.assigned_to} (${task.claimed_at})`);
11055
11106
  }
11056
11107
  if (task.depends_on.length > 0) {
11057
- console.log(` ${chalk23.dim("Depends on:")} ${task.depends_on.join(", ")}`);
11108
+ console.log(` ${chalk24.dim("Depends on:")} ${task.depends_on.join(", ")}`);
11058
11109
  if (blocked) {
11059
- console.log(` ${chalk23.dim("Blocked by:")} ${chalk23.red(blockedBy.join(", "))}`);
11110
+ console.log(` ${chalk24.dim("Blocked by:")} ${chalk24.red(blockedBy.join(", "))}`);
11060
11111
  }
11061
11112
  }
11062
11113
  if (task.tags.length > 0) {
11063
- console.log(` ${chalk23.dim("Tags:")} ${task.tags.join(", ")}`);
11114
+ console.log(` ${chalk24.dim("Tags:")} ${task.tags.join(", ")}`);
11064
11115
  }
11065
11116
  if (task.branch) {
11066
- console.log(` ${chalk23.dim("Branch:")} ${task.branch}`);
11117
+ console.log(` ${chalk24.dim("Branch:")} ${task.branch}`);
11067
11118
  }
11068
11119
  if (task.notes) {
11069
- console.log(` ${chalk23.dim("Notes:")} ${task.notes}`);
11120
+ console.log(` ${chalk24.dim("Notes:")} ${task.notes}`);
11070
11121
  }
11071
- console.log(` ${chalk23.dim("Created:")} ${task.created}`);
11072
- console.log(` ${chalk23.dim("Updated:")} ${task.updated}`);
11122
+ console.log(` ${chalk24.dim("Created:")} ${task.created}`);
11123
+ console.log(` ${chalk24.dim("Updated:")} ${task.updated}`);
11073
11124
  console.log();
11074
11125
  } else {
11075
11126
  const tasks = await service.filter({ parent: query });
@@ -11078,10 +11129,10 @@ function createTaskShowCommand() {
11078
11129
  return;
11079
11130
  }
11080
11131
  if (tasks.length === 0) {
11081
- console.log(chalk23.dim(`No tasks for parent: ${query}`));
11132
+ console.log(chalk24.dim(`No tasks for parent: ${query}`));
11082
11133
  return;
11083
11134
  }
11084
- console.log(chalk23.bold(`
11135
+ console.log(chalk24.bold(`
11085
11136
  \u{1F4CB} ${query} (${tasks.length} tasks)
11086
11137
  `));
11087
11138
  const allTasks = await service.readAll();
@@ -11089,11 +11140,11 @@ function createTaskShowCommand() {
11089
11140
  for (const task of tasks) {
11090
11141
  const isBlocked = task.status === "todo" && task.depends_on.length > 0 && !task.depends_on.every((id) => doneIds.has(id));
11091
11142
  const icon = isBlocked ? BLOCKED_ICON : STATUS_ICONS[task.status] || "\u{1F4CB}";
11092
- let line = ` ${icon} ${chalk23.dim(task.id)} P${task.priority} ${task.title}`;
11093
- if (task.assigned_to) line += chalk23.cyan(` @${task.assigned_to}`);
11143
+ let line = ` ${icon} ${chalk24.dim(task.id)} P${task.priority} ${task.title}`;
11144
+ if (task.assigned_to) line += chalk24.cyan(` @${task.assigned_to}`);
11094
11145
  if (isBlocked) {
11095
11146
  const bb = task.depends_on.filter((id) => !doneIds.has(id));
11096
- line += chalk23.red(` (blocked: ${bb.join(", ")})`);
11147
+ line += chalk24.red(` (blocked: ${bb.join(", ")})`);
11097
11148
  }
11098
11149
  console.log(line);
11099
11150
  }
@@ -11103,11 +11154,11 @@ function createTaskShowCommand() {
11103
11154
  }
11104
11155
 
11105
11156
  // src/commands/tasks/pick.ts
11106
- import { Command as Command51 } from "commander";
11107
- import chalk24 from "chalk";
11157
+ import { Command as Command52 } from "commander";
11158
+ import chalk25 from "chalk";
11108
11159
  import { confirm as confirm9 } from "@inquirer/prompts";
11109
11160
  function createTaskPickCommand() {
11110
- return new Command51("pick").description("Claim the next available task").option("-j, --json", "Output JSON").action(async (options) => {
11161
+ return new Command52("pick").description("Claim the next available task").option("-j, --json", "Output JSON").action(async (options) => {
11111
11162
  const service = new TaskService();
11112
11163
  const ready = await service.getReady();
11113
11164
  if (ready.length === 0) {
@@ -11115,8 +11166,8 @@ function createTaskPickCommand() {
11115
11166
  console.log(JSON.stringify({ picked: null, message: "No tasks ready" }));
11116
11167
  return;
11117
11168
  }
11118
- console.log(chalk24.dim("No tasks ready to pick."));
11119
- console.log(chalk24.dim('\u{1F4A1} Add tasks first: jai1 t add "..."'));
11169
+ console.log(chalk25.dim("No tasks ready to pick."));
11170
+ console.log(chalk25.dim('\u{1F4A1} Add tasks first: jai1 t add "..."'));
11120
11171
  return;
11121
11172
  }
11122
11173
  const top = ready[0];
@@ -11126,13 +11177,13 @@ function createTaskPickCommand() {
11126
11177
  console.log(JSON.stringify(picked2, null, 2));
11127
11178
  return;
11128
11179
  }
11129
- console.log(chalk24.bold("\n\u{1F4CC} Next available task:"));
11130
- console.log(` ${chalk24.bold(top.id)} P${top.priority}${icon} ${top.title}`);
11180
+ console.log(chalk25.bold("\n\u{1F4CC} Next available task:"));
11181
+ console.log(` ${chalk25.bold(top.id)} P${top.priority}${icon} ${top.title}`);
11131
11182
  if (top.parent) {
11132
- console.log(` ${chalk24.dim("Parent:")} ${top.parent}`);
11183
+ console.log(` ${chalk25.dim("Parent:")} ${top.parent}`);
11133
11184
  }
11134
11185
  if (ready.length > 1) {
11135
- console.log(chalk24.dim(`
11186
+ console.log(chalk25.dim(`
11136
11187
  +${ready.length - 1} more tasks ready`));
11137
11188
  }
11138
11189
  const proceed = await confirm9({
@@ -11140,20 +11191,20 @@ function createTaskPickCommand() {
11140
11191
  default: true
11141
11192
  });
11142
11193
  if (!proceed) {
11143
- console.log(chalk24.dim("\nCancelled."));
11194
+ console.log(chalk25.dim("\nCancelled."));
11144
11195
  return;
11145
11196
  }
11146
11197
  const picked = await service.pick(top.id);
11147
- console.log(chalk24.green(`
11198
+ console.log(chalk25.green(`
11148
11199
  \u2705 ${picked.id} assigned to @${picked.assigned_to}, status \u2192 in_progress`));
11149
11200
  });
11150
11201
  }
11151
11202
 
11152
11203
  // src/commands/tasks/done.ts
11153
- import { Command as Command52 } from "commander";
11154
- import chalk25 from "chalk";
11204
+ import { Command as Command53 } from "commander";
11205
+ import chalk26 from "chalk";
11155
11206
  function createTaskDoneCommand() {
11156
- return new Command52("done").description("Mark task as done").argument("<id>", "Task ID (e.g. T-001)").option("-j, --json", "Output JSON").action(async (id, options) => {
11207
+ return new Command53("done").description("Mark task as done").argument("<id>", "Task ID (e.g. T-001)").option("-j, --json", "Output JSON").action(async (id, options) => {
11157
11208
  const service = new TaskService();
11158
11209
  try {
11159
11210
  const task = await service.markDone(id);
@@ -11161,19 +11212,19 @@ function createTaskDoneCommand() {
11161
11212
  console.log(JSON.stringify(task, null, 2));
11162
11213
  return;
11163
11214
  }
11164
- console.log(chalk25.green(`\u2705 ${task.id}: ${task.title} \u2192 done`));
11215
+ console.log(chalk26.green(`\u2705 ${task.id}: ${task.title} \u2192 done`));
11165
11216
  } catch (error) {
11166
- console.error(chalk25.red(`\u274C ${error instanceof Error ? error.message : String(error)}`));
11217
+ console.error(chalk26.red(`\u274C ${error instanceof Error ? error.message : String(error)}`));
11167
11218
  process.exit(1);
11168
11219
  }
11169
11220
  });
11170
11221
  }
11171
11222
 
11172
11223
  // src/commands/tasks/dep.ts
11173
- import { Command as Command53 } from "commander";
11174
- import chalk26 from "chalk";
11224
+ import { Command as Command54 } from "commander";
11225
+ import chalk27 from "chalk";
11175
11226
  function createTaskDepCommand() {
11176
- return new Command53("dep").description("Add dependency: child depends on parent").argument("<childId>", "Child task ID (the one that waits)").argument("<parentId>", "Parent task ID (must be done first)").option("-j, --json", "Output JSON").action(async (childId, parentId, options) => {
11227
+ return new Command54("dep").description("Add dependency: child depends on parent").argument("<childId>", "Child task ID (the one that waits)").argument("<parentId>", "Parent task ID (must be done first)").option("-j, --json", "Output JSON").action(async (childId, parentId, options) => {
11177
11228
  const service = new TaskService();
11178
11229
  try {
11179
11230
  const task = await service.addDependency(childId, parentId);
@@ -11181,156 +11232,156 @@ function createTaskDepCommand() {
11181
11232
  console.log(JSON.stringify(task, null, 2));
11182
11233
  return;
11183
11234
  }
11184
- console.log(chalk26.green(`\u2705 ${childId} now depends on ${parentId}`));
11185
- console.log(chalk26.dim(` ${task.title} \u2192 waits for ${parentId}`));
11235
+ console.log(chalk27.green(`\u2705 ${childId} now depends on ${parentId}`));
11236
+ console.log(chalk27.dim(` ${task.title} \u2192 waits for ${parentId}`));
11186
11237
  } catch (error) {
11187
- console.error(chalk26.red(`\u274C ${error instanceof Error ? error.message : String(error)}`));
11238
+ console.error(chalk27.red(`\u274C ${error instanceof Error ? error.message : String(error)}`));
11188
11239
  process.exit(1);
11189
11240
  }
11190
11241
  });
11191
11242
  }
11192
11243
 
11193
11244
  // src/commands/tasks/sync.ts
11194
- import { Command as Command54 } from "commander";
11195
- import chalk27 from "chalk";
11245
+ import { Command as Command55 } from "commander";
11246
+ import chalk28 from "chalk";
11196
11247
  function createTaskSyncCommand() {
11197
- return new Command54("sync").description("Sync tasks with git (commit & push only tasks file)").option("--pull", "Pull and merge tasks from origin/main").option("--push", "Commit and push tasks file").action(async (options) => {
11248
+ return new Command55("sync").description("Sync tasks with git (commit & push only tasks file)").option("--pull", "Pull and merge tasks from origin/main").option("--push", "Commit and push tasks file").action(async (options) => {
11198
11249
  const service = new TaskService();
11199
11250
  if (options.pull) {
11200
- console.log(chalk27.dim("\u23F3 Pulling tasks from origin/main..."));
11251
+ console.log(chalk28.dim("\u23F3 Pulling tasks from origin/main..."));
11201
11252
  try {
11202
11253
  const result = await service.syncPull();
11203
- console.log(chalk27.green(`\u2705 Sync pull complete: ${result.merged} tasks merged`));
11254
+ console.log(chalk28.green(`\u2705 Sync pull complete: ${result.merged} tasks merged`));
11204
11255
  } catch (error) {
11205
- console.error(chalk27.red(`\u274C ${error instanceof Error ? error.message : String(error)}`));
11256
+ console.error(chalk28.red(`\u274C ${error instanceof Error ? error.message : String(error)}`));
11206
11257
  process.exit(1);
11207
11258
  }
11208
11259
  return;
11209
11260
  }
11210
- console.log(chalk27.dim("\u23F3 Syncing tasks to git..."));
11261
+ console.log(chalk28.dim("\u23F3 Syncing tasks to git..."));
11211
11262
  try {
11212
11263
  await service.syncPush();
11213
- console.log(chalk27.green("\u2705 Tasks synced to git"));
11264
+ console.log(chalk28.green("\u2705 Tasks synced to git"));
11214
11265
  } catch (error) {
11215
- console.error(chalk27.red(`\u274C ${error instanceof Error ? error.message : String(error)}`));
11266
+ console.error(chalk28.red(`\u274C ${error instanceof Error ? error.message : String(error)}`));
11216
11267
  process.exit(1);
11217
11268
  }
11218
11269
  });
11219
11270
  }
11220
11271
 
11221
11272
  // src/commands/tasks/guide.ts
11222
- import { Command as Command55 } from "commander";
11223
- import chalk28 from "chalk";
11273
+ import { Command as Command56 } from "commander";
11274
+ import chalk29 from "chalk";
11224
11275
  var GUIDE_TEXT = `
11225
- ${chalk28.cyan.bold("\u{1F4D6} Jai1 Task Management Guide")}
11226
-
11227
- ${chalk28.bold("\u2501\u2501\u2501 STATUSES \u2501\u2501\u2501")}
11228
- ${chalk28.dim("todo")} \u{1F4CB} Ch\u01B0a b\u1EAFt \u0111\u1EA7u
11229
- ${chalk28.dim("in_progress")} \u{1F535} \u0110ang l\xE0m (bao g\u1ED3m review)
11230
- ${chalk28.dim("done")} \u2705 Ho\xE0n th\xE0nh
11231
- ${chalk28.dim("cancelled")} \u26AB Hu\u1EF7
11232
- ${chalk28.dim("(blocked)")} \u{1F534} Computed: depends_on ch\u01B0a done
11233
-
11234
- ${chalk28.bold("\u2501\u2501\u2501 PRIORITY \u2501\u2501\u2501")}
11235
- ${chalk28.dim("0")} = \u{1F525} Critical \u2014 Prod down, security, block c\u1EA3 team
11236
- ${chalk28.dim("1")} = \u{1F534} High \u2014 Feature ch\xEDnh, deadline g\u1EA7n
11237
- ${chalk28.dim("2")} = \u{1F7E1} Medium \u2014 B\xECnh th\u01B0\u1EDDng (default)
11238
- ${chalk28.dim("3")} = \u{1F7E2} Low \u2014 Nice-to-have, docs, refactor
11239
-
11240
- ${chalk28.bold("\u2501\u2501\u2501 QUICK START \u2501\u2501\u2501")}
11241
- ${chalk28.cyan("jai1 t add")} "Fix login bug" -p 1 -P bug/login
11242
- ${chalk28.cyan("jai1 t ready")} Show tasks s\u1EB5n s\xE0ng
11243
- ${chalk28.cyan("jai1 t pick")} Claim & start working
11244
- ${chalk28.cyan("jai1 t done")} T-003 Mark complete
11245
-
11246
- ${chalk28.bold("\u2501\u2501\u2501 DAILY WORKFLOW \u2501\u2501\u2501")}
11247
- ${chalk28.cyan("jai1 t sync --pull")} Pull latest tasks
11248
- ${chalk28.cyan("jai1 t summary")} Dashboard t\u1ED5ng quan
11249
- ${chalk28.cyan("jai1 t ready")} Xem tasks s\u1EB5n s\xE0ng
11250
- ${chalk28.cyan("jai1 t pick")} Claim task m\u1EDBi
11251
- ${chalk28.cyan("jai1 t done")} T-xxx Ho\xE0n th\xE0nh task
11252
- ${chalk28.cyan("jai1 t sync --push")} Push l\xEAn git
11253
-
11254
- ${chalk28.bold("\u2501\u2501\u2501 ADDING TASKS \u2501\u2501\u2501")}
11255
- ${chalk28.yellow("\u26A0 Lu\xF4n ki\u1EC3m tra duplicate tr\u01B0\u1EDBc khi add:")}
11256
- ${chalk28.cyan("jai1 t list -P")} feature/xxx
11257
-
11258
- ${chalk28.dim("Add cho feature:")}
11259
- ${chalk28.cyan("jai1 t add")} "Setup DB schema" -p 1 -P feature/xxx
11260
- ${chalk28.cyan("jai1 t add")} "Create API" -p 1 -P feature/xxx
11261
- ${chalk28.cyan("jai1 t add")} "Build UI" -p 2 -P feature/xxx
11262
-
11263
- ${chalk28.dim("Add cho plan:")}
11264
- ${chalk28.cyan("jai1 t add")} "Refactor middleware" -p 2 -P plan/xxx
11265
-
11266
- ${chalk28.dim("Add standalone:")}
11267
- ${chalk28.cyan("jai1 t add")} "Fix README typo" -p 3
11268
-
11269
- ${chalk28.dim("Add bug fix:")}
11270
- ${chalk28.cyan("jai1 t add")} "Fix login redirect" -p 1 -P bug/xxx
11271
-
11272
- ${chalk28.bold("\u2501\u2501\u2501 DEPENDENCY \u2501\u2501\u2501")}
11273
- ${chalk28.dim("Task dependency:")}
11274
- ${chalk28.cyan("jai1 t dep")} T-002 T-001 T-002 ch\u1EDD T-001 done
11275
- ${chalk28.cyan("jai1 t dep")} T-003 T-002 T-003 ch\u1EDD T-002 done
11276
-
11277
- ${chalk28.dim("Feature-level dependency:")}
11278
- ${chalk28.dim("# N\u1EBFu feature/auth ph\u1EE5 thu\u1ED9c feature/user-model:")}
11279
- ${chalk28.cyan("jai1 t add")} "[DEP] Wait for feature/user-model" -p 1 -P feature/auth
11280
- ${chalk28.dim("# R\u1ED3i dep n\xF3 v\u1EDBi tasks cu\u1ED1i c\u1EE7a user-model")}
11281
-
11282
- ${chalk28.dim("View deps:")}
11283
- ${chalk28.cyan("jai1 t show")} T-002 Hi\u1EC7n depends_on
11284
-
11285
- ${chalk28.bold("\u2501\u2501\u2501 TEAM COLLABORATION \u2501\u2501\u2501")}
11286
- ${chalk28.yellow("\u26A0 Assignment ch\u1EC9 qua pick \u2014 kh\xF4ng set th\u1EE7 c\xF4ng.")}
11287
- ${chalk28.dim("Khi b\u1EA1n pick \u2192 team th\u1EA5y task \u0111\xE3 c\xF3 ng\u01B0\u1EDDi nh\u1EADn.")}
11288
-
11289
- ${chalk28.dim("Sync morning:")} ${chalk28.cyan("jai1 t sync --pull")}
11290
- ${chalk28.dim("Sync evening:")} ${chalk28.cyan("jai1 t sync --push")}
11291
-
11292
- ${chalk28.bold("\u2501\u2501\u2501 FOR AI AGENTS (Workflow Integration) \u2501\u2501\u2501")}
11293
- ${chalk28.dim("Khi t\u1EA1o tasks t\u1EEB feature/plan:")}
11294
- 1. ${chalk28.cyan("jai1 t list -P")} <parent> Check existing (tr\xE1nh duplicate)
11295
- 2. ${chalk28.cyan("jai1 t add")} "..." -p <0-3> -P <parent> Add t\u1EEBng task
11296
- 3. ${chalk28.cyan("jai1 t dep")} <child> <parent> Set dependencies
11297
- 4. ${chalk28.cyan("jai1 t done")} <id> Mark complete
11298
-
11299
- ${chalk28.dim("Khi implement task ti\u1EBFp theo:")}
11300
- 1. ${chalk28.cyan("jai1 t pick")} (ho\u1EB7c ${chalk28.cyan("jai1 t ready -P")} <parent>)
11276
+ ${chalk29.cyan.bold("\u{1F4D6} Jai1 Task Management Guide")}
11277
+
11278
+ ${chalk29.bold("\u2501\u2501\u2501 STATUSES \u2501\u2501\u2501")}
11279
+ ${chalk29.dim("todo")} \u{1F4CB} Ch\u01B0a b\u1EAFt \u0111\u1EA7u
11280
+ ${chalk29.dim("in_progress")} \u{1F535} \u0110ang l\xE0m (bao g\u1ED3m review)
11281
+ ${chalk29.dim("done")} \u2705 Ho\xE0n th\xE0nh
11282
+ ${chalk29.dim("cancelled")} \u26AB Hu\u1EF7
11283
+ ${chalk29.dim("(blocked)")} \u{1F534} Computed: depends_on ch\u01B0a done
11284
+
11285
+ ${chalk29.bold("\u2501\u2501\u2501 PRIORITY \u2501\u2501\u2501")}
11286
+ ${chalk29.dim("0")} = \u{1F525} Critical \u2014 Prod down, security, block c\u1EA3 team
11287
+ ${chalk29.dim("1")} = \u{1F534} High \u2014 Feature ch\xEDnh, deadline g\u1EA7n
11288
+ ${chalk29.dim("2")} = \u{1F7E1} Medium \u2014 B\xECnh th\u01B0\u1EDDng (default)
11289
+ ${chalk29.dim("3")} = \u{1F7E2} Low \u2014 Nice-to-have, docs, refactor
11290
+
11291
+ ${chalk29.bold("\u2501\u2501\u2501 QUICK START \u2501\u2501\u2501")}
11292
+ ${chalk29.cyan("jai1 t add")} "Fix login bug" -p 1 -P bug/login
11293
+ ${chalk29.cyan("jai1 t ready")} Show tasks s\u1EB5n s\xE0ng
11294
+ ${chalk29.cyan("jai1 t pick")} Claim & start working
11295
+ ${chalk29.cyan("jai1 t done")} T-003 Mark complete
11296
+
11297
+ ${chalk29.bold("\u2501\u2501\u2501 DAILY WORKFLOW \u2501\u2501\u2501")}
11298
+ ${chalk29.cyan("jai1 t sync --pull")} Pull latest tasks
11299
+ ${chalk29.cyan("jai1 t summary")} Dashboard t\u1ED5ng quan
11300
+ ${chalk29.cyan("jai1 t ready")} Xem tasks s\u1EB5n s\xE0ng
11301
+ ${chalk29.cyan("jai1 t pick")} Claim task m\u1EDBi
11302
+ ${chalk29.cyan("jai1 t done")} T-xxx Ho\xE0n th\xE0nh task
11303
+ ${chalk29.cyan("jai1 t sync --push")} Push l\xEAn git
11304
+
11305
+ ${chalk29.bold("\u2501\u2501\u2501 ADDING TASKS \u2501\u2501\u2501")}
11306
+ ${chalk29.yellow("\u26A0 Lu\xF4n ki\u1EC3m tra duplicate tr\u01B0\u1EDBc khi add:")}
11307
+ ${chalk29.cyan("jai1 t list -P")} feature/xxx
11308
+
11309
+ ${chalk29.dim("Add cho feature:")}
11310
+ ${chalk29.cyan("jai1 t add")} "Setup DB schema" -p 1 -P feature/xxx
11311
+ ${chalk29.cyan("jai1 t add")} "Create API" -p 1 -P feature/xxx
11312
+ ${chalk29.cyan("jai1 t add")} "Build UI" -p 2 -P feature/xxx
11313
+
11314
+ ${chalk29.dim("Add cho plan:")}
11315
+ ${chalk29.cyan("jai1 t add")} "Refactor middleware" -p 2 -P plan/xxx
11316
+
11317
+ ${chalk29.dim("Add standalone:")}
11318
+ ${chalk29.cyan("jai1 t add")} "Fix README typo" -p 3
11319
+
11320
+ ${chalk29.dim("Add bug fix:")}
11321
+ ${chalk29.cyan("jai1 t add")} "Fix login redirect" -p 1 -P bug/xxx
11322
+
11323
+ ${chalk29.bold("\u2501\u2501\u2501 DEPENDENCY \u2501\u2501\u2501")}
11324
+ ${chalk29.dim("Task dependency:")}
11325
+ ${chalk29.cyan("jai1 t dep")} T-002 T-001 T-002 ch\u1EDD T-001 done
11326
+ ${chalk29.cyan("jai1 t dep")} T-003 T-002 T-003 ch\u1EDD T-002 done
11327
+
11328
+ ${chalk29.dim("Feature-level dependency:")}
11329
+ ${chalk29.dim("# N\u1EBFu feature/auth ph\u1EE5 thu\u1ED9c feature/user-model:")}
11330
+ ${chalk29.cyan("jai1 t add")} "[DEP] Wait for feature/user-model" -p 1 -P feature/auth
11331
+ ${chalk29.dim("# R\u1ED3i dep n\xF3 v\u1EDBi tasks cu\u1ED1i c\u1EE7a user-model")}
11332
+
11333
+ ${chalk29.dim("View deps:")}
11334
+ ${chalk29.cyan("jai1 t show")} T-002 Hi\u1EC7n depends_on
11335
+
11336
+ ${chalk29.bold("\u2501\u2501\u2501 TEAM COLLABORATION \u2501\u2501\u2501")}
11337
+ ${chalk29.yellow("\u26A0 Assignment ch\u1EC9 qua pick \u2014 kh\xF4ng set th\u1EE7 c\xF4ng.")}
11338
+ ${chalk29.dim("Khi b\u1EA1n pick \u2192 team th\u1EA5y task \u0111\xE3 c\xF3 ng\u01B0\u1EDDi nh\u1EADn.")}
11339
+
11340
+ ${chalk29.dim("Sync morning:")} ${chalk29.cyan("jai1 t sync --pull")}
11341
+ ${chalk29.dim("Sync evening:")} ${chalk29.cyan("jai1 t sync --push")}
11342
+
11343
+ ${chalk29.bold("\u2501\u2501\u2501 FOR AI AGENTS (Workflow Integration) \u2501\u2501\u2501")}
11344
+ ${chalk29.dim("Khi t\u1EA1o tasks t\u1EEB feature/plan:")}
11345
+ 1. ${chalk29.cyan("jai1 t list -P")} <parent> Check existing (tr\xE1nh duplicate)
11346
+ 2. ${chalk29.cyan("jai1 t add")} "..." -p <0-3> -P <parent> Add t\u1EEBng task
11347
+ 3. ${chalk29.cyan("jai1 t dep")} <child> <parent> Set dependencies
11348
+ 4. ${chalk29.cyan("jai1 t done")} <id> Mark complete
11349
+
11350
+ ${chalk29.dim("Khi implement task ti\u1EBFp theo:")}
11351
+ 1. ${chalk29.cyan("jai1 t pick")} (ho\u1EB7c ${chalk29.cyan("jai1 t ready -P")} <parent>)
11301
11352
  2. Implement task
11302
- 3. ${chalk28.cyan("jai1 t done")} <id>
11353
+ 3. ${chalk29.cyan("jai1 t done")} <id>
11303
11354
 
11304
- ${chalk28.dim("Status transitions:")}
11355
+ ${chalk29.dim("Status transitions:")}
11305
11356
  add \u2192 todo (default)
11306
11357
  pick \u2192 in_progress (auto assign)
11307
11358
  done \u2192 done
11308
11359
  update -s \u2192 any valid status
11309
11360
 
11310
- ${chalk28.bold("\u2501\u2501\u2501 ALL COMMANDS \u2501\u2501\u2501")}
11311
- ${chalk28.cyan("jai1 t list")} [-s status] [-P parent] [-j]
11312
- ${chalk28.cyan("jai1 t ready")} [-P parent] [-j]
11313
- ${chalk28.cyan("jai1 t add")} <title> [-p 0-3] [-P parent] [-t tags] [-j]
11314
- ${chalk28.cyan("jai1 t update")} <id> [-s <status>] [-n <notes>] [-j]
11315
- ${chalk28.cyan("jai1 t show")} <id|parent> [-j]
11316
- ${chalk28.cyan("jai1 t pick")} [-j]
11317
- ${chalk28.cyan("jai1 t done")} <id> [-j]
11318
- ${chalk28.cyan("jai1 t dep")} <childId> <parentId> [-j]
11319
- ${chalk28.cyan("jai1 t sync")} [--pull] [--push]
11320
- ${chalk28.cyan("jai1 t summary")} [-j]
11321
- ${chalk28.cyan("jai1 t guide")}
11322
-
11323
- ${chalk28.dim("-j / --json available on all commands (except guide, sync)")}
11361
+ ${chalk29.bold("\u2501\u2501\u2501 ALL COMMANDS \u2501\u2501\u2501")}
11362
+ ${chalk29.cyan("jai1 t list")} [-s status] [-P parent] [-j]
11363
+ ${chalk29.cyan("jai1 t ready")} [-P parent] [-j]
11364
+ ${chalk29.cyan("jai1 t add")} <title> [-p 0-3] [-P parent] [-t tags] [-j]
11365
+ ${chalk29.cyan("jai1 t update")} <id> [-s <status>] [-n <notes>] [-j]
11366
+ ${chalk29.cyan("jai1 t show")} <id|parent> [-j]
11367
+ ${chalk29.cyan("jai1 t pick")} [-j]
11368
+ ${chalk29.cyan("jai1 t done")} <id> [-j]
11369
+ ${chalk29.cyan("jai1 t dep")} <childId> <parentId> [-j]
11370
+ ${chalk29.cyan("jai1 t sync")} [--pull] [--push]
11371
+ ${chalk29.cyan("jai1 t summary")} [-j]
11372
+ ${chalk29.cyan("jai1 t guide")}
11373
+
11374
+ ${chalk29.dim("-j / --json available on all commands (except guide, sync)")}
11324
11375
  `;
11325
11376
  function createTaskGuideCommand() {
11326
- return new Command55("guide").description("Show full task management guide").action(() => {
11377
+ return new Command56("guide").description("Show full task management guide").action(() => {
11327
11378
  console.log(GUIDE_TEXT);
11328
11379
  });
11329
11380
  }
11330
11381
 
11331
11382
  // src/commands/tasks/index.ts
11332
11383
  function createTasksCommand() {
11333
- const cmd = new Command56("tasks").alias("t").description("Task management \u2014 track, assign, and manage development tasks").hook("preAction", (thisCommand, actionCommand) => {
11384
+ const cmd = new Command57("tasks").alias("t").description("Task management \u2014 track, assign, and manage development tasks").hook("preAction", (thisCommand, actionCommand) => {
11334
11385
  if (actionCommand.name() !== "guide") {
11335
11386
  TaskService.ensureJai1Dir();
11336
11387
  }
@@ -11354,12 +11405,12 @@ function createTasksCommand() {
11354
11405
  }
11355
11406
 
11356
11407
  // src/commands/kit/index.ts
11357
- import { Command as Command60 } from "commander";
11358
- import chalk30 from "chalk";
11408
+ import { Command as Command61 } from "commander";
11409
+ import chalk31 from "chalk";
11359
11410
 
11360
11411
  // src/commands/kit/list.ts
11361
- import { Command as Command57 } from "commander";
11362
- import chalk29 from "chalk";
11412
+ import { Command as Command58 } from "commander";
11413
+ import chalk30 from "chalk";
11363
11414
  import Table6 from "cli-table3";
11364
11415
 
11365
11416
  // src/services/starter-kit.service.ts
@@ -11427,13 +11478,13 @@ var StarterKitService = class {
11427
11478
 
11428
11479
  // src/commands/kit/list.ts
11429
11480
  function createKitListCommand() {
11430
- return new Command57("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) => {
11481
+ return new Command58("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) => {
11431
11482
  const configService = new ConfigService();
11432
11483
  const config = await configService.load();
11433
11484
  if (!config) {
11434
11485
  throw new ValidationError('Not initialized. Run "jai1 auth" first.');
11435
11486
  }
11436
- console.log(chalk29.cyan("\u{1F4E6} \u0110ang t\u1EA3i danh s\xE1ch starter kits..."));
11487
+ console.log(chalk30.cyan("\u{1F4E6} \u0110ang t\u1EA3i danh s\xE1ch starter kits..."));
11437
11488
  console.log();
11438
11489
  const kitService = new StarterKitService();
11439
11490
  const kits = await kitService.list(config, {
@@ -11441,9 +11492,9 @@ function createKitListCommand() {
11441
11492
  search: options.search
11442
11493
  });
11443
11494
  if (kits.length === 0) {
11444
- console.log(chalk29.yellow("Kh\xF4ng t\xECm th\u1EA5y starter kits n\xE0o."));
11495
+ console.log(chalk30.yellow("Kh\xF4ng t\xECm th\u1EA5y starter kits n\xE0o."));
11445
11496
  if (options.category || options.search) {
11446
- console.log(chalk29.dim("Th\u1EED b\u1ECF filter \u0111\u1EC3 xem t\u1EA5t c\u1EA3."));
11497
+ console.log(chalk30.dim("Th\u1EED b\u1ECF filter \u0111\u1EC3 xem t\u1EA5t c\u1EA3."));
11447
11498
  }
11448
11499
  return;
11449
11500
  }
@@ -11467,35 +11518,35 @@ function createKitListCommand() {
11467
11518
  const categoryKits = byCategory[category];
11468
11519
  const categoryIcon = category === "frontend" ? "\u{1F3A8}" : category === "backend" ? "\u2699\uFE0F" : category === "fullstack" ? "\u{1F680}" : "\u{1F4E6}";
11469
11520
  console.log(
11470
- chalk29.bold(`${categoryIcon} ${category.charAt(0).toUpperCase() + category.slice(1)}`)
11521
+ chalk30.bold(`${categoryIcon} ${category.charAt(0).toUpperCase() + category.slice(1)}`)
11471
11522
  );
11472
11523
  const table = new Table6({
11473
11524
  head: [
11474
- chalk29.cyan("Slug"),
11475
- chalk29.cyan("M\xF4 t\u1EA3"),
11476
- chalk29.cyan("Version")
11525
+ chalk30.cyan("Slug"),
11526
+ chalk30.cyan("M\xF4 t\u1EA3"),
11527
+ chalk30.cyan("Version")
11477
11528
  ],
11478
11529
  style: { head: [], border: ["gray"] }
11479
11530
  });
11480
11531
  for (const kit of categoryKits) {
11481
11532
  table.push([
11482
- chalk29.white(kit.slug),
11483
- chalk29.dim(kit.description.slice(0, 50)),
11484
- chalk29.green(`v${kit.version}`)
11533
+ chalk30.white(kit.slug),
11534
+ chalk30.dim(kit.description.slice(0, 50)),
11535
+ chalk30.green(`v${kit.version}`)
11485
11536
  ]);
11486
11537
  }
11487
11538
  console.log(table.toString());
11488
11539
  console.log();
11489
11540
  }
11490
- console.log(chalk29.dim(`T\u1ED5ng c\u1ED9ng: ${kits.length} starter kit(s)`));
11491
- console.log(chalk29.dim('\n\u{1F4A1} Ch\u1EA1y "jai1 kit create <slug>" \u0111\u1EC3 t\u1EA1o project m\u1EDBi'));
11541
+ console.log(chalk30.dim(`T\u1ED5ng c\u1ED9ng: ${kits.length} starter kit(s)`));
11542
+ console.log(chalk30.dim('\n\u{1F4A1} Ch\u1EA1y "jai1 kit create <slug>" \u0111\u1EC3 t\u1EA1o project m\u1EDBi'));
11492
11543
  });
11493
11544
  }
11494
11545
 
11495
11546
  // src/commands/kit/info.ts
11496
- import { Command as Command58 } from "commander";
11547
+ import { Command as Command59 } from "commander";
11497
11548
  function createKitInfoCommand() {
11498
- return new Command58("info").description("Show detailed information about a starter kit").argument("<slug>", "Starter kit slug").action(async (slug) => {
11549
+ return new Command59("info").description("Show detailed information about a starter kit").argument("<slug>", "Starter kit slug").action(async (slug) => {
11499
11550
  const configService = new ConfigService();
11500
11551
  const config = await configService.load();
11501
11552
  if (!config) {
@@ -11544,7 +11595,7 @@ Post-Init Commands:`);
11544
11595
  }
11545
11596
 
11546
11597
  // src/commands/kit/create.ts
11547
- import { Command as Command59 } from "commander";
11598
+ import { Command as Command60 } from "commander";
11548
11599
  import { promises as fs21 } from "fs";
11549
11600
  import { join as join11 } from "path";
11550
11601
  import { select as select3, input as input2, checkbox as checkbox4 } from "@inquirer/prompts";
@@ -11589,7 +11640,7 @@ var HookExecutor = class {
11589
11640
 
11590
11641
  // src/commands/kit/create.ts
11591
11642
  function createKitCreateCommand() {
11592
- return new Command59("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) => {
11643
+ return new Command60("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) => {
11593
11644
  const configService = new ConfigService();
11594
11645
  const config = await configService.load();
11595
11646
  if (!config) {
@@ -11768,23 +11819,23 @@ async function getAllFiles(dir) {
11768
11819
 
11769
11820
  // src/commands/kit/index.ts
11770
11821
  function showKitHelp() {
11771
- console.log(chalk30.bold.cyan("\u{1F4E6} jai1 kit") + chalk30.dim(" - Qu\u1EA3n l\xFD starter kits"));
11822
+ console.log(chalk31.bold.cyan("\u{1F4E6} jai1 kit") + chalk31.dim(" - Qu\u1EA3n l\xFD starter kits"));
11772
11823
  console.log();
11773
- console.log(chalk30.bold("C\xE1c l\u1EC7nh:"));
11774
- console.log(` ${chalk30.cyan("list")} Li\u1EC7t k\xEA c\xE1c starter kits c\xF3 s\u1EB5n`);
11775
- console.log(` ${chalk30.cyan("info")} Xem chi ti\u1EBFt m\u1ED9t starter kit`);
11776
- console.log(` ${chalk30.cyan("create")} T\u1EA1o project m\u1EDBi t\u1EEB starter kit`);
11824
+ console.log(chalk31.bold("C\xE1c l\u1EC7nh:"));
11825
+ console.log(` ${chalk31.cyan("list")} Li\u1EC7t k\xEA c\xE1c starter kits c\xF3 s\u1EB5n`);
11826
+ console.log(` ${chalk31.cyan("info")} Xem chi ti\u1EBFt m\u1ED9t starter kit`);
11827
+ console.log(` ${chalk31.cyan("create")} T\u1EA1o project m\u1EDBi t\u1EEB starter kit`);
11777
11828
  console.log();
11778
- console.log(chalk30.bold("V\xED d\u1EE5:"));
11779
- console.log(chalk30.dim(" $ jai1 kit list"));
11780
- console.log(chalk30.dim(" $ jai1 kit list --category frontend"));
11781
- console.log(chalk30.dim(" $ jai1 kit info next-tw4-shadcn"));
11782
- console.log(chalk30.dim(" $ jai1 kit create next-tw4-shadcn my-project"));
11829
+ console.log(chalk31.bold("V\xED d\u1EE5:"));
11830
+ console.log(chalk31.dim(" $ jai1 kit list"));
11831
+ console.log(chalk31.dim(" $ jai1 kit list --category frontend"));
11832
+ console.log(chalk31.dim(" $ jai1 kit info next-tw4-shadcn"));
11833
+ console.log(chalk31.dim(" $ jai1 kit create next-tw4-shadcn my-project"));
11783
11834
  console.log();
11784
- console.log(chalk30.dim('Ch\u1EA1y "jai1 kit <l\u1EC7nh> --help" \u0111\u1EC3 xem chi ti\u1EBFt'));
11835
+ console.log(chalk31.dim('Ch\u1EA1y "jai1 kit <l\u1EC7nh> --help" \u0111\u1EC3 xem chi ti\u1EBFt'));
11785
11836
  }
11786
11837
  function createKitCommand() {
11787
- const cmd = new Command60("kit").description("Manage starter kits for new projects").action(() => {
11838
+ const cmd = new Command61("kit").description("Manage starter kits for new projects").action(() => {
11788
11839
  showKitHelp();
11789
11840
  });
11790
11841
  cmd.addCommand(createKitListCommand());
@@ -11794,21 +11845,21 @@ function createKitCommand() {
11794
11845
  }
11795
11846
 
11796
11847
  // src/commands/rules/index.ts
11797
- import { Command as Command67 } from "commander";
11798
- import chalk32 from "chalk";
11848
+ import { Command as Command68 } from "commander";
11849
+ import chalk33 from "chalk";
11799
11850
 
11800
11851
  // src/commands/rules/list.ts
11801
- import { Command as Command61 } from "commander";
11802
- import chalk31 from "chalk";
11852
+ import { Command as Command62 } from "commander";
11853
+ import chalk32 from "chalk";
11803
11854
  import Table7 from "cli-table3";
11804
11855
  function createRulesListCommand() {
11805
- return new Command61("list").description("List available rule presets").option("--json", "Output as JSON").action(async (options) => {
11856
+ return new Command62("list").description("List available rule presets").option("--json", "Output as JSON").action(async (options) => {
11806
11857
  const configService = new ConfigService();
11807
11858
  const config = await configService.load();
11808
11859
  if (!config) {
11809
11860
  throw new ValidationError('Not initialized. Run "jai1 auth" first.');
11810
11861
  }
11811
- console.log(chalk31.cyan("\u{1F4CB} \u0110ang t\u1EA3i danh s\xE1ch rule presets..."));
11862
+ console.log(chalk32.cyan("\u{1F4CB} \u0110ang t\u1EA3i danh s\xE1ch rule presets..."));
11812
11863
  console.log();
11813
11864
  try {
11814
11865
  const response = await fetch(`${config.apiUrl}/api/rules/presets`, {
@@ -11825,23 +11876,23 @@ function createRulesListCommand() {
11825
11876
  return;
11826
11877
  }
11827
11878
  if (data.total === 0) {
11828
- console.log(chalk31.yellow("Kh\xF4ng c\xF3 presets n\xE0o."));
11879
+ console.log(chalk32.yellow("Kh\xF4ng c\xF3 presets n\xE0o."));
11829
11880
  return;
11830
11881
  }
11831
11882
  console.log(
11832
- chalk31.green(`\u2713 T\xECm th\u1EA5y ${chalk31.bold(data.total)} preset${data.total > 1 ? "s" : ""}`)
11883
+ chalk32.green(`\u2713 T\xECm th\u1EA5y ${chalk32.bold(data.total)} preset${data.total > 1 ? "s" : ""}`)
11833
11884
  );
11834
11885
  console.log();
11835
11886
  for (const preset of data.presets) {
11836
- console.log(chalk31.bold.cyan(`\u{1F4E6} ${preset.slug}`));
11887
+ console.log(chalk32.bold.cyan(`\u{1F4E6} ${preset.slug}`));
11837
11888
  const table = new Table7({
11838
11889
  style: { head: [], border: ["gray"], compact: true },
11839
11890
  colWidths: [15, 55]
11840
11891
  });
11841
11892
  table.push(
11842
- [chalk31.dim("T\xEAn"), chalk31.white(preset.name)],
11843
- [chalk31.dim("M\xF4 t\u1EA3"), chalk31.white(preset.description)],
11844
- [chalk31.dim("Version"), chalk31.green(`v${preset.version}`)]
11893
+ [chalk32.dim("T\xEAn"), chalk32.white(preset.name)],
11894
+ [chalk32.dim("M\xF4 t\u1EA3"), chalk32.white(preset.description)],
11895
+ [chalk32.dim("Version"), chalk32.green(`v${preset.version}`)]
11845
11896
  );
11846
11897
  const stackParts = [];
11847
11898
  if (preset.stack.frontend) stackParts.push(preset.stack.frontend);
@@ -11849,16 +11900,16 @@ function createRulesListCommand() {
11849
11900
  if (preset.stack.css) stackParts.push(preset.stack.css);
11850
11901
  if (preset.stack.database) stackParts.push(preset.stack.database);
11851
11902
  if (stackParts.length > 0) {
11852
- table.push([chalk31.dim("Stack"), chalk31.yellow(stackParts.join(" + "))]);
11903
+ table.push([chalk32.dim("Stack"), chalk32.yellow(stackParts.join(" + "))]);
11853
11904
  }
11854
11905
  table.push(
11855
- [chalk31.dim("Tags"), chalk31.dim(preset.tags.join(", ") || "-")],
11856
- [chalk31.dim("Downloads"), chalk31.white(preset.downloads.toString())]
11906
+ [chalk32.dim("Tags"), chalk32.dim(preset.tags.join(", ") || "-")],
11907
+ [chalk32.dim("Downloads"), chalk32.white(preset.downloads.toString())]
11857
11908
  );
11858
11909
  console.log(table.toString());
11859
11910
  console.log();
11860
11911
  }
11861
- console.log(chalk31.dim('\u{1F4A1} Ch\u1EA1y "jai1 rules apply <name>" \u0111\u1EC3 \xE1p d\u1EE5ng preset'));
11912
+ console.log(chalk32.dim('\u{1F4A1} Ch\u1EA1y "jai1 rules apply <name>" \u0111\u1EC3 \xE1p d\u1EE5ng preset'));
11862
11913
  } catch (error) {
11863
11914
  throw new Error(
11864
11915
  `L\u1ED7i khi t\u1EA3i presets: ${error instanceof Error ? error.message : String(error)}`
@@ -11868,7 +11919,7 @@ function createRulesListCommand() {
11868
11919
  }
11869
11920
 
11870
11921
  // src/commands/rules/init.ts
11871
- import { Command as Command62 } from "commander";
11922
+ import { Command as Command63 } from "commander";
11872
11923
  import { promises as fs23 } from "fs";
11873
11924
  import { join as join13 } from "path";
11874
11925
  import { select as select4, confirm as confirm10 } from "@inquirer/prompts";
@@ -11993,7 +12044,7 @@ var ProjectConfigService = class {
11993
12044
 
11994
12045
  // src/commands/rules/init.ts
11995
12046
  function createRulesInitCommand() {
11996
- return new Command62("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) => {
12047
+ return new Command63("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) => {
11997
12048
  const configService = new ConfigService();
11998
12049
  const config = await configService.load();
11999
12050
  if (!config) {
@@ -12125,7 +12176,7 @@ async function applyAgentsMdFormat(bundle) {
12125
12176
  }
12126
12177
 
12127
12178
  // src/commands/rules/apply.ts
12128
- import { Command as Command63 } from "commander";
12179
+ import { Command as Command64 } from "commander";
12129
12180
  import { promises as fs25 } from "fs";
12130
12181
  import { join as join15 } from "path";
12131
12182
  import { search, confirm as confirm11, checkbox as checkbox5 } from "@inquirer/prompts";
@@ -12639,7 +12690,7 @@ Restoring backup from ${metadata.timestamp}...`);
12639
12690
 
12640
12691
  // src/commands/rules/apply.ts
12641
12692
  function createRulesApplyCommand() {
12642
- return new Command63("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) => {
12693
+ return new Command64("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) => {
12643
12694
  const configService = new ConfigService();
12644
12695
  const config = await configService.load();
12645
12696
  if (!config) {
@@ -12934,11 +12985,11 @@ function createRulesApplyCommand() {
12934
12985
  }
12935
12986
 
12936
12987
  // src/commands/rules/restore.ts
12937
- import { Command as Command64 } from "commander";
12988
+ import { Command as Command65 } from "commander";
12938
12989
  import { join as join16 } from "path";
12939
12990
  import { select as select5, confirm as confirm12 } from "@inquirer/prompts";
12940
12991
  function createRulesRestoreCommand() {
12941
- return new Command64("restore").description("Restore rules from a backup").option("--latest", "Restore the most recent backup").option("-y, --yes", "Skip confirmation").action(async (options) => {
12992
+ return new Command65("restore").description("Restore rules from a backup").option("--latest", "Restore the most recent backup").option("-y, --yes", "Skip confirmation").action(async (options) => {
12942
12993
  const backupService = new BackupService();
12943
12994
  const backups = await backupService.listBackups();
12944
12995
  if (backups.length === 0) {
@@ -13007,12 +13058,12 @@ function formatTimestamp(timestamp) {
13007
13058
  }
13008
13059
 
13009
13060
  // src/commands/rules/sync.ts
13010
- import { Command as Command65 } from "commander";
13061
+ import { Command as Command66 } from "commander";
13011
13062
  import { promises as fs26 } from "fs";
13012
13063
  import { join as join17 } from "path";
13013
13064
  import { checkbox as checkbox6, confirm as confirm13, Separator } from "@inquirer/prompts";
13014
13065
  function createRulesSyncCommand() {
13015
- return new Command65("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) => {
13066
+ return new Command66("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) => {
13016
13067
  const rulePresetDir = join17(process.cwd(), ".jai1", "rule-preset");
13017
13068
  const presetJsonPath = join17(rulePresetDir, "preset.json");
13018
13069
  let presetExists = false;
@@ -13230,11 +13281,11 @@ function buildIdeChoices(currentIdes, detected, suggestions) {
13230
13281
  }
13231
13282
 
13232
13283
  // src/commands/rules/info.ts
13233
- import { Command as Command66 } from "commander";
13284
+ import { Command as Command67 } from "commander";
13234
13285
  import { promises as fs27 } from "fs";
13235
13286
  import { join as join18 } from "path";
13236
13287
  function createRulesInfoCommand() {
13237
- return new Command66("info").description("Show current preset information").option("--json", "Output as JSON").action(async (options) => {
13288
+ return new Command67("info").description("Show current preset information").option("--json", "Output as JSON").action(async (options) => {
13238
13289
  const projectConfigService = new ProjectConfigService();
13239
13290
  const rulesConfig = await projectConfigService.loadRules();
13240
13291
  if (!rulesConfig) {
@@ -13337,26 +13388,26 @@ async function checkIdeFilesExist(ideId, format) {
13337
13388
 
13338
13389
  // src/commands/rules/index.ts
13339
13390
  function showRulesHelp() {
13340
- console.log(chalk32.bold.cyan("\u{1F4CB} jai1 rules") + chalk32.dim(" - Qu\u1EA3n l\xFD rule presets cho AI agents"));
13391
+ console.log(chalk33.bold.cyan("\u{1F4CB} jai1 rules") + chalk33.dim(" - Qu\u1EA3n l\xFD rule presets cho AI agents"));
13341
13392
  console.log();
13342
- console.log(chalk32.bold("C\xE1c l\u1EC7nh:"));
13343
- console.log(` ${chalk32.cyan("list")} Li\u1EC7t k\xEA c\xE1c presets c\xF3 s\u1EB5n`);
13344
- console.log(` ${chalk32.cyan("info")} Xem chi ti\u1EBFt m\u1ED9t preset`);
13345
- console.log(` ${chalk32.cyan("init")} Kh\u1EDFi t\u1EA1o rules t\u1EEB preset`);
13346
- console.log(` ${chalk32.cyan("apply")} \xC1p d\u1EE5ng preset v\xE0o project`);
13347
- console.log(` ${chalk32.cyan("sync")} \u0110\u1ED3ng b\u1ED9 rules sang c\xE1c \u0111\u1ECBnh d\u1EA1ng IDE`);
13348
- console.log(` ${chalk32.cyan("restore")} Kh\xF4i ph\u1EE5c rules t\u1EEB backup`);
13393
+ console.log(chalk33.bold("C\xE1c l\u1EC7nh:"));
13394
+ console.log(` ${chalk33.cyan("list")} Li\u1EC7t k\xEA c\xE1c presets c\xF3 s\u1EB5n`);
13395
+ console.log(` ${chalk33.cyan("info")} Xem chi ti\u1EBFt m\u1ED9t preset`);
13396
+ console.log(` ${chalk33.cyan("init")} Kh\u1EDFi t\u1EA1o rules t\u1EEB preset`);
13397
+ console.log(` ${chalk33.cyan("apply")} \xC1p d\u1EE5ng preset v\xE0o project`);
13398
+ console.log(` ${chalk33.cyan("sync")} \u0110\u1ED3ng b\u1ED9 rules sang c\xE1c \u0111\u1ECBnh d\u1EA1ng IDE`);
13399
+ console.log(` ${chalk33.cyan("restore")} Kh\xF4i ph\u1EE5c rules t\u1EEB backup`);
13349
13400
  console.log();
13350
- console.log(chalk32.bold("V\xED d\u1EE5:"));
13351
- console.log(chalk32.dim(" $ jai1 rules list"));
13352
- console.log(chalk32.dim(" $ jai1 rules info react-typescript"));
13353
- console.log(chalk32.dim(" $ jai1 rules init --preset=react-typescript"));
13354
- console.log(chalk32.dim(" $ jai1 rules apply react-typescript"));
13401
+ console.log(chalk33.bold("V\xED d\u1EE5:"));
13402
+ console.log(chalk33.dim(" $ jai1 rules list"));
13403
+ console.log(chalk33.dim(" $ jai1 rules info react-typescript"));
13404
+ console.log(chalk33.dim(" $ jai1 rules init --preset=react-typescript"));
13405
+ console.log(chalk33.dim(" $ jai1 rules apply react-typescript"));
13355
13406
  console.log();
13356
- console.log(chalk32.dim('Ch\u1EA1y "jai1 rules <l\u1EC7nh> --help" \u0111\u1EC3 xem chi ti\u1EBFt'));
13407
+ console.log(chalk33.dim('Ch\u1EA1y "jai1 rules <l\u1EC7nh> --help" \u0111\u1EC3 xem chi ti\u1EBFt'));
13357
13408
  }
13358
13409
  function createRulesCommand() {
13359
- const rulesCommand = new Command67("rules").description("Manage rule presets for AI agents").action(() => {
13410
+ const rulesCommand = new Command68("rules").description("Manage rule presets for AI agents").action(() => {
13360
13411
  showRulesHelp();
13361
13412
  });
13362
13413
  rulesCommand.addCommand(createRulesListCommand());
@@ -13369,7 +13420,7 @@ function createRulesCommand() {
13369
13420
  }
13370
13421
 
13371
13422
  // src/commands/upgrade.ts
13372
- import { Command as Command68 } from "commander";
13423
+ import { Command as Command69 } from "commander";
13373
13424
  import { confirm as confirm14 } from "@inquirer/prompts";
13374
13425
  import { execSync as execSync4 } from "child_process";
13375
13426
  var colors2 = {
@@ -13381,7 +13432,7 @@ var colors2 = {
13381
13432
  bold: "\x1B[1m"
13382
13433
  };
13383
13434
  function createUpgradeCommand() {
13384
- return new Command68("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) => {
13435
+ return new Command69("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) => {
13385
13436
  await handleUpgrade(options);
13386
13437
  });
13387
13438
  }
@@ -13529,11 +13580,11 @@ function getInstallCommand(packageManager2) {
13529
13580
  }
13530
13581
 
13531
13582
  // src/commands/clean.ts
13532
- import { Command as Command69 } from "commander";
13583
+ import { Command as Command70 } from "commander";
13533
13584
  import { confirm as confirm15, select as select6 } from "@inquirer/prompts";
13534
13585
  import { join as join19 } from "path";
13535
13586
  function createCleanCommand() {
13536
- return new Command69("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) => {
13587
+ return new Command70("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) => {
13537
13588
  await handleClean(options);
13538
13589
  });
13539
13590
  }
@@ -13647,7 +13698,7 @@ async function cleanTarget(target, skipConfirm) {
13647
13698
  }
13648
13699
 
13649
13700
  // src/commands/redmine/check.ts
13650
- import { Command as Command70 } from "commander";
13701
+ import { Command as Command71 } from "commander";
13651
13702
 
13652
13703
  // src/services/redmine-config.service.ts
13653
13704
  import { readFile as readFile7 } from "fs/promises";
@@ -13954,7 +14005,7 @@ async function checkConnectivity(config) {
13954
14005
 
13955
14006
  // src/commands/redmine/check.ts
13956
14007
  function createRedmineCheckCommand() {
13957
- const cmd = new Command70("check").description("Check Redmine connectivity").option("-c, --config <path>", "Config file path", "redmine.config.yaml").option("--json", "Output as JSON").action(async (options) => {
14008
+ const cmd = new Command71("check").description("Check Redmine connectivity").option("-c, --config <path>", "Config file path", "redmine.config.yaml").option("--json", "Output as JSON").action(async (options) => {
13958
14009
  await handleRedmineCheck(options);
13959
14010
  });
13960
14011
  return cmd;
@@ -13982,7 +14033,7 @@ async function handleRedmineCheck(options) {
13982
14033
  }
13983
14034
 
13984
14035
  // src/commands/redmine/sync-issue.ts
13985
- import { Command as Command71 } from "commander";
14036
+ import { Command as Command72 } from "commander";
13986
14037
 
13987
14038
  // src/sync-issue.ts
13988
14039
  import { resolve as resolve3, relative } from "path";
@@ -14366,7 +14417,7 @@ function extractIssueIdFromUrl(url) {
14366
14417
 
14367
14418
  // src/commands/redmine/sync-issue.ts
14368
14419
  function createSyncIssueCommand() {
14369
- const cmd = new Command71("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) => {
14420
+ const cmd = new Command72("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) => {
14370
14421
  await handleSyncIssue(options);
14371
14422
  });
14372
14423
  return cmd;
@@ -14410,7 +14461,7 @@ async function handleSyncIssue(options) {
14410
14461
  }
14411
14462
 
14412
14463
  // src/commands/redmine/sync-project.ts
14413
- import { Command as Command72 } from "commander";
14464
+ import { Command as Command73 } from "commander";
14414
14465
 
14415
14466
  // src/sync-project.ts
14416
14467
  async function syncProject(config, options = {}) {
@@ -14480,7 +14531,7 @@ async function syncProject(config, options = {}) {
14480
14531
 
14481
14532
  // src/commands/redmine/sync-project.ts
14482
14533
  function createSyncProjectCommand() {
14483
- const cmd = new Command72("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) => {
14534
+ const cmd = new Command73("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) => {
14484
14535
  await handleSyncProject(options);
14485
14536
  });
14486
14537
  return cmd;
@@ -14535,12 +14586,12 @@ async function handleSyncProject(options) {
14535
14586
  }
14536
14587
 
14537
14588
  // src/commands/framework/info.ts
14538
- import { Command as Command73 } from "commander";
14589
+ import { Command as Command74 } from "commander";
14539
14590
  import { promises as fs28 } from "fs";
14540
14591
  import { join as join20 } from "path";
14541
14592
  import { homedir as homedir6 } from "os";
14542
14593
  function createInfoCommand() {
14543
- const cmd = new Command73("info").description("Show client configuration and status").option("--json", "Output as JSON").option("--verbose", "Show detailed information").action(async (options) => {
14594
+ const cmd = new Command74("info").description("Show client configuration and status").option("--json", "Output as JSON").option("--verbose", "Show detailed information").action(async (options) => {
14544
14595
  await handleInfo(options);
14545
14596
  });
14546
14597
  return cmd;
@@ -14596,7 +14647,7 @@ async function getProjectStatus2() {
14596
14647
  }
14597
14648
 
14598
14649
  // src/commands/self-update.ts
14599
- import { Command as Command74 } from "commander";
14650
+ import { Command as Command75 } from "commander";
14600
14651
  import { confirm as confirm16 } from "@inquirer/prompts";
14601
14652
  import { execSync as execSync5 } from "child_process";
14602
14653
  var colors3 = {
@@ -14608,7 +14659,7 @@ var colors3 = {
14608
14659
  bold: "\x1B[1m"
14609
14660
  };
14610
14661
  function createSelfUpdateCommand() {
14611
- return new Command74("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) => {
14662
+ return new Command75("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) => {
14612
14663
  await handleSelfUpdate(options);
14613
14664
  });
14614
14665
  }
@@ -14748,10 +14799,10 @@ function getInstallCommand2(packageManager2) {
14748
14799
  }
14749
14800
 
14750
14801
  // src/commands/clear-backups.ts
14751
- import { Command as Command75 } from "commander";
14802
+ import { Command as Command76 } from "commander";
14752
14803
  import { confirm as confirm17 } from "@inquirer/prompts";
14753
14804
  function createClearBackupsCommand() {
14754
- return new Command75("clear-backups").description("Clear backup files").option("-y, --yes", "Skip confirmation").action(async (options) => {
14805
+ return new Command76("clear-backups").description("Clear backup files").option("-y, --yes", "Skip confirmation").action(async (options) => {
14755
14806
  const service = new ComponentsService();
14756
14807
  const backups = await service.listBackups(process.cwd());
14757
14808
  if (backups.length === 0) {
@@ -14776,7 +14827,7 @@ function createClearBackupsCommand() {
14776
14827
  }
14777
14828
 
14778
14829
  // src/commands/vscode/index.ts
14779
- import { Command as Command76 } from "commander";
14830
+ import { Command as Command77 } from "commander";
14780
14831
  import { checkbox as checkbox7, confirm as confirm18, select as select7 } from "@inquirer/prompts";
14781
14832
  import fs29 from "fs/promises";
14782
14833
  import path12 from "path";
@@ -14916,7 +14967,7 @@ var PERFORMANCE_GROUPS2 = {
14916
14967
  }
14917
14968
  };
14918
14969
  function createVSCodeCommand() {
14919
- const vscodeCommand = new Command76("vscode").description("Qu\u1EA3n l\xFD c\xE0i \u0111\u1EB7t VSCode cho d\u1EF1 \xE1n hi\u1EC7n t\u1EA1i");
14970
+ const vscodeCommand = new Command77("vscode").description("Qu\u1EA3n l\xFD c\xE0i \u0111\u1EB7t VSCode cho d\u1EF1 \xE1n hi\u1EC7n t\u1EA1i");
14920
14971
  vscodeCommand.action(async () => {
14921
14972
  await interactiveMode2();
14922
14973
  });
@@ -15087,10 +15138,10 @@ async function resetSettings2(groupKeys) {
15087
15138
  }
15088
15139
 
15089
15140
  // src/commands/migrate-ide.ts
15090
- import { Command as Command77 } from "commander";
15141
+ import { Command as Command78 } from "commander";
15091
15142
  import { checkbox as checkbox8, confirm as confirm19 } from "@inquirer/prompts";
15092
15143
  function createMigrateIdeCommand() {
15093
- const cmd = new Command77("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) => {
15144
+ const cmd = new Command78("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) => {
15094
15145
  await runMigrateIde(options);
15095
15146
  });
15096
15147
  return cmd;
@@ -15199,62 +15250,63 @@ async function runMigrateIde(options) {
15199
15250
 
15200
15251
  // src/utils/help-formatter.ts
15201
15252
  import boxen4 from "boxen";
15202
- import chalk33 from "chalk";
15253
+ import chalk34 from "chalk";
15203
15254
  import gradient from "gradient-string";
15204
15255
  import figlet from "figlet";
15205
15256
  function showCustomHelp(version) {
15206
15257
  const title = figlet.textSync("JAI1", { font: "Small" });
15207
15258
  console.log(gradient.pastel(title));
15208
15259
  console.log(
15209
- boxen4(chalk33.cyan(`Agentic Coding CLI v${version}`), {
15260
+ boxen4(chalk34.cyan(`Agentic Coding CLI v${version}`), {
15210
15261
  padding: { left: 1, right: 1, top: 0, bottom: 0 },
15211
15262
  borderStyle: "round",
15212
15263
  borderColor: "cyan"
15213
15264
  })
15214
15265
  );
15215
- console.log(chalk33.bold("\n\u{1F527} Thi\u1EBFt l\u1EADp & Th\xF4ng tin"));
15266
+ console.log(chalk34.bold("\n\u{1F527} Thi\u1EBFt l\u1EADp & Th\xF4ng tin"));
15216
15267
  console.log(" auth X\xE1c th\u1EF1c v\xE0 c\u1EA5u h\xECnh client");
15217
15268
  console.log(" status Hi\u1EC3n th\u1ECB tr\u1EA1ng th\xE1i c\u1EA5u h\xECnh");
15218
15269
  console.log(" client-info T\u1EA1o th\xF4ng tin client \u0111\u1EC3 g\u1EEDi \u0111\u1ED9i ph\xE1t tri\u1EC3n");
15219
15270
  console.log(" errors Qu\u1EA3n l\xFD error logs c\u1EE5c b\u1ED9");
15220
15271
  console.log(" guide H\u01B0\u1EDBng d\u1EABn s\u1EED d\u1EE5ng nhanh");
15272
+ console.log(" quickstart B\u1EAFt \u0111\u1EA7u t\u1EEB \u0111\xE2u? (theo t\xECnh hu\u1ED1ng)");
15221
15273
  console.log(" doctor Chu\u1EA9n \u0111o\xE1n project hi\u1EC7n t\u1EA1i");
15222
- console.log(chalk33.bold("\n\u{1F4E6} Qu\u1EA3n l\xFD Components"));
15274
+ console.log(chalk34.bold("\n\u{1F4E6} Qu\u1EA3n l\xFD Components"));
15223
15275
  console.log(" apply C\xE0i \u0111\u1EB7t components (interactive)");
15224
15276
  console.log(" update C\u1EADp nh\u1EADt components \u0111\xE3 c\xE0i");
15225
15277
  console.log(" check Ki\u1EC3m tra c\u1EADp nh\u1EADt t\u1EEB server");
15226
- console.log(chalk33.bold("\n\u{1F5A5}\uFE0F IDE & T\xEDch h\u1EE3p"));
15278
+ console.log(chalk34.bold("\n\u{1F5A5}\uFE0F IDE & T\xEDch h\u1EE3p"));
15227
15279
  console.log(" ide L\u1EC7nh c\u1EA5u h\xECnh IDE");
15228
15280
  console.log(" chat Chat AI v\u1EDBi Jai1 LLM Proxy");
15229
15281
  console.log(" openai-keys Th\xF4ng tin API credentials");
15230
- console.log(chalk33.bold("\n\u{1F916} AI Tools"));
15282
+ console.log(chalk34.bold("\n\u{1F916} AI Tools"));
15231
15283
  console.log(" translate D\u1ECBch v\u0103n b\u1EA3n/file b\u1EB1ng AI");
15232
15284
  console.log(" image T\u1EA1o \u1EA3nh (Coming Soon)");
15233
15285
  console.log(" stats Th\u1ED1ng k\xEA s\u1EED d\u1EE5ng LLM");
15234
15286
  console.log(" feedback G\u1EEDi b\xE1o c\xE1o/\u0111\u1EC1 xu\u1EA5t");
15235
- console.log(chalk33.bold("\n\u{1F4C1} Project"));
15287
+ console.log(chalk34.bold("\n\u{1F4C1} Project"));
15236
15288
  console.log(" kit Qu\u1EA3n l\xFD starter kits");
15237
15289
  console.log(" rules Qu\u1EA3n l\xFD rule presets");
15238
15290
  console.log(" deps Qu\u1EA3n l\xFD dependencies");
15239
15291
  console.log(" redmine Redmine context sync");
15240
- console.log(chalk33.bold("\n\u2699\uFE0F B\u1EA3o tr\xEC"));
15292
+ console.log(chalk34.bold("\n\u2699\uFE0F B\u1EA3o tr\xEC"));
15241
15293
  console.log(" upgrade C\u1EADp nh\u1EADt CLI client");
15242
15294
  console.log(" clean D\u1ECDn d\u1EB9p cache/backup");
15243
15295
  console.log(" utils Developer utilities");
15244
15296
  const name = getCliName();
15245
- console.log(chalk33.dim(`
15297
+ console.log(chalk34.dim(`
15246
15298
  S\u1EED d\u1EE5ng: ${name} [l\u1EC7nh] --help \u0111\u1EC3 xem chi ti\u1EBFt`));
15247
15299
  }
15248
15300
  function showUnknownCommand(commandName) {
15249
- console.error(chalk33.red(`\u274C L\u1EC7nh kh\xF4ng t\u1ED3n t\u1EA1i: ${commandName}`));
15301
+ console.error(chalk34.red(`\u274C L\u1EC7nh kh\xF4ng t\u1ED3n t\u1EA1i: ${commandName}`));
15250
15302
  const name = getCliName();
15251
- console.error(chalk33.dim(`
15303
+ console.error(chalk34.dim(`
15252
15304
  G\u1EE3i \xFD: Ch\u1EA1y ${name} --help \u0111\u1EC3 xem danh s\xE1ch l\u1EC7nh`));
15253
15305
  }
15254
15306
 
15255
15307
  // src/cli.ts
15256
15308
  checkNodeVersion();
15257
- var program = new Command78();
15309
+ var program = new Command79();
15258
15310
  if (process.argv.includes("-v") || process.argv.includes("--version")) {
15259
15311
  console.log(package_default.version);
15260
15312
  if (!process.argv.includes("--skip-update-check")) {
@@ -15277,6 +15329,7 @@ program.addCommand(createUpdateCommand());
15277
15329
  program.addCommand(createCheckCommand());
15278
15330
  program.addCommand(createIdeCommand());
15279
15331
  program.addCommand(createGuideCommand());
15332
+ program.addCommand(createQuickstartCommand());
15280
15333
  program.addCommand(createDoctorCommand());
15281
15334
  program.addCommand(createChatCommand());
15282
15335
  program.addCommand(createOpenAiKeysCommand());
@@ -15293,9 +15346,9 @@ program.addCommand(createKitCommand());
15293
15346
  program.addCommand(createRulesCommand());
15294
15347
  program.addCommand(createUpgradeCommand());
15295
15348
  program.addCommand(createCleanCommand());
15296
- var redmineCommand = new Command78("redmine").description("Redmine context sync commands");
15349
+ var redmineCommand = new Command79("redmine").description("Redmine context sync commands");
15297
15350
  redmineCommand.addCommand(createRedmineCheckCommand());
15298
- var syncCommand = new Command78("sync").description("Sync Redmine issues to markdown files");
15351
+ var syncCommand = new Command79("sync").description("Sync Redmine issues to markdown files");
15299
15352
  syncCommand.addCommand(createSyncIssueCommand());
15300
15353
  syncCommand.addCommand(createSyncProjectCommand());
15301
15354
  redmineCommand.addCommand(syncCommand);