@jvittechs/jai1-cli 0.1.91 → 0.1.92

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/cli.ts
4
- import { Command as Command55 } from "commander";
4
+ import { Command as Command60 } from "commander";
5
5
 
6
6
  // src/errors/index.ts
7
7
  var Jai1Error = class extends Error {
@@ -33,7 +33,7 @@ var NetworkError = class extends Jai1Error {
33
33
  // package.json
34
34
  var package_default = {
35
35
  name: "@jvittechs/jai1-cli",
36
- version: "0.1.91",
36
+ version: "0.1.92",
37
37
  description: "A unified CLI tool for JV-IT TECHS developers to manage Jai1 Framework. Please contact TeamAI for usage instructions.",
38
38
  type: "module",
39
39
  bin: {
@@ -97,6 +97,7 @@ var package_default = {
97
97
  "p-retry": "^6.2.0",
98
98
  react: "^18.3.1",
99
99
  slugify: "^1.6.6",
100
+ "terminal-image": "^4.1.0",
100
101
  undici: "^6.19.5",
101
102
  yaml: "^2.5.0",
102
103
  zod: "^3.23.8"
@@ -5414,11 +5415,266 @@ function createTranslateCommand() {
5414
5415
  return cmd;
5415
5416
  }
5416
5417
 
5418
+ // src/commands/image/index.ts
5419
+ import { Command as Command20 } from "commander";
5420
+
5421
+ // src/commands/image/gen.ts
5422
+ import { Command as Command16 } from "commander";
5423
+
5424
+ // src/services/image.service.ts
5425
+ var ImageService = class {
5426
+ /**
5427
+ * Generate image from prompt
5428
+ */
5429
+ async generate(config, options) {
5430
+ const response = await fetch(`${config.apiUrl}/api/image/generate`, {
5431
+ method: "POST",
5432
+ headers: {
5433
+ "Content-Type": "application/json",
5434
+ "JAI1-Access-Key": config.accessKey
5435
+ },
5436
+ body: JSON.stringify(options)
5437
+ });
5438
+ if (!response.ok) {
5439
+ let errorMessage = `HTTP ${response.status}`;
5440
+ try {
5441
+ const error = await response.json();
5442
+ errorMessage = error.message || errorMessage;
5443
+ } catch (e) {
5444
+ }
5445
+ throw new NetworkError(errorMessage);
5446
+ }
5447
+ const data = await response.json();
5448
+ return data.data;
5449
+ }
5450
+ /**
5451
+ * List generated images
5452
+ */
5453
+ async list(config, options) {
5454
+ const params = new URLSearchParams();
5455
+ if (options.model) params.set("model", options.model);
5456
+ if (options.limit) params.set("limit", options.limit.toString());
5457
+ if (options.offset) params.set("offset", options.offset.toString());
5458
+ const url = `${config.apiUrl}/api/image/list?${params}`;
5459
+ const response = await fetch(url, {
5460
+ headers: {
5461
+ "JAI1-Access-Key": config.accessKey
5462
+ }
5463
+ });
5464
+ if (!response.ok) {
5465
+ throw new NetworkError(`Failed to list images: HTTP ${response.status}`);
5466
+ }
5467
+ const data = await response.json();
5468
+ return data.data;
5469
+ }
5470
+ /**
5471
+ * Get image info
5472
+ */
5473
+ async getInfo(config, id) {
5474
+ const response = await fetch(`${config.apiUrl}/api/image/${id}`, {
5475
+ headers: {
5476
+ "JAI1-Access-Key": config.accessKey
5477
+ }
5478
+ });
5479
+ if (!response.ok) {
5480
+ if (response.status === 404) {
5481
+ throw new Error("Image not found");
5482
+ }
5483
+ throw new NetworkError(`Failed to get image: HTTP ${response.status}`);
5484
+ }
5485
+ const data = await response.json();
5486
+ return data.data;
5487
+ }
5488
+ /**
5489
+ * Delete image
5490
+ */
5491
+ async delete(config, id) {
5492
+ const response = await fetch(`${config.apiUrl}/api/image/${id}`, {
5493
+ method: "DELETE",
5494
+ headers: {
5495
+ "JAI1-Access-Key": config.accessKey
5496
+ }
5497
+ });
5498
+ if (!response.ok) {
5499
+ if (response.status === 404) {
5500
+ throw new Error("Image not found");
5501
+ }
5502
+ throw new NetworkError(`Failed to delete image: HTTP ${response.status}`);
5503
+ }
5504
+ }
5505
+ };
5506
+
5507
+ // src/commands/image/gen.ts
5508
+ import terminalImage from "terminal-image";
5509
+ function createImageGenCommand() {
5510
+ return new Command16("gen").description("Generate an image from text prompt").argument("<prompt>", "Image description prompt").option("-m, --model <model>", "Model to use", "gemini-3-flash-preview").option("-w, --width <number>", "Image width").option("-h, --height <number>", "Image height").option("-r, --ratio <ratio>", "Aspect ratio (1:1, 16:9, 9:16, 4:3, 3:4)").option("--negative <prompt>", "Negative prompt").option("--seed <number>", "Random seed").option("--no-display", "Don't display image in terminal").action(async (prompt, options) => {
5511
+ const configService = new ConfigService();
5512
+ const config = await configService.load();
5513
+ if (!config) {
5514
+ throw new ValidationError('Not initialized. Run "jai1 auth" first.');
5515
+ }
5516
+ const imageService = new ImageService();
5517
+ console.log("\u{1F3A8} Generating image...");
5518
+ console.log(` Prompt: ${prompt}`);
5519
+ console.log(` Model: ${options.model}`);
5520
+ try {
5521
+ const result = await imageService.generate(config, {
5522
+ prompt,
5523
+ model: options.model,
5524
+ ...options.width && { width: parseInt(options.width) },
5525
+ ...options.height && { height: parseInt(options.height) },
5526
+ ...options.ratio && { aspectRatio: options.ratio },
5527
+ ...options.negative && { negativePrompt: options.negative },
5528
+ ...options.seed && { seed: parseInt(options.seed) }
5529
+ });
5530
+ console.log("\n\u2705 Image generated successfully!");
5531
+ console.log(` URL: ${result.url}`);
5532
+ console.log(` Size: ${(result.contentSize / 1024).toFixed(2)} KB`);
5533
+ console.log(` ID: ${result.id}`);
5534
+ if (options.display !== false) {
5535
+ try {
5536
+ const imageResponse = await fetch(result.url);
5537
+ const arrayBuffer = await imageResponse.arrayBuffer();
5538
+ const imageBuffer = Buffer.from(arrayBuffer);
5539
+ const rendered = await terminalImage.buffer(imageBuffer, {
5540
+ width: "50%",
5541
+ height: "50%"
5542
+ });
5543
+ console.log("\n" + rendered);
5544
+ } catch (displayError) {
5545
+ }
5546
+ }
5547
+ console.log('\n\u{1F4A1} Tip: Use "jai1 image list" to view all your images');
5548
+ console.log(' Use "jai1 image info <id>" for details');
5549
+ } catch (error) {
5550
+ if (error instanceof Error) {
5551
+ if (error.message.includes("Rate limit")) {
5552
+ console.error("\n\u26A0\uFE0F Rate limit exceeded");
5553
+ console.error(' Use "jai1 image limits" to check your quota');
5554
+ } else {
5555
+ throw error;
5556
+ }
5557
+ }
5558
+ throw error;
5559
+ }
5560
+ });
5561
+ }
5562
+
5563
+ // src/commands/image/list.ts
5564
+ import { Command as Command17 } from "commander";
5565
+ function createImageListCommand() {
5566
+ return new Command17("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) => {
5567
+ const configService = new ConfigService();
5568
+ const config = await configService.load();
5569
+ if (!config) {
5570
+ throw new ValidationError('Not initialized. Run "jai1 auth" first.');
5571
+ }
5572
+ const imageService = new ImageService();
5573
+ const result = await imageService.list(config, {
5574
+ model: options.model,
5575
+ limit: parseInt(options.limit),
5576
+ offset: parseInt(options.offset)
5577
+ });
5578
+ if (result.images.length === 0) {
5579
+ console.log("No images found.");
5580
+ return;
5581
+ }
5582
+ console.log(`
5583
+ \u{1F4F8} Your Generated Images (${result.total} total):
5584
+ `);
5585
+ for (const img of result.images) {
5586
+ const date = new Date(img.createdAt).toLocaleString();
5587
+ const promptPreview = img.prompt.length > 50 ? img.prompt.slice(0, 50) + "..." : img.prompt;
5588
+ console.log(`ID: ${img.id.toString().padEnd(6)} | ${date}`);
5589
+ console.log(` Model: ${img.model}`);
5590
+ console.log(` Prompt: ${promptPreview}`);
5591
+ console.log(` URL: ${img.url}`);
5592
+ console.log();
5593
+ }
5594
+ if (result.total > result.offset + result.limit) {
5595
+ const nextOffset = result.offset + result.limit;
5596
+ console.log(`\u{1F4A1} Show more: jai1 image list -o ${nextOffset}`);
5597
+ }
5598
+ });
5599
+ }
5600
+
5601
+ // src/commands/image/info.ts
5602
+ import { Command as Command18 } from "commander";
5603
+ function createImageInfoCommand() {
5604
+ return new Command18("info").description("Get detailed info about an image").argument("<id>", "Image ID").action(async (id) => {
5605
+ const configService = new ConfigService();
5606
+ const config = await configService.load();
5607
+ if (!config) {
5608
+ throw new ValidationError('Not initialized. Run "jai1 auth" first.');
5609
+ }
5610
+ const imageService = new ImageService();
5611
+ const image = await imageService.getInfo(config, parseInt(id));
5612
+ console.log("\n\u{1F4F8} Image Details:\n");
5613
+ console.log(`ID: ${image.id}`);
5614
+ console.log(`Model: ${image.model}`);
5615
+ console.log(`Prompt: ${image.prompt}`);
5616
+ console.log(`URL: ${image.url}`);
5617
+ console.log(`Size: ${(image.contentSize / 1024).toFixed(2)} KB`);
5618
+ if (image.width && image.height) {
5619
+ console.log(`Dimensions: ${image.width}x${image.height}`);
5620
+ }
5621
+ console.log(`Created: ${new Date(image.createdAt).toLocaleString()}`);
5622
+ if (image.metadata) {
5623
+ const meta = typeof image.metadata === "string" ? JSON.parse(image.metadata) : image.metadata;
5624
+ if (meta.aspectRatio) {
5625
+ console.log(`Ratio: ${meta.aspectRatio}`);
5626
+ }
5627
+ if (meta.negativePrompt) {
5628
+ console.log(`Negative: ${meta.negativePrompt}`);
5629
+ }
5630
+ if (meta.seed) {
5631
+ console.log(`Seed: ${meta.seed}`);
5632
+ }
5633
+ }
5634
+ });
5635
+ }
5636
+
5637
+ // src/commands/image/delete.ts
5638
+ import { Command as Command19 } from "commander";
5639
+ import { confirm as confirm4 } from "@inquirer/prompts";
5640
+ function createImageDeleteCommand() {
5641
+ return new Command19("delete").description("Delete a generated image").argument("<id>", "Image ID").option("-y, --yes", "Skip confirmation").action(async (id, options) => {
5642
+ const configService = new ConfigService();
5643
+ const config = await configService.load();
5644
+ if (!config) {
5645
+ throw new ValidationError('Not initialized. Run "jai1 auth" first.');
5646
+ }
5647
+ if (!options.yes) {
5648
+ const confirmed = await confirm4({
5649
+ message: `Are you sure you want to delete image #${id}?`,
5650
+ default: false
5651
+ });
5652
+ if (!confirmed) {
5653
+ console.log("Cancelled.");
5654
+ return;
5655
+ }
5656
+ }
5657
+ const imageService = new ImageService();
5658
+ await imageService.delete(config, parseInt(id));
5659
+ console.log(`\u2705 Image #${id} deleted successfully.`);
5660
+ });
5661
+ }
5662
+
5663
+ // src/commands/image/index.ts
5664
+ function createImageCommand() {
5665
+ const cmd = new Command20("image").description("Image generation commands");
5666
+ cmd.addCommand(createImageGenCommand());
5667
+ cmd.addCommand(createImageListCommand());
5668
+ cmd.addCommand(createImageInfoCommand());
5669
+ cmd.addCommand(createImageDeleteCommand());
5670
+ return cmd;
5671
+ }
5672
+
5417
5673
  // src/commands/utils/index.ts
5418
- import { Command as Command29 } from "commander";
5674
+ import { Command as Command34 } from "commander";
5419
5675
 
5420
5676
  // src/commands/utils/password.ts
5421
- import { Command as Command16 } from "commander";
5677
+ import { Command as Command21 } from "commander";
5422
5678
 
5423
5679
  // src/services/utils.service.ts
5424
5680
  import crypto from "crypto";
@@ -5687,7 +5943,7 @@ async function handlePasswordGeneration(options) {
5687
5943
  }
5688
5944
  }
5689
5945
  function createPasswordCommand() {
5690
- const cmd = new Command16("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", `
5946
+ const cmd = new Command21("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", `
5691
5947
  Examples:
5692
5948
  $ jai1 utils password
5693
5949
  $ jai1 utils password --length 24
@@ -5705,7 +5961,7 @@ Examples:
5705
5961
  }
5706
5962
 
5707
5963
  // src/commands/utils/uuid.ts
5708
- import { Command as Command17 } from "commander";
5964
+ import { Command as Command22 } from "commander";
5709
5965
  async function handleUuidGeneration(options) {
5710
5966
  const service = new UtilsService();
5711
5967
  try {
@@ -5733,7 +5989,7 @@ async function handleUuidGeneration(options) {
5733
5989
  }
5734
5990
  }
5735
5991
  function createUuidCommand() {
5736
- const cmd = new Command17("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", `
5992
+ const cmd = new Command22("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", `
5737
5993
  Examples:
5738
5994
  $ jai1 utils uuid
5739
5995
  $ jai1 utils uuid --count 10
@@ -5750,7 +6006,7 @@ Examples:
5750
6006
  }
5751
6007
 
5752
6008
  // src/commands/utils/hash.ts
5753
- import { Command as Command18 } from "commander";
6009
+ import { Command as Command23 } from "commander";
5754
6010
  async function handleHashGeneration(input4, options) {
5755
6011
  const service = new UtilsService();
5756
6012
  try {
@@ -5790,7 +6046,7 @@ async function handleHashGeneration(input4, options) {
5790
6046
  }
5791
6047
  }
5792
6048
  function createHashCommand() {
5793
- const cmd = new Command18("hash").description("Generate hash (MD5, SHA, bcrypt)").argument("[input]", "Text to hash").option(
6049
+ const cmd = new Command23("hash").description("Generate hash (MD5, SHA, bcrypt)").argument("[input]", "Text to hash").option(
5794
6050
  "-a, --algorithm <algorithm>",
5795
6051
  "Hash algorithm (md5, sha1, sha256, sha512, bcrypt)",
5796
6052
  "sha256"
@@ -5812,7 +6068,7 @@ Examples:
5812
6068
  }
5813
6069
 
5814
6070
  // src/commands/utils/base64-encode.ts
5815
- import { Command as Command19 } from "commander";
6071
+ import { Command as Command24 } from "commander";
5816
6072
  import { readFile as readFile2 } from "fs/promises";
5817
6073
  async function handleBase64Encode(input4, options) {
5818
6074
  const service = new UtilsService();
@@ -5845,7 +6101,7 @@ async function handleBase64Encode(input4, options) {
5845
6101
  }
5846
6102
  }
5847
6103
  function createBase64EncodeCommand() {
5848
- const cmd = new Command19("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", `
6104
+ const cmd = new Command24("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", `
5849
6105
  Examples:
5850
6106
  $ jai1 utils base64-encode "hello world"
5851
6107
  $ jai1 utils base64-encode "hello world" --url-safe
@@ -5858,7 +6114,7 @@ Examples:
5858
6114
  }
5859
6115
 
5860
6116
  // src/commands/utils/base64-decode.ts
5861
- import { Command as Command20 } from "commander";
6117
+ import { Command as Command25 } from "commander";
5862
6118
  import { readFile as readFile3, writeFile } from "fs/promises";
5863
6119
  async function handleBase64Decode(input4, options) {
5864
6120
  const service = new UtilsService();
@@ -5890,7 +6146,7 @@ async function handleBase64Decode(input4, options) {
5890
6146
  }
5891
6147
  }
5892
6148
  function createBase64DecodeCommand() {
5893
- const cmd = new Command20("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", `
6149
+ const cmd = new Command25("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", `
5894
6150
  Examples:
5895
6151
  $ jai1 utils base64-decode "aGVsbG8gd29ybGQ="
5896
6152
  $ jai1 utils base64-decode --file ./encoded.txt
@@ -5903,7 +6159,7 @@ Examples:
5903
6159
  }
5904
6160
 
5905
6161
  // src/commands/utils/http.ts
5906
- import { Command as Command21 } from "commander";
6162
+ import { Command as Command26 } from "commander";
5907
6163
  import { readFile as readFile4 } from "fs/promises";
5908
6164
  async function handleHttpRequest(url, options) {
5909
6165
  const service = new UtilsService();
@@ -5969,7 +6225,7 @@ async function handleHttpRequest(url, options) {
5969
6225
  }
5970
6226
  }
5971
6227
  function createHttpCommand() {
5972
- const cmd = new Command21("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", `
6228
+ const cmd = new Command26("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", `
5973
6229
  Examples:
5974
6230
  $ jai1 utils http https://api.example.com/users
5975
6231
  $ jai1 utils http https://api.example.com/users -X POST -d '{"name":"John"}'
@@ -5987,7 +6243,7 @@ Examples:
5987
6243
  }
5988
6244
 
5989
6245
  // src/commands/utils/jwt.ts
5990
- import { Command as Command22 } from "commander";
6246
+ import { Command as Command27 } from "commander";
5991
6247
  async function handleJwtDecode(token) {
5992
6248
  const service = new UtilsService();
5993
6249
  try {
@@ -6026,7 +6282,7 @@ async function handleJwtEncode(options) {
6026
6282
  }
6027
6283
  }
6028
6284
  function createJwtCommand() {
6029
- const jwtCommand = new Command22("jwt").description("Decode and encode JWT tokens");
6285
+ const jwtCommand = new Command27("jwt").description("Decode and encode JWT tokens");
6030
6286
  jwtCommand.command("decode").description("Decode JWT token").argument("<token>", "JWT token to decode").addHelpText("after", `
6031
6287
  Examples:
6032
6288
  $ jai1 utils jwt decode "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
@@ -6047,7 +6303,7 @@ Examples:
6047
6303
  }
6048
6304
 
6049
6305
  // src/commands/utils/unix-time.ts
6050
- import { Command as Command23 } from "commander";
6306
+ import { Command as Command28 } from "commander";
6051
6307
  async function handleUnixTime(input4, options) {
6052
6308
  const service = new UtilsService();
6053
6309
  try {
@@ -6095,7 +6351,7 @@ async function handleUnixTime(input4, options) {
6095
6351
  }
6096
6352
  }
6097
6353
  function createUnixTimeCommand() {
6098
- const cmd = new Command23("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", `
6354
+ const cmd = new Command28("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", `
6099
6355
  Examples:
6100
6356
  $ jai1 utils unix-time
6101
6357
  $ jai1 utils unix-time 1702550400
@@ -6110,7 +6366,7 @@ Examples:
6110
6366
  }
6111
6367
 
6112
6368
  // src/commands/utils/timezone.ts
6113
- import { Command as Command24 } from "commander";
6369
+ import { Command as Command29 } from "commander";
6114
6370
  async function handleTimezoneConversion(time, options) {
6115
6371
  const service = new UtilsService();
6116
6372
  try {
@@ -6147,7 +6403,7 @@ async function handleTimezoneConversion(time, options) {
6147
6403
  }
6148
6404
  }
6149
6405
  function createTimezoneCommand() {
6150
- const cmd = new Command24("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", `
6406
+ const cmd = new Command29("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", `
6151
6407
  Examples:
6152
6408
  $ jai1 utils timezone --list
6153
6409
  $ jai1 utils timezone "2024-01-15 10:00" --from "America/New_York" --to "Asia/Tokyo"
@@ -6160,7 +6416,7 @@ Examples:
6160
6416
  }
6161
6417
 
6162
6418
  // src/commands/utils/url-encode.ts
6163
- import { Command as Command25 } from "commander";
6419
+ import { Command as Command30 } from "commander";
6164
6420
  async function handleUrlEncode(input4, options) {
6165
6421
  const service = new UtilsService();
6166
6422
  try {
@@ -6181,7 +6437,7 @@ async function handleUrlEncode(input4, options) {
6181
6437
  }
6182
6438
  }
6183
6439
  function createUrlEncodeCommand() {
6184
- const cmd = new Command25("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", `
6440
+ const cmd = new Command30("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", `
6185
6441
  Examples:
6186
6442
  $ jai1 utils url-encode "hello world"
6187
6443
  $ jai1 utils url-encode "hello world & test"
@@ -6194,7 +6450,7 @@ Examples:
6194
6450
  }
6195
6451
 
6196
6452
  // src/commands/utils/url-decode.ts
6197
- import { Command as Command26 } from "commander";
6453
+ import { Command as Command31 } from "commander";
6198
6454
  async function handleUrlDecode(input4, options) {
6199
6455
  const service = new UtilsService();
6200
6456
  try {
@@ -6215,7 +6471,7 @@ async function handleUrlDecode(input4, options) {
6215
6471
  }
6216
6472
  }
6217
6473
  function createUrlDecodeCommand() {
6218
- const cmd = new Command26("url-decode").description("Decode URL-encoded string").argument("<input>", "Text to decode").option("--full", "Decode full URL (use decodeURI instead of decodeURIComponent)").addHelpText("after", `
6474
+ const cmd = new Command31("url-decode").description("Decode URL-encoded string").argument("<input>", "Text to decode").option("--full", "Decode full URL (use decodeURI instead of decodeURIComponent)").addHelpText("after", `
6219
6475
  Examples:
6220
6476
  $ jai1 utils url-decode "hello%20world"
6221
6477
  $ jai1 utils url-decode "hello%20world%20%26%20test"
@@ -6228,7 +6484,7 @@ Examples:
6228
6484
  }
6229
6485
 
6230
6486
  // src/commands/utils/cron.ts
6231
- import { Command as Command27 } from "commander";
6487
+ import { Command as Command32 } from "commander";
6232
6488
  import cronstrue from "cronstrue";
6233
6489
  async function handleCronParse(expression) {
6234
6490
  try {
@@ -6271,7 +6527,7 @@ async function handleCronParse(expression) {
6271
6527
  }
6272
6528
  }
6273
6529
  function createCronCommand() {
6274
- const cmd = new Command27("cron").description("Parse and explain cron expression").argument("<expression>", 'Cron expression (e.g., "0 5 * * *")').addHelpText("after", `
6530
+ const cmd = new Command32("cron").description("Parse and explain cron expression").argument("<expression>", 'Cron expression (e.g., "0 5 * * *")').addHelpText("after", `
6275
6531
  Examples:
6276
6532
  $ jai1 utils cron "0 5 * * *"
6277
6533
  $ jai1 utils cron "*/15 * * * *"
@@ -6285,7 +6541,7 @@ Examples:
6285
6541
  }
6286
6542
 
6287
6543
  // src/commands/utils/markdown-preview.ts
6288
- import { Command as Command28 } from "commander";
6544
+ import { Command as Command33 } from "commander";
6289
6545
  import { readFile as readFile5 } from "fs/promises";
6290
6546
  import { marked } from "marked";
6291
6547
  import TerminalRenderer from "marked-terminal";
@@ -6324,7 +6580,7 @@ ${code.trim()}
6324
6580
  }
6325
6581
  }
6326
6582
  function createMarkdownPreviewCommand() {
6327
- const cmd = new Command28("markdown-preview").description("Preview markdown file in terminal").argument("<file>", "Markdown file path").option("--raw", "Show raw markdown instead of rendered").addHelpText("after", `
6583
+ const cmd = new Command33("markdown-preview").description("Preview markdown file in terminal").argument("<file>", "Markdown file path").option("--raw", "Show raw markdown instead of rendered").addHelpText("after", `
6328
6584
  Examples:
6329
6585
  $ jai1 utils markdown-preview README.md
6330
6586
  $ jai1 utils markdown-preview ./docs/guide.md
@@ -7733,7 +7989,7 @@ async function runInteractiveMode() {
7733
7989
 
7734
7990
  // src/commands/utils/index.ts
7735
7991
  function createUtilsCommand() {
7736
- const utilsCommand = new Command29("utils").description("Developer utilities for common tasks").option("-i, --interactive", "Run in interactive mode").addHelpText("after", `
7992
+ const utilsCommand = new Command34("utils").description("Developer utilities for common tasks").option("-i, --interactive", "Run in interactive mode").addHelpText("after", `
7737
7993
  Interactive Mode:
7738
7994
  $ jai1 utils --interactive
7739
7995
  $ jai1 utils -i
@@ -7768,11 +8024,11 @@ Quick Usage:
7768
8024
  }
7769
8025
 
7770
8026
  // src/commands/deps/index.ts
7771
- import { Command as Command31 } from "commander";
8027
+ import { Command as Command36 } from "commander";
7772
8028
 
7773
8029
  // src/commands/deps/upgrade.ts
7774
- import { Command as Command30 } from "commander";
7775
- import { checkbox as checkbox3, confirm as confirm4 } from "@inquirer/prompts";
8030
+ import { Command as Command35 } from "commander";
8031
+ import { checkbox as checkbox3, confirm as confirm5 } from "@inquirer/prompts";
7776
8032
 
7777
8033
  // src/services/deps.service.ts
7778
8034
  import { promises as fs10 } from "fs";
@@ -7985,7 +8241,7 @@ var colors2 = {
7985
8241
  dim: "\x1B[2m"
7986
8242
  };
7987
8243
  function createDepsUpgradeCommand() {
7988
- return new Command30("upgrade").description("Upgrade npm packages l\xEAn version m\u1EDBi nh\u1EA5t").option("--check", "Ch\u1EC9 ki\u1EC3m tra, kh\xF4ng upgrade").option("--all", "Upgrade t\u1EA5t c\u1EA3 kh\xF4ng c\u1EA7n ch\u1ECDn").option("--deps-only", "Ch\u1EC9 upgrade dependencies").option("--dev-only", "Ch\u1EC9 upgrade devDependencies").action(async (options) => {
8244
+ return new Command35("upgrade").description("Upgrade npm packages l\xEAn version m\u1EDBi nh\u1EA5t").option("--check", "Ch\u1EC9 ki\u1EC3m tra, kh\xF4ng upgrade").option("--all", "Upgrade t\u1EA5t c\u1EA3 kh\xF4ng c\u1EA7n ch\u1ECDn").option("--deps-only", "Ch\u1EC9 upgrade dependencies").option("--dev-only", "Ch\u1EC9 upgrade devDependencies").action(async (options) => {
7989
8245
  await handleDepsUpgrade(options);
7990
8246
  });
7991
8247
  }
@@ -8077,7 +8333,7 @@ ${colors2.yellow}\u23F8\uFE0F \u0110\xE3 h\u1EE7y${colors2.reset}
8077
8333
  }
8078
8334
  let shouldProceed;
8079
8335
  try {
8080
- shouldProceed = await confirm4({
8336
+ shouldProceed = await confirm5({
8081
8337
  message: `Ti\u1EBFn h\xE0nh upgrade ${selectedPackages.length} packages?`,
8082
8338
  default: true
8083
8339
  });
@@ -8165,16 +8421,16 @@ function displayUpgradeTable(packages) {
8165
8421
 
8166
8422
  // src/commands/deps/index.ts
8167
8423
  function createDepsCommand() {
8168
- const depsCommand = new Command31("deps").description("Qu\u1EA3n l\xFD dependencies trong project");
8424
+ const depsCommand = new Command36("deps").description("Qu\u1EA3n l\xFD dependencies trong project");
8169
8425
  depsCommand.addCommand(createDepsUpgradeCommand());
8170
8426
  return depsCommand;
8171
8427
  }
8172
8428
 
8173
8429
  // src/commands/kit/index.ts
8174
- import { Command as Command35 } from "commander";
8430
+ import { Command as Command40 } from "commander";
8175
8431
 
8176
8432
  // src/commands/kit/list.ts
8177
- import { Command as Command32 } from "commander";
8433
+ import { Command as Command37 } from "commander";
8178
8434
 
8179
8435
  // src/services/starter-kit.service.ts
8180
8436
  import { promises as fs11 } from "fs";
@@ -8241,7 +8497,7 @@ var StarterKitService = class {
8241
8497
 
8242
8498
  // src/commands/kit/list.ts
8243
8499
  function createKitListCommand() {
8244
- return new Command32("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) => {
8500
+ return new Command37("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) => {
8245
8501
  const configService = new ConfigService();
8246
8502
  const config = await configService.load();
8247
8503
  if (!config) {
@@ -8278,9 +8534,9 @@ function createKitListCommand() {
8278
8534
  }
8279
8535
 
8280
8536
  // src/commands/kit/info.ts
8281
- import { Command as Command33 } from "commander";
8537
+ import { Command as Command38 } from "commander";
8282
8538
  function createKitInfoCommand() {
8283
- return new Command33("info").description("Show detailed information about a starter kit").argument("<slug>", "Starter kit slug").action(async (slug) => {
8539
+ return new Command38("info").description("Show detailed information about a starter kit").argument("<slug>", "Starter kit slug").action(async (slug) => {
8284
8540
  const configService = new ConfigService();
8285
8541
  const config = await configService.load();
8286
8542
  if (!config) {
@@ -8329,7 +8585,7 @@ Post-Init Commands:`);
8329
8585
  }
8330
8586
 
8331
8587
  // src/commands/kit/create.ts
8332
- import { Command as Command34 } from "commander";
8588
+ import { Command as Command39 } from "commander";
8333
8589
  import { promises as fs12 } from "fs";
8334
8590
  import { join as join6 } from "path";
8335
8591
  import { select as select2, input, checkbox as checkbox4 } from "@inquirer/prompts";
@@ -8374,7 +8630,7 @@ var HookExecutor = class {
8374
8630
 
8375
8631
  // src/commands/kit/create.ts
8376
8632
  function createKitCreateCommand() {
8377
- return new Command34("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) => {
8633
+ return new Command39("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) => {
8378
8634
  const configService = new ConfigService();
8379
8635
  const config = await configService.load();
8380
8636
  if (!config) {
@@ -8546,7 +8802,7 @@ async function getAllFiles(dir) {
8546
8802
 
8547
8803
  // src/commands/kit/index.ts
8548
8804
  function createKitCommand() {
8549
- const cmd = new Command35("kit").description("Manage starter kits for new projects").action(() => {
8805
+ const cmd = new Command40("kit").description("Manage starter kits for new projects").action(() => {
8550
8806
  cmd.help();
8551
8807
  });
8552
8808
  cmd.addCommand(createKitListCommand());
@@ -8556,12 +8812,12 @@ function createKitCommand() {
8556
8812
  }
8557
8813
 
8558
8814
  // src/commands/rules/index.ts
8559
- import { Command as Command42 } from "commander";
8815
+ import { Command as Command47 } from "commander";
8560
8816
 
8561
8817
  // src/commands/rules/list.ts
8562
- import { Command as Command36 } from "commander";
8818
+ import { Command as Command41 } from "commander";
8563
8819
  function createRulesListCommand() {
8564
- return new Command36("list").description("List available rule presets").option("--json", "Output as JSON").action(async (options) => {
8820
+ return new Command41("list").description("List available rule presets").option("--json", "Output as JSON").action(async (options) => {
8565
8821
  const configService = new ConfigService();
8566
8822
  const config = await configService.load();
8567
8823
  if (!config) {
@@ -8616,12 +8872,12 @@ function createRulesListCommand() {
8616
8872
  }
8617
8873
 
8618
8874
  // src/commands/rules/init.ts
8619
- import { Command as Command37 } from "commander";
8875
+ import { Command as Command42 } from "commander";
8620
8876
  import { promises as fs13 } from "fs";
8621
8877
  import { join as join7 } from "path";
8622
- import { select as select3, confirm as confirm5 } from "@inquirer/prompts";
8878
+ import { select as select3, confirm as confirm6 } from "@inquirer/prompts";
8623
8879
  function createRulesInitCommand() {
8624
- return new Command37("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) => {
8880
+ return new Command42("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) => {
8625
8881
  const configService = new ConfigService();
8626
8882
  const config = await configService.load();
8627
8883
  if (!config) {
@@ -8681,7 +8937,7 @@ function createRulesInitCommand() {
8681
8937
  });
8682
8938
  }
8683
8939
  if (!options.yes) {
8684
- const proceed = await confirm5({
8940
+ const proceed = await confirm6({
8685
8941
  message: `Apply preset '${bundle.preset.name}' to current directory?`,
8686
8942
  default: true
8687
8943
  });
@@ -8749,10 +9005,10 @@ async function applyAgentsMdFormat(bundle) {
8749
9005
  }
8750
9006
 
8751
9007
  // src/commands/rules/apply.ts
8752
- import { Command as Command38 } from "commander";
9008
+ import { Command as Command43 } from "commander";
8753
9009
  import { promises as fs15 } from "fs";
8754
9010
  import { join as join9 } from "path";
8755
- import { select as select4, confirm as confirm6, checkbox as checkbox5 } from "@inquirer/prompts";
9011
+ import { select as select4, confirm as confirm7, checkbox as checkbox5 } from "@inquirer/prompts";
8756
9012
 
8757
9013
  // src/services/rules-generator.service.ts
8758
9014
  var RulesGeneratorService = class {
@@ -9332,7 +9588,7 @@ Restoring backup from ${metadata.timestamp}...`);
9332
9588
 
9333
9589
  // src/commands/rules/apply.ts
9334
9590
  function createRulesApplyCommand() {
9335
- return new Command38("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)").option("--skip-backup", "Skip backup creation").option("-y, --yes", "Skip all confirmations (auto mode)").action(async (presetSlug, options) => {
9591
+ return new Command43("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)").option("--skip-backup", "Skip backup creation").option("-y, --yes", "Skip all confirmations (auto mode)").action(async (presetSlug, options) => {
9336
9592
  const configService = new ConfigService();
9337
9593
  const config = await configService.load();
9338
9594
  if (!config) {
@@ -9472,7 +9728,7 @@ function createRulesApplyCommand() {
9472
9728
  if (backupPath) {
9473
9729
  console.log(` Backup: ${backupPath}`);
9474
9730
  }
9475
- const proceed = await confirm6({
9731
+ const proceed = await confirm7({
9476
9732
  message: "Apply these rules to the current directory?",
9477
9733
  default: true
9478
9734
  });
@@ -9577,11 +9833,11 @@ function createRulesApplyCommand() {
9577
9833
  }
9578
9834
 
9579
9835
  // src/commands/rules/restore.ts
9580
- import { Command as Command39 } from "commander";
9836
+ import { Command as Command44 } from "commander";
9581
9837
  import { join as join10 } from "path";
9582
- import { select as select5, confirm as confirm7 } from "@inquirer/prompts";
9838
+ import { select as select5, confirm as confirm8 } from "@inquirer/prompts";
9583
9839
  function createRulesRestoreCommand() {
9584
- return new Command39("restore").description("Restore rules from a backup").option("--latest", "Restore the most recent backup").option("-y, --yes", "Skip confirmation").action(async (options) => {
9840
+ return new Command44("restore").description("Restore rules from a backup").option("--latest", "Restore the most recent backup").option("-y, --yes", "Skip confirmation").action(async (options) => {
9585
9841
  const backupService = new BackupService();
9586
9842
  const backups = await backupService.listBackups();
9587
9843
  if (backups.length === 0) {
@@ -9613,7 +9869,7 @@ function createRulesRestoreCommand() {
9613
9869
  console.log(` IDEs: ${selectedBackup.ides.join(", ")}`);
9614
9870
  console.log(` Files: ${selectedBackup.files.length}`);
9615
9871
  if (!options.yes) {
9616
- const proceed = await confirm7({
9872
+ const proceed = await confirm8({
9617
9873
  message: "This will overwrite current rules. Continue?",
9618
9874
  default: false
9619
9875
  });
@@ -9649,12 +9905,12 @@ function formatTimestamp(timestamp) {
9649
9905
  }
9650
9906
 
9651
9907
  // src/commands/rules/sync.ts
9652
- import { Command as Command40 } from "commander";
9908
+ import { Command as Command45 } from "commander";
9653
9909
  import { promises as fs16 } from "fs";
9654
9910
  import { join as join11 } from "path";
9655
- import { confirm as confirm8 } from "@inquirer/prompts";
9911
+ import { confirm as confirm9 } from "@inquirer/prompts";
9656
9912
  function createRulesSyncCommand() {
9657
- return new Command40("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) => {
9913
+ return new Command45("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) => {
9658
9914
  const configPath = join11(process.cwd(), "jai1-rules.json");
9659
9915
  let projectConfig;
9660
9916
  try {
@@ -9685,7 +9941,7 @@ Detected ${detected.length} active IDE(s):
9685
9941
  console.log(` ${confidence} ${d.name} - ${d.ruleCount} rules`);
9686
9942
  });
9687
9943
  if (!options.yes) {
9688
- const proceed = await confirm8({
9944
+ const proceed = await confirm9({
9689
9945
  message: "\nSync these detected IDEs?",
9690
9946
  default: true
9691
9947
  });
@@ -9799,11 +10055,11 @@ async function checkPathExists(absolutePath) {
9799
10055
  }
9800
10056
 
9801
10057
  // src/commands/rules/info.ts
9802
- import { Command as Command41 } from "commander";
10058
+ import { Command as Command46 } from "commander";
9803
10059
  import { promises as fs17 } from "fs";
9804
10060
  import { join as join12 } from "path";
9805
10061
  function createRulesInfoCommand() {
9806
- return new Command41("info").description("Show current preset information").option("--json", "Output as JSON").action(async (options) => {
10062
+ return new Command46("info").description("Show current preset information").option("--json", "Output as JSON").action(async (options) => {
9807
10063
  const configPath = join12(process.cwd(), "jai1-rules.json");
9808
10064
  let projectConfig;
9809
10065
  try {
@@ -9909,7 +10165,7 @@ async function checkIdeFilesExist(ideId, format) {
9909
10165
 
9910
10166
  // src/commands/rules/index.ts
9911
10167
  function createRulesCommand() {
9912
- const rulesCommand = new Command42("rules").description("Manage rule presets for AI agents");
10168
+ const rulesCommand = new Command47("rules").description("Manage rule presets for AI agents");
9913
10169
  rulesCommand.addCommand(createRulesListCommand());
9914
10170
  rulesCommand.addCommand(createRulesInitCommand());
9915
10171
  rulesCommand.addCommand(createRulesApplyCommand());
@@ -9920,8 +10176,8 @@ function createRulesCommand() {
9920
10176
  }
9921
10177
 
9922
10178
  // src/commands/upgrade.ts
9923
- import { Command as Command43 } from "commander";
9924
- import { confirm as confirm9 } from "@inquirer/prompts";
10179
+ import { Command as Command48 } from "commander";
10180
+ import { confirm as confirm10 } from "@inquirer/prompts";
9925
10181
  import { execSync as execSync2 } from "child_process";
9926
10182
  var colors3 = {
9927
10183
  yellow: "\x1B[33m",
@@ -9932,7 +10188,7 @@ var colors3 = {
9932
10188
  bold: "\x1B[1m"
9933
10189
  };
9934
10190
  function createUpgradeCommand() {
9935
- return new Command43("upgrade").description("Upgrade jai1-client to the latest version").option("--check", "Only check for updates without installing").option("--force", "Force upgrade without confirmation").action(async (options) => {
10191
+ return new Command48("upgrade").description("Upgrade jai1-client to the latest version").option("--check", "Only check for updates without installing").option("--force", "Force upgrade without confirmation").action(async (options) => {
9936
10192
  await handleUpgrade(options);
9937
10193
  });
9938
10194
  }
@@ -9976,7 +10232,7 @@ ${colors3.bold}Current version:${colors3.reset} ${currentVersion}`);
9976
10232
  return;
9977
10233
  }
9978
10234
  if (!options.force) {
9979
- const shouldUpdate = await confirm9({
10235
+ const shouldUpdate = await confirm10({
9980
10236
  message: "Update to the latest version now?",
9981
10237
  default: true
9982
10238
  });
@@ -10080,11 +10336,11 @@ function getInstallCommand(packageManager2) {
10080
10336
  }
10081
10337
 
10082
10338
  // src/commands/clean.ts
10083
- import { Command as Command44 } from "commander";
10084
- import { confirm as confirm10, select as select6 } from "@inquirer/prompts";
10339
+ import { Command as Command49 } from "commander";
10340
+ import { confirm as confirm11, select as select6 } from "@inquirer/prompts";
10085
10341
  import { join as join13 } from "path";
10086
10342
  function createCleanCommand() {
10087
- return new Command44("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) => {
10343
+ return new Command49("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) => {
10088
10344
  await handleClean(options);
10089
10345
  });
10090
10346
  }
@@ -10179,7 +10435,7 @@ async function cleanTarget(target, skipConfirm) {
10179
10435
  }
10180
10436
  const countStr = info.count ? ` (${info.count} items)` : "";
10181
10437
  if (!skipConfirm) {
10182
- const confirmed = await confirm10({
10438
+ const confirmed = await confirm11({
10183
10439
  message: `Delete ${target.name}${countStr}?`,
10184
10440
  default: false
10185
10441
  });
@@ -10197,7 +10453,7 @@ async function cleanTarget(target, skipConfirm) {
10197
10453
  }
10198
10454
 
10199
10455
  // src/commands/redmine/check.ts
10200
- import { Command as Command45 } from "commander";
10456
+ import { Command as Command50 } from "commander";
10201
10457
 
10202
10458
  // src/services/redmine-config.service.ts
10203
10459
  import { readFile as readFile6 } from "fs/promises";
@@ -10504,7 +10760,7 @@ async function checkConnectivity(config) {
10504
10760
 
10505
10761
  // src/commands/redmine/check.ts
10506
10762
  function createRedmineCheckCommand() {
10507
- const cmd = new Command45("check").description("Check Redmine connectivity").option("-c, --config <path>", "Config file path", "redmine.config.yaml").option("--json", "Output as JSON").action(async (options) => {
10763
+ const cmd = new Command50("check").description("Check Redmine connectivity").option("-c, --config <path>", "Config file path", "redmine.config.yaml").option("--json", "Output as JSON").action(async (options) => {
10508
10764
  await handleRedmineCheck(options);
10509
10765
  });
10510
10766
  return cmd;
@@ -10532,7 +10788,7 @@ async function handleRedmineCheck(options) {
10532
10788
  }
10533
10789
 
10534
10790
  // src/commands/redmine/sync-issue.ts
10535
- import { Command as Command46 } from "commander";
10791
+ import { Command as Command51 } from "commander";
10536
10792
 
10537
10793
  // src/sync-issue.ts
10538
10794
  import { resolve as resolve3, relative } from "path";
@@ -10908,7 +11164,7 @@ function extractIssueIdFromUrl(url) {
10908
11164
 
10909
11165
  // src/commands/redmine/sync-issue.ts
10910
11166
  function createSyncIssueCommand() {
10911
- const cmd = new Command46("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) => {
11167
+ const cmd = new Command51("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) => {
10912
11168
  await handleSyncIssue(options);
10913
11169
  });
10914
11170
  return cmd;
@@ -10952,7 +11208,7 @@ async function handleSyncIssue(options) {
10952
11208
  }
10953
11209
 
10954
11210
  // src/commands/redmine/sync-project.ts
10955
- import { Command as Command47 } from "commander";
11211
+ import { Command as Command52 } from "commander";
10956
11212
 
10957
11213
  // src/sync-project.ts
10958
11214
  async function syncProject(config, options = {}) {
@@ -11022,7 +11278,7 @@ async function syncProject(config, options = {}) {
11022
11278
 
11023
11279
  // src/commands/redmine/sync-project.ts
11024
11280
  function createSyncProjectCommand() {
11025
- const cmd = new Command47("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) => {
11281
+ const cmd = new Command52("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) => {
11026
11282
  await handleSyncProject(options);
11027
11283
  });
11028
11284
  return cmd;
@@ -11077,12 +11333,12 @@ async function handleSyncProject(options) {
11077
11333
  }
11078
11334
 
11079
11335
  // src/commands/framework/info.ts
11080
- import { Command as Command48 } from "commander";
11336
+ import { Command as Command53 } from "commander";
11081
11337
  import { promises as fs18 } from "fs";
11082
11338
  import { join as join14 } from "path";
11083
11339
  import { homedir as homedir5 } from "os";
11084
11340
  function createInfoCommand() {
11085
- const cmd = new Command48("info").description("Show jai1-client configuration and status").option("--json", "Output as JSON").option("--verbose", "Show detailed information").action(async (options) => {
11341
+ const cmd = new Command53("info").description("Show jai1-client configuration and status").option("--json", "Output as JSON").option("--verbose", "Show detailed information").action(async (options) => {
11086
11342
  await handleInfo(options);
11087
11343
  });
11088
11344
  return cmd;
@@ -11138,8 +11394,8 @@ async function getProjectStatus2() {
11138
11394
  }
11139
11395
 
11140
11396
  // src/commands/self-update.ts
11141
- import { Command as Command49 } from "commander";
11142
- import { confirm as confirm11 } from "@inquirer/prompts";
11397
+ import { Command as Command54 } from "commander";
11398
+ import { confirm as confirm12 } from "@inquirer/prompts";
11143
11399
  import { execSync as execSync3 } from "child_process";
11144
11400
  var colors4 = {
11145
11401
  yellow: "\x1B[33m",
@@ -11150,7 +11406,7 @@ var colors4 = {
11150
11406
  bold: "\x1B[1m"
11151
11407
  };
11152
11408
  function createSelfUpdateCommand() {
11153
- return new Command49("self-update").description("Update jai1-client to the latest version").option("--check", "Only check for updates without installing").option("--force", "Force update without confirmation").action(async (options) => {
11409
+ return new Command54("self-update").description("Update jai1-client to the latest version").option("--check", "Only check for updates without installing").option("--force", "Force update without confirmation").action(async (options) => {
11154
11410
  await handleSelfUpdate(options);
11155
11411
  });
11156
11412
  }
@@ -11194,7 +11450,7 @@ ${colors4.bold}Current version:${colors4.reset} ${currentVersion}`);
11194
11450
  return;
11195
11451
  }
11196
11452
  if (!options.force) {
11197
- const shouldUpdate = await confirm11({
11453
+ const shouldUpdate = await confirm12({
11198
11454
  message: "Update to the latest version now?",
11199
11455
  default: true
11200
11456
  });
@@ -11290,10 +11546,10 @@ function getInstallCommand2(packageManager2) {
11290
11546
  }
11291
11547
 
11292
11548
  // src/commands/clear-backups.ts
11293
- import { Command as Command50 } from "commander";
11294
- import { confirm as confirm12 } from "@inquirer/prompts";
11549
+ import { Command as Command55 } from "commander";
11550
+ import { confirm as confirm13 } from "@inquirer/prompts";
11295
11551
  function createClearBackupsCommand() {
11296
- return new Command50("clear-backups").description("Clear backup files").option("-y, --yes", "Skip confirmation").action(async (options) => {
11552
+ return new Command55("clear-backups").description("Clear backup files").option("-y, --yes", "Skip confirmation").action(async (options) => {
11297
11553
  const service = new ComponentsService();
11298
11554
  const backups = await service.listBackups(process.cwd());
11299
11555
  if (backups.length === 0) {
@@ -11309,7 +11565,7 @@ function createClearBackupsCommand() {
11309
11565
  }
11310
11566
  console.log();
11311
11567
  if (!options.yes) {
11312
- const ok = await confirm12({ message: "Delete all backups?", default: false });
11568
+ const ok = await confirm13({ message: "Delete all backups?", default: false });
11313
11569
  if (!ok) return;
11314
11570
  }
11315
11571
  await service.clearBackups(process.cwd());
@@ -11318,8 +11574,8 @@ function createClearBackupsCommand() {
11318
11574
  }
11319
11575
 
11320
11576
  // src/commands/vscode/index.ts
11321
- import { Command as Command51 } from "commander";
11322
- import { checkbox as checkbox7, confirm as confirm13, select as select7 } from "@inquirer/prompts";
11577
+ import { Command as Command56 } from "commander";
11578
+ import { checkbox as checkbox7, confirm as confirm14, select as select7 } from "@inquirer/prompts";
11323
11579
  import fs19 from "fs/promises";
11324
11580
  import path7 from "path";
11325
11581
  import { existsSync as existsSync3 } from "fs";
@@ -11458,7 +11714,7 @@ var PERFORMANCE_GROUPS2 = {
11458
11714
  }
11459
11715
  };
11460
11716
  function createVSCodeCommand() {
11461
- const vscodeCommand = new Command51("vscode").description("Qu\u1EA3n l\xFD c\xE0i \u0111\u1EB7t VSCode cho d\u1EF1 \xE1n hi\u1EC7n t\u1EA1i");
11717
+ const vscodeCommand = new Command56("vscode").description("Qu\u1EA3n l\xFD c\xE0i \u0111\u1EB7t VSCode cho d\u1EF1 \xE1n hi\u1EC7n t\u1EA1i");
11462
11718
  vscodeCommand.action(async () => {
11463
11719
  await interactiveMode2();
11464
11720
  });
@@ -11562,7 +11818,7 @@ async function applyGroups2(groupKeys, action) {
11562
11818
  console.log("\u{1F4C4} \u0110\xE3 \u0111\u1ECDc c\xE0i \u0111\u1EB7t hi\u1EC7n t\u1EA1i t\u1EEB settings.json");
11563
11819
  } catch {
11564
11820
  console.warn("\u26A0\uFE0F Kh\xF4ng th\u1EC3 \u0111\u1ECDc settings.json (c\xF3 th\u1EC3 ch\u1EE9a comments).");
11565
- const confirmOverwrite = await confirm13({
11821
+ const confirmOverwrite = await confirm14({
11566
11822
  message: "Ghi \u0111\xE8 file settings.json hi\u1EC7n t\u1EA1i?",
11567
11823
  default: false
11568
11824
  });
@@ -11609,7 +11865,7 @@ async function resetSettings2(groupKeys) {
11609
11865
  console.log("\n\u26A0\uFE0F Kh\xF4ng t\xECm th\u1EA5y file settings.json");
11610
11866
  return;
11611
11867
  }
11612
- const confirmReset = await confirm13({
11868
+ const confirmReset = await confirm14({
11613
11869
  message: groupKeys.length === 0 ? "Reset T\u1EA4T C\u1EA2 settings v\u1EC1 m\u1EB7c \u0111\u1ECBnh (x\xF3a to\xE0n b\u1ED9 file)?" : `Reset c\xE1c nh\xF3m: ${groupKeys.join(", ")}?`,
11614
11870
  default: false
11615
11871
  });
@@ -11629,9 +11885,9 @@ async function resetSettings2(groupKeys) {
11629
11885
  // src/commands/guide.ts
11630
11886
  import React40 from "react";
11631
11887
  import { render as render6 } from "ink";
11632
- import { Command as Command52 } from "commander";
11888
+ import { Command as Command57 } from "commander";
11633
11889
  function createGuideCommand() {
11634
- const cmd = new Command52("guide").description("Interactive guide center for Agentic Coding").option("--topic <topic>", "Open specific topic (intro, rules, workflows, prompts, skills)").action(async (options) => {
11890
+ const cmd = new Command57("guide").description("Interactive guide center for Agentic Coding").option("--topic <topic>", "Open specific topic (intro, rules, workflows, prompts, skills)").action(async (options) => {
11635
11891
  const { waitUntilExit } = render6(
11636
11892
  React40.createElement(GuideApp, {
11637
11893
  initialTopic: options.topic,
@@ -11648,9 +11904,9 @@ function createGuideCommand() {
11648
11904
  // src/commands/context.ts
11649
11905
  import React41 from "react";
11650
11906
  import { render as render7 } from "ink";
11651
- import { Command as Command53 } from "commander";
11907
+ import { Command as Command58 } from "commander";
11652
11908
  function createContextCommand() {
11653
- const cmd = new Command53("context").description("Kh\xE1m ph\xE1 v\xE0 qu\u1EA3n l\xFD context d\u1EF1 \xE1n cho c\xE1c IDE").option("--ide <ide>", "M\u1EDF tr\u1EF1c ti\u1EBFp IDE c\u1EE5 th\u1EC3 (cursor, windsurf, antigravity, jai1)").option("--type <type>", "Hi\u1EC3n th\u1ECB lo\u1EA1i context c\u1EE5 th\u1EC3 (rules, workflows, skills, agents, prompts)").option("--stats", "Hi\u1EC3n th\u1ECB th\u1ED1ng k\xEA context (non-interactive)").action(async (options) => {
11909
+ const cmd = new Command58("context").description("Kh\xE1m ph\xE1 v\xE0 qu\u1EA3n l\xFD context d\u1EF1 \xE1n cho c\xE1c IDE").option("--ide <ide>", "M\u1EDF tr\u1EF1c ti\u1EBFp IDE c\u1EE5 th\u1EC3 (cursor, windsurf, antigravity, jai1)").option("--type <type>", "Hi\u1EC3n th\u1ECB lo\u1EA1i context c\u1EE5 th\u1EC3 (rules, workflows, skills, agents, prompts)").option("--stats", "Hi\u1EC3n th\u1ECB th\u1ED1ng k\xEA context (non-interactive)").action(async (options) => {
11654
11910
  let initialIDE;
11655
11911
  if (options.ide) {
11656
11912
  const validIDEs = ["cursor", "windsurf", "antigravity", "jai1"];
@@ -11727,10 +11983,10 @@ async function printStats2() {
11727
11983
  }
11728
11984
 
11729
11985
  // src/commands/migrate-ide.ts
11730
- import { Command as Command54 } from "commander";
11731
- import { checkbox as checkbox8, confirm as confirm14 } from "@inquirer/prompts";
11986
+ import { Command as Command59 } from "commander";
11987
+ import { checkbox as checkbox8, confirm as confirm15 } from "@inquirer/prompts";
11732
11988
  function createMigrateIdeCommand() {
11733
- const cmd = new Command54("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) => {
11989
+ const cmd = new Command59("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) => {
11734
11990
  await runMigrateIde(options);
11735
11991
  });
11736
11992
  return cmd;
@@ -11799,7 +12055,7 @@ async function runMigrateIde(options) {
11799
12055
  if (options.dryRun) {
11800
12056
  console.log("\u{1F50D} DRY RUN - No files will be written\n");
11801
12057
  }
11802
- const confirmed = await confirm14({
12058
+ const confirmed = await confirm15({
11803
12059
  message: "Proceed with migration?",
11804
12060
  default: true
11805
12061
  });
@@ -11836,7 +12092,7 @@ async function runMigrateIde(options) {
11836
12092
  }
11837
12093
 
11838
12094
  // src/cli.ts
11839
- var program = new Command55();
12095
+ var program = new Command60();
11840
12096
  if (process.argv.includes("-v") || process.argv.includes("--version")) {
11841
12097
  console.log(package_default.version);
11842
12098
  if (!process.argv.includes("--skip-update-check")) {
@@ -11857,15 +12113,16 @@ program.addCommand(createChatCommand());
11857
12113
  program.addCommand(createOpenAiKeysCommand());
11858
12114
  program.addCommand(createStatsCommand());
11859
12115
  program.addCommand(createTranslateCommand());
12116
+ program.addCommand(createImageCommand());
11860
12117
  program.addCommand(createUtilsCommand());
11861
12118
  program.addCommand(createDepsCommand());
11862
12119
  program.addCommand(createKitCommand());
11863
12120
  program.addCommand(createRulesCommand());
11864
12121
  program.addCommand(createUpgradeCommand());
11865
12122
  program.addCommand(createCleanCommand());
11866
- var redmineCommand = new Command55("redmine").description("Redmine context sync commands");
12123
+ var redmineCommand = new Command60("redmine").description("Redmine context sync commands");
11867
12124
  redmineCommand.addCommand(createRedmineCheckCommand());
11868
- var syncCommand = new Command55("sync").description("Sync Redmine issues to markdown files");
12125
+ var syncCommand = new Command60("sync").description("Sync Redmine issues to markdown files");
11869
12126
  syncCommand.addCommand(createSyncIssueCommand());
11870
12127
  syncCommand.addCommand(createSyncProjectCommand());
11871
12128
  redmineCommand.addCommand(syncCommand);