@jvittechs/jai1-cli 0.1.62 → 0.1.64

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
@@ -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.62",
36
+ version: "0.1.64",
37
37
  description: "Unified CLI for Jai1 Framework Management and Redmine Context Sync",
38
38
  type: "module",
39
39
  bin: {
@@ -894,9 +894,9 @@ var UnifiedApplyApp = ({
894
894
  (c) => c.filepath.toLowerCase().includes(query) || c.name.toLowerCase().includes(query) || c.tags && c.tags.some((t) => t.toLowerCase().includes(query))
895
895
  );
896
896
  }, [components, searchQuery]);
897
- useInput((input, key) => {
897
+ useInput((input2, key) => {
898
898
  if (viewState === "summary") {
899
- if (key.return || input === "q" || key.escape) {
899
+ if (key.return || input2 === "q" || key.escape) {
900
900
  onExit();
901
901
  }
902
902
  return;
@@ -910,7 +910,7 @@ var UnifiedApplyApp = ({
910
910
  else setFocusArea("search");
911
911
  return;
912
912
  }
913
- if (key.escape || input === "q") {
913
+ if (key.escape || input2 === "q") {
914
914
  onExit();
915
915
  return;
916
916
  }
@@ -925,7 +925,7 @@ var UnifiedApplyApp = ({
925
925
  setCursorIndex((prev) => Math.max(0, prev - 1));
926
926
  } else if (key.downArrow) {
927
927
  setCursorIndex((prev) => Math.min(filteredComponents.length - 1, prev + 1));
928
- } else if (input === " ") {
928
+ } else if (input2 === " ") {
929
929
  const current = filteredComponents[cursorIndex];
930
930
  if (current) {
931
931
  setSelectedPaths((prev) => {
@@ -938,13 +938,13 @@ var UnifiedApplyApp = ({
938
938
  return next;
939
939
  });
940
940
  }
941
- } else if (input === "a") {
941
+ } else if (input2 === "a") {
942
942
  setSelectedPaths((prev) => {
943
943
  const next = new Set(prev);
944
944
  filteredComponents.forEach((c) => next.add(c.filepath));
945
945
  return next;
946
946
  });
947
- } else if (input === "c") {
947
+ } else if (input2 === "c") {
948
948
  setSelectedPaths(/* @__PURE__ */ new Set());
949
949
  }
950
950
  }
@@ -953,7 +953,7 @@ var UnifiedApplyApp = ({
953
953
  setSelectedPackageIndex((prev) => Math.max(0, prev - 1));
954
954
  } else if (key.rightArrow) {
955
955
  setSelectedPackageIndex((prev) => Math.min(tags.length - 1, prev + 1));
956
- } else if (input === " " || key.return) {
956
+ } else if (input2 === " " || key.return) {
957
957
  const tag = tags[selectedPackageIndex];
958
958
  if (tag) {
959
959
  const packageComponents = components.filter((c) => c.tags?.includes(tag.tag));
@@ -1331,7 +1331,7 @@ var MainMenuView = ({ ideContexts, onSelect }) => {
1331
1331
  available: ideContexts.some((ctx) => ctx.ide === "jai1")
1332
1332
  }
1333
1333
  ];
1334
- useInput2((input, key) => {
1334
+ useInput2((input2, key) => {
1335
1335
  if (key.upArrow) {
1336
1336
  setSelectedIndex((prev) => Math.max(0, prev - 1));
1337
1337
  } else if (key.downArrow) {
@@ -1433,13 +1433,13 @@ var IDEOverviewView = ({
1433
1433
  count: ideContext.stats.byType.context
1434
1434
  });
1435
1435
  }
1436
- useInput3((input, key) => {
1436
+ useInput3((input2, key) => {
1437
1437
  if (key.tab || key.rightArrow) {
1438
1438
  setSelectedTabIndex((prev) => Math.min(tabs.length - 1, prev + 1));
1439
1439
  } else if (key.leftArrow) {
1440
1440
  setSelectedTabIndex((prev) => Math.max(0, prev - 1));
1441
1441
  }
1442
- const num = parseInt(input, 10);
1442
+ const num = parseInt(input2, 10);
1443
1443
  if (!isNaN(num) && num >= 1 && num <= tabs.length) {
1444
1444
  setSelectedTabIndex(num - 1);
1445
1445
  }
@@ -1501,7 +1501,7 @@ import React7, { useState as useState4 } from "react";
1501
1501
  import { Box as Box5, Text as Text6, useInput as useInput4 } from "ink";
1502
1502
  var ListView = ({ items, contentType, onSelect, onBack }) => {
1503
1503
  const [selectedIndex, setSelectedIndex] = useState4(0);
1504
- useInput4((input, key) => {
1504
+ useInput4((input2, key) => {
1505
1505
  if (key.upArrow) {
1506
1506
  setSelectedIndex((prev) => Math.max(0, prev - 1));
1507
1507
  } else if (key.downArrow) {
@@ -1552,18 +1552,18 @@ var DetailView = ({ item, scrollPosition: initialScroll, onBack }) => {
1552
1552
  const [scrollPosition, setScrollPosition] = useState5(initialScroll);
1553
1553
  const maxVisibleLines = 25;
1554
1554
  const maxScroll = Math.max(0, item.previewLines.length - maxVisibleLines);
1555
- useInput5((input, key) => {
1556
- if (key.upArrow || input === "k") {
1555
+ useInput5((input2, key) => {
1556
+ if (key.upArrow || input2 === "k") {
1557
1557
  setScrollPosition((prev) => Math.max(0, prev - 1));
1558
- } else if (key.downArrow || input === "j") {
1558
+ } else if (key.downArrow || input2 === "j") {
1559
1559
  setScrollPosition((prev) => Math.min(maxScroll, prev + 1));
1560
- } else if (key.pageDown || input === "d") {
1560
+ } else if (key.pageDown || input2 === "d") {
1561
1561
  setScrollPosition((prev) => Math.min(maxScroll, prev + 5));
1562
- } else if (key.pageUp || input === "u") {
1562
+ } else if (key.pageUp || input2 === "u") {
1563
1563
  setScrollPosition((prev) => Math.max(0, prev - 5));
1564
- } else if (input === "g") {
1564
+ } else if (input2 === "g") {
1565
1565
  setScrollPosition(0);
1566
- } else if (input === "G") {
1566
+ } else if (input2 === "G") {
1567
1567
  setScrollPosition(maxScroll);
1568
1568
  } else if (key.escape || key.backspace) {
1569
1569
  onBack();
@@ -1959,8 +1959,8 @@ var ContextApp = ({ initialIDE, initialType, onExit }) => {
1959
1959
  setLoading(false);
1960
1960
  });
1961
1961
  }, [initialIDE]);
1962
- useInput6((input, key) => {
1963
- if (input === "q") {
1962
+ useInput6((input2, key) => {
1963
+ if (input2 === "q") {
1964
1964
  onExit();
1965
1965
  return;
1966
1966
  }
@@ -2887,7 +2887,7 @@ var MENU_ITEMS = [
2887
2887
  ];
2888
2888
  var MenuView = ({ onSelect }) => {
2889
2889
  const [selectedIndex, setSelectedIndex] = useState7(0);
2890
- useInput7((input, key) => {
2890
+ useInput7((input2, key) => {
2891
2891
  if (key.upArrow) {
2892
2892
  setSelectedIndex((prev) => Math.max(0, prev - 1));
2893
2893
  } else if (key.downArrow) {
@@ -3500,7 +3500,7 @@ var AgenticGuideView = ({ onBack }) => {
3500
3500
  const [isTyping, setIsTyping] = useState8(false);
3501
3501
  const [selectedSuggestion, setSelectedSuggestion] = useState8(0);
3502
3502
  const [focusArea, setFocusArea] = useState8("input");
3503
- useInput8((input, key) => {
3503
+ useInput8((input2, key) => {
3504
3504
  if (key.escape) {
3505
3505
  onBack();
3506
3506
  return;
@@ -3632,7 +3632,7 @@ var GuideApp = ({ initialTopic, onExit }) => {
3632
3632
  setCurrentTopic(TOPIC_MAP[initialTopic]);
3633
3633
  }
3634
3634
  }, [initialTopic]);
3635
- useInput9((input, key) => {
3635
+ useInput9((input2, key) => {
3636
3636
  if (key.escape || currentTopic !== "menu" && key.backspace) {
3637
3637
  if (currentTopic === "menu") {
3638
3638
  onExit();
@@ -3642,7 +3642,7 @@ var GuideApp = ({ initialTopic, onExit }) => {
3642
3642
  }
3643
3643
  return;
3644
3644
  }
3645
- if (input === "q") {
3645
+ if (input2 === "q") {
3646
3646
  onExit();
3647
3647
  return;
3648
3648
  }
@@ -4137,7 +4137,7 @@ var ModelSelector = ({
4137
4137
  const allowedModels = models.filter((m) => m.allowed);
4138
4138
  const currentIndex = allowedModels.findIndex((m) => m.id === currentModel);
4139
4139
  const [selectedIndex, setSelectedIndex] = useState12(Math.max(0, currentIndex));
4140
- useInput10((input, key) => {
4140
+ useInput10((input2, key) => {
4141
4141
  if (key.escape) {
4142
4142
  onCancel();
4143
4143
  return;
@@ -4259,7 +4259,7 @@ var ChatApp = ({ service, initialModel }) => {
4259
4259
  }
4260
4260
  return false;
4261
4261
  }, [refetch, exit]);
4262
- useInput11((input, key) => {
4262
+ useInput11((input2, key) => {
4263
4263
  if (showSlashMenu) {
4264
4264
  if (key.upArrow) {
4265
4265
  setSlashMenuIndex((i) => Math.max(0, i - 1));
@@ -4460,9 +4460,9 @@ var TranslationService = class {
4460
4460
  /**
4461
4461
  * Detect input type
4462
4462
  */
4463
- async detectInputType(input) {
4463
+ async detectInputType(input2) {
4464
4464
  try {
4465
- const stat = await fs7.stat(input);
4465
+ const stat = await fs7.stat(input2);
4466
4466
  if (stat.isDirectory()) return "folder";
4467
4467
  if (stat.isFile()) return "file";
4468
4468
  } catch {
@@ -4694,7 +4694,7 @@ Return ONLY the translated content, no explanations.`;
4694
4694
  };
4695
4695
 
4696
4696
  // src/commands/translate.ts
4697
- async function handleTranslate(input, options) {
4697
+ async function handleTranslate(input2, options) {
4698
4698
  const configService = new ConfigService();
4699
4699
  const config = await configService.load();
4700
4700
  if (!config) {
@@ -4702,16 +4702,16 @@ async function handleTranslate(input, options) {
4702
4702
  }
4703
4703
  const llmService = new LlmProxyService(config);
4704
4704
  const translationService = new TranslationService(llmService, options, options.model);
4705
- const inputType = await translationService.detectInputType(input);
4705
+ const inputType = await translationService.detectInputType(input2);
4706
4706
  switch (inputType) {
4707
4707
  case "text":
4708
- await handleTextTranslation(translationService, input, options);
4708
+ await handleTextTranslation(translationService, input2, options);
4709
4709
  break;
4710
4710
  case "file":
4711
- await handleFileTranslation(translationService, input, options);
4711
+ await handleFileTranslation(translationService, input2, options);
4712
4712
  break;
4713
4713
  case "folder":
4714
- await handleFolderTranslation(translationService, input, options);
4714
+ await handleFolderTranslation(translationService, input2, options);
4715
4715
  break;
4716
4716
  }
4717
4717
  }
@@ -4788,8 +4788,8 @@ async function handleFolderTranslation(service, folderPath, options) {
4788
4788
  }
4789
4789
  }
4790
4790
  function createTranslateCommand() {
4791
- const cmd = new Command13("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 (input, options) => {
4792
- await handleTranslate(input, options);
4791
+ const cmd = new Command13("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 (input2, options) => {
4792
+ await handleTranslate(input2, options);
4793
4793
  });
4794
4794
  return cmd;
4795
4795
  }
@@ -4849,12 +4849,12 @@ var UtilsService = class {
4849
4849
  /**
4850
4850
  * Hash text or file using specified algorithm
4851
4851
  */
4852
- async hash(input, algorithm) {
4852
+ async hash(input2, algorithm) {
4853
4853
  if (algorithm === "bcrypt") {
4854
4854
  throw new Error("Use hashBcrypt for bcrypt algorithm");
4855
4855
  }
4856
4856
  const hash = crypto.createHash(algorithm);
4857
- hash.update(input);
4857
+ hash.update(input2);
4858
4858
  return hash.digest("hex");
4859
4859
  }
4860
4860
  /**
@@ -4867,14 +4867,14 @@ var UtilsService = class {
4867
4867
  /**
4868
4868
  * Hash using bcrypt
4869
4869
  */
4870
- async hashBcrypt(input, rounds = 10) {
4871
- return bcrypt.hash(input, rounds);
4870
+ async hashBcrypt(input2, rounds = 10) {
4871
+ return bcrypt.hash(input2, rounds);
4872
4872
  }
4873
4873
  /**
4874
4874
  * Base64 encode
4875
4875
  */
4876
- base64Encode(input, urlSafe = false) {
4877
- const buffer = typeof input === "string" ? Buffer.from(input, "utf-8") : input;
4876
+ base64Encode(input2, urlSafe = false) {
4877
+ const buffer = typeof input2 === "string" ? Buffer.from(input2, "utf-8") : input2;
4878
4878
  let encoded = buffer.toString("base64");
4879
4879
  if (urlSafe) {
4880
4880
  encoded = encoded.replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
@@ -4884,8 +4884,8 @@ var UtilsService = class {
4884
4884
  /**
4885
4885
  * Base64 decode
4886
4886
  */
4887
- base64Decode(input) {
4888
- let normalized = input.replace(/-/g, "+").replace(/_/g, "/");
4887
+ base64Decode(input2) {
4888
+ let normalized = input2.replace(/-/g, "+").replace(/_/g, "/");
4889
4889
  while (normalized.length % 4) {
4890
4890
  normalized += "=";
4891
4891
  }
@@ -5014,14 +5014,14 @@ var UtilsService = class {
5014
5014
  /**
5015
5015
  * URL encode
5016
5016
  */
5017
- urlEncode(input, full = false) {
5018
- return full ? encodeURI(input) : encodeURIComponent(input);
5017
+ urlEncode(input2, full = false) {
5018
+ return full ? encodeURI(input2) : encodeURIComponent(input2);
5019
5019
  }
5020
5020
  /**
5021
5021
  * URL decode
5022
5022
  */
5023
- urlDecode(input, full = false) {
5024
- return full ? decodeURI(input) : decodeURIComponent(input);
5023
+ urlDecode(input2, full = false) {
5024
+ return full ? decodeURI(input2) : decodeURIComponent(input2);
5025
5025
  }
5026
5026
  /**
5027
5027
  * Format bytes to human-readable size
@@ -5131,7 +5131,7 @@ Examples:
5131
5131
 
5132
5132
  // src/commands/utils/hash.ts
5133
5133
  import { Command as Command16 } from "commander";
5134
- async function handleHashGeneration(input, options) {
5134
+ async function handleHashGeneration(input2, options) {
5135
5135
  const service = new UtilsService();
5136
5136
  try {
5137
5137
  let hash;
@@ -5142,14 +5142,14 @@ async function handleHashGeneration(input, options) {
5142
5142
  }
5143
5143
  hash = await service.hashFile(options.file, options.algorithm);
5144
5144
  } else {
5145
- if (!input) {
5145
+ if (!input2) {
5146
5146
  console.error("\u274C Please provide input text or use --file option");
5147
5147
  process.exit(1);
5148
5148
  }
5149
5149
  if (options.algorithm === "bcrypt") {
5150
- hash = await service.hashBcrypt(input, options.rounds);
5150
+ hash = await service.hashBcrypt(input2, options.rounds);
5151
5151
  } else {
5152
- hash = await service.hash(input, options.algorithm);
5152
+ hash = await service.hash(input2, options.algorithm);
5153
5153
  }
5154
5154
  }
5155
5155
  console.log("\u{1F512} Hash Result:");
@@ -5182,8 +5182,8 @@ Examples:
5182
5182
  $ jai1 utils hash "password" --algorithm bcrypt --rounds 12
5183
5183
  $ jai1 utils hash --file ./myfile.txt
5184
5184
  $ jai1 utils hash --file ./image.png --algorithm sha512
5185
- `).action(async (input, options) => {
5186
- await handleHashGeneration(input, {
5185
+ `).action(async (input2, options) => {
5186
+ await handleHashGeneration(input2, {
5187
5187
  ...options,
5188
5188
  rounds: parseInt(options.rounds, 10)
5189
5189
  });
@@ -5194,7 +5194,7 @@ Examples:
5194
5194
  // src/commands/utils/base64-encode.ts
5195
5195
  import { Command as Command17 } from "commander";
5196
5196
  import { readFile as readFile2 } from "fs/promises";
5197
- async function handleBase64Encode(input, options) {
5197
+ async function handleBase64Encode(input2, options) {
5198
5198
  const service = new UtilsService();
5199
5199
  try {
5200
5200
  let encoded;
@@ -5202,11 +5202,11 @@ async function handleBase64Encode(input, options) {
5202
5202
  const content = await readFile2(options.file);
5203
5203
  encoded = service.base64Encode(content, options.urlSafe);
5204
5204
  } else {
5205
- if (!input) {
5205
+ if (!input2) {
5206
5206
  console.error("\u274C Please provide input text or use --file option");
5207
5207
  process.exit(1);
5208
5208
  }
5209
- encoded = service.base64Encode(input, options.urlSafe);
5209
+ encoded = service.base64Encode(input2, options.urlSafe);
5210
5210
  }
5211
5211
  console.log("\u{1F4DD} Base64 Encoded:");
5212
5212
  console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
@@ -5231,8 +5231,8 @@ Examples:
5231
5231
  $ jai1 utils base64-encode "hello world" --url-safe
5232
5232
  $ jai1 utils base64-encode --file ./document.txt
5233
5233
  $ jai1 utils base64-encode --file ./image.png
5234
- `).action(async (input, options) => {
5235
- await handleBase64Encode(input, options);
5234
+ `).action(async (input2, options) => {
5235
+ await handleBase64Encode(input2, options);
5236
5236
  });
5237
5237
  return cmd;
5238
5238
  }
@@ -5240,18 +5240,18 @@ Examples:
5240
5240
  // src/commands/utils/base64-decode.ts
5241
5241
  import { Command as Command18 } from "commander";
5242
5242
  import { readFile as readFile3, writeFile } from "fs/promises";
5243
- async function handleBase64Decode(input, options) {
5243
+ async function handleBase64Decode(input2, options) {
5244
5244
  const service = new UtilsService();
5245
5245
  try {
5246
5246
  let encodedInput;
5247
5247
  if (options.file) {
5248
5248
  encodedInput = await readFile3(options.file, "utf-8");
5249
5249
  } else {
5250
- if (!input) {
5250
+ if (!input2) {
5251
5251
  console.error("\u274C Please provide Base64 input or use --file option");
5252
5252
  process.exit(1);
5253
5253
  }
5254
- encodedInput = input;
5254
+ encodedInput = input2;
5255
5255
  }
5256
5256
  const decoded = service.base64Decode(encodedInput.trim());
5257
5257
  if (options.output) {
@@ -5276,8 +5276,8 @@ Examples:
5276
5276
  $ jai1 utils base64-decode --file ./encoded.txt
5277
5277
  $ jai1 utils base64-decode "aGVsbG8=" --output ./decoded.txt
5278
5278
  $ jai1 utils base64-decode --file ./encoded.txt --output ./image.png
5279
- `).action(async (input, options) => {
5280
- await handleBase64Decode(input, options);
5279
+ `).action(async (input2, options) => {
5280
+ await handleBase64Decode(input2, options);
5281
5281
  });
5282
5282
  return cmd;
5283
5283
  }
@@ -5428,10 +5428,10 @@ Examples:
5428
5428
 
5429
5429
  // src/commands/utils/unix-time.ts
5430
5430
  import { Command as Command21 } from "commander";
5431
- async function handleUnixTime(input, options) {
5431
+ async function handleUnixTime(input2, options) {
5432
5432
  const service = new UtilsService();
5433
5433
  try {
5434
- if (!input) {
5434
+ if (!input2) {
5435
5435
  const now = /* @__PURE__ */ new Date();
5436
5436
  const timestamp = service.dateToUnix(now, options.ms);
5437
5437
  console.log("\u{1F552} Current Unix Timestamp:");
@@ -5441,8 +5441,8 @@ async function handleUnixTime(input, options) {
5441
5441
  console.log(` ISO: ${now.toISOString()}`);
5442
5442
  console.log(` Local: ${now.toLocaleString()}`);
5443
5443
  console.log();
5444
- } else if (/^\d+$/.test(input)) {
5445
- const timestamp = parseInt(input, 10);
5444
+ } else if (/^\d+$/.test(input2)) {
5445
+ const timestamp = parseInt(input2, 10);
5446
5446
  const date = service.unixToDate(timestamp, options.ms);
5447
5447
  console.log("\u{1F552} Unix Timestamp to Date:");
5448
5448
  console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
@@ -5455,7 +5455,7 @@ async function handleUnixTime(input, options) {
5455
5455
  }
5456
5456
  console.log();
5457
5457
  } else {
5458
- const date = new Date(input);
5458
+ const date = new Date(input2);
5459
5459
  if (isNaN(date.getTime())) {
5460
5460
  console.error("\u274C Invalid date format");
5461
5461
  process.exit(1);
@@ -5463,7 +5463,7 @@ async function handleUnixTime(input, options) {
5463
5463
  const timestamp = service.dateToUnix(date, options.ms);
5464
5464
  console.log("\u{1F552} Date to Unix Timestamp:");
5465
5465
  console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
5466
- console.log(` Input: ${input}`);
5466
+ console.log(` Input: ${input2}`);
5467
5467
  console.log(` Parsed: ${date.toISOString()}`);
5468
5468
  console.log();
5469
5469
  console.log(` ${timestamp}${options.ms ? " (ms)" : ""}`);
@@ -5483,8 +5483,8 @@ Examples:
5483
5483
  $ jai1 utils unix-time "2024-01-15 10:30:00"
5484
5484
  $ jai1 utils unix-time "2024-01-15" --format local
5485
5485
  $ jai1 utils unix-time --ms
5486
- `).action(async (input, options) => {
5487
- await handleUnixTime(input, options);
5486
+ `).action(async (input2, options) => {
5487
+ await handleUnixTime(input2, options);
5488
5488
  });
5489
5489
  return cmd;
5490
5490
  }
@@ -5541,10 +5541,10 @@ Examples:
5541
5541
 
5542
5542
  // src/commands/utils/url-encode.ts
5543
5543
  import { Command as Command23 } from "commander";
5544
- async function handleUrlEncode(input, options) {
5544
+ async function handleUrlEncode(input2, options) {
5545
5545
  const service = new UtilsService();
5546
5546
  try {
5547
- const encoded = service.urlEncode(input, options.full);
5547
+ const encoded = service.urlEncode(input2, options.full);
5548
5548
  console.log("\u{1F517} URL Encoded:");
5549
5549
  console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
5550
5550
  if (options.full) {
@@ -5567,18 +5567,18 @@ Examples:
5567
5567
  $ jai1 utils url-encode "hello world & test"
5568
5568
  $ jai1 utils url-encode "name=John Doe&age=30"
5569
5569
  $ jai1 utils url-encode "https://example.com/path with spaces" --full
5570
- `).showHelpAfterError("(add --help for additional examples)").action(async (input, options) => {
5571
- await handleUrlEncode(input, options);
5570
+ `).showHelpAfterError("(add --help for additional examples)").action(async (input2, options) => {
5571
+ await handleUrlEncode(input2, options);
5572
5572
  });
5573
5573
  return cmd;
5574
5574
  }
5575
5575
 
5576
5576
  // src/commands/utils/url-decode.ts
5577
5577
  import { Command as Command24 } from "commander";
5578
- async function handleUrlDecode(input, options) {
5578
+ async function handleUrlDecode(input2, options) {
5579
5579
  const service = new UtilsService();
5580
5580
  try {
5581
- const decoded = service.urlDecode(input, options.full);
5581
+ const decoded = service.urlDecode(input2, options.full);
5582
5582
  console.log("\u{1F517} URL Decoded:");
5583
5583
  console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
5584
5584
  if (options.full) {
@@ -5601,8 +5601,8 @@ Examples:
5601
5601
  $ jai1 utils url-decode "hello%20world%20%26%20test"
5602
5602
  $ jai1 utils url-decode "name%3DJohn%20Doe%26age%3D30"
5603
5603
  $ jai1 utils url-decode "https://example.com/path%20with%20spaces" --full
5604
- `).showHelpAfterError("(add --help for additional examples)").action(async (input, options) => {
5605
- await handleUrlDecode(input, options);
5604
+ `).showHelpAfterError("(add --help for additional examples)").action(async (input2, options) => {
5605
+ await handleUrlDecode(input2, options);
5606
5606
  });
5607
5607
  return cmd;
5608
5608
  }
@@ -5671,13 +5671,24 @@ import { marked } from "marked";
5671
5671
  import TerminalRenderer from "marked-terminal";
5672
5672
  async function handleMarkdownPreview(file, options) {
5673
5673
  try {
5674
- const content = await readFile5(file, "utf-8");
5674
+ let content = await readFile5(file, "utf-8");
5675
5675
  if (options.raw) {
5676
5676
  console.log("\u{1F4C4} Markdown File (Raw):");
5677
5677
  console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n");
5678
5678
  console.log(content);
5679
5679
  console.log();
5680
5680
  } else {
5681
+ content = content.replace(/```mermaid\n([\s\S]*?)```/g, (match, code) => {
5682
+ return `
5683
+ \u{1F3A8} **Mermaid Diagram**
5684
+
5685
+ \`\`\`
5686
+ ${code.trim()}
5687
+ \`\`\`
5688
+
5689
+ \u{1F4A1} *Tip: Mermaid diagrams cannot be rendered in terminal. View in a Markdown viewer.*
5690
+ `;
5691
+ });
5681
5692
  marked.setOptions({
5682
5693
  // @ts-ignore - marked-terminal types may not match perfectly
5683
5694
  renderer: new TerminalRenderer()
@@ -5705,9 +5716,388 @@ Examples:
5705
5716
  return cmd;
5706
5717
  }
5707
5718
 
5719
+ // src/commands/utils/interactive.ts
5720
+ import { select as select2, input, confirm as confirm4 } from "@inquirer/prompts";
5721
+ var MENU_ITEMS2 = [
5722
+ { name: "\u{1F510} Generate Password", value: "password", description: "Create secure random passwords" },
5723
+ { name: "\u{1F194} Generate UUID", value: "uuid", description: "Generate UUID v4 identifiers" },
5724
+ { name: "\u{1F512} Generate Hash", value: "hash", description: "Hash text with MD5/SHA/bcrypt" },
5725
+ { name: "\u{1F4DD} Base64 Encode", value: "base64-encode", description: "Encode text to Base64" },
5726
+ { name: "\u{1F4DD} Base64 Decode", value: "base64-decode", description: "Decode Base64 strings" },
5727
+ { name: "\u{1F310} HTTP Request", value: "http", description: "Make HTTP requests with formatted output" },
5728
+ { name: "\u{1F511} JWT Decode/Encode", value: "jwt", description: "Work with JWT tokens" },
5729
+ { name: "\u{1F552} Unix Time", value: "unix-time", description: "Convert unix timestamps" },
5730
+ { name: "\u{1F30D} Timezone Convert", value: "timezone", description: "Convert between timezones" },
5731
+ { name: "\u{1F517} URL Encode", value: "url-encode", description: "Encode URL components" },
5732
+ { name: "\u{1F517} URL Decode", value: "url-decode", description: "Decode URL components" },
5733
+ { name: "\u23F0 Cron Parser", value: "cron", description: "Parse cron expressions" },
5734
+ { name: "\u{1F4C4} Markdown Preview", value: "markdown", description: "Preview markdown files" },
5735
+ { name: "\u274C Exit", value: "exit", description: "Exit interactive mode" }
5736
+ ];
5737
+ async function runInteractiveMode() {
5738
+ const service = new UtilsService();
5739
+ console.log("\n\u{1F6E0}\uFE0F Developer Utilities - Interactive Mode\n");
5740
+ let running = true;
5741
+ while (running) {
5742
+ const choice = await select2({
5743
+ message: "Select a utility:",
5744
+ choices: MENU_ITEMS2
5745
+ });
5746
+ if (choice === "exit") {
5747
+ console.log("\n\u{1F44B} Goodbye!\n");
5748
+ running = false;
5749
+ break;
5750
+ }
5751
+ try {
5752
+ switch (choice) {
5753
+ case "password":
5754
+ await handlePasswordInteractive(service);
5755
+ break;
5756
+ case "uuid":
5757
+ await handleUuidInteractive(service);
5758
+ break;
5759
+ case "hash":
5760
+ await handleHashInteractive(service);
5761
+ break;
5762
+ case "base64-encode":
5763
+ await handleBase64EncodeInteractive(service);
5764
+ break;
5765
+ case "base64-decode":
5766
+ await handleBase64DecodeInteractive(service);
5767
+ break;
5768
+ case "http":
5769
+ await handleHttpInteractive(service);
5770
+ break;
5771
+ case "jwt":
5772
+ await handleJwtInteractive(service);
5773
+ break;
5774
+ case "unix-time":
5775
+ await handleUnixTimeInteractive(service);
5776
+ break;
5777
+ case "timezone":
5778
+ await handleTimezoneInteractive(service);
5779
+ break;
5780
+ case "url-encode":
5781
+ await handleUrlEncodeInteractive(service);
5782
+ break;
5783
+ case "url-decode":
5784
+ await handleUrlDecodeInteractive(service);
5785
+ break;
5786
+ case "cron":
5787
+ await handleCronInteractive(service);
5788
+ break;
5789
+ case "markdown":
5790
+ await handleMarkdownInteractive();
5791
+ break;
5792
+ }
5793
+ const continueChoice = await confirm4({
5794
+ message: "Continue with another utility?",
5795
+ default: true
5796
+ });
5797
+ if (!continueChoice) {
5798
+ console.log("\n\u{1F44B} Goodbye!\n");
5799
+ running = false;
5800
+ } else {
5801
+ console.log("");
5802
+ }
5803
+ } catch (error) {
5804
+ if (error instanceof Error && error.message.includes("User force closed")) {
5805
+ console.log("\n\n\u{1F44B} Goodbye!\n");
5806
+ running = false;
5807
+ } else {
5808
+ console.error("\n\u274C Error:", error instanceof Error ? error.message : String(error));
5809
+ console.log("");
5810
+ }
5811
+ }
5812
+ }
5813
+ }
5814
+ async function handlePasswordInteractive(service) {
5815
+ const length = await input({
5816
+ message: "Password length:",
5817
+ default: "16"
5818
+ });
5819
+ const count = await input({
5820
+ message: "Number of passwords:",
5821
+ default: "1"
5822
+ });
5823
+ const passwords = [];
5824
+ for (let i = 0; i < parseInt(count, 10); i++) {
5825
+ passwords.push(
5826
+ service.generatePassword({
5827
+ length: parseInt(length, 10),
5828
+ lowercase: true,
5829
+ uppercase: true,
5830
+ digits: true,
5831
+ symbols: true
5832
+ })
5833
+ );
5834
+ }
5835
+ console.log("\n\u{1F510} Generated Password(s):");
5836
+ console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
5837
+ passwords.forEach((p, i) => {
5838
+ console.log(`${passwords.length > 1 ? `${i + 1}. ` : ""}${p}`);
5839
+ });
5840
+ console.log("");
5841
+ }
5842
+ async function handleUuidInteractive(service) {
5843
+ const count = await input({
5844
+ message: "Number of UUIDs:",
5845
+ default: "1"
5846
+ });
5847
+ const uuids = [];
5848
+ for (let i = 0; i < parseInt(count, 10); i++) {
5849
+ uuids.push(service.generateUuid());
5850
+ }
5851
+ console.log("\n\u{1F194} Generated UUID(s):");
5852
+ console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
5853
+ uuids.forEach((u, i) => {
5854
+ console.log(`${uuids.length > 1 ? `${i + 1}. ` : ""}${u}`);
5855
+ });
5856
+ console.log("");
5857
+ }
5858
+ async function handleHashInteractive(service) {
5859
+ const text = await input({
5860
+ message: "Text to hash:"
5861
+ });
5862
+ const algorithm = await select2({
5863
+ message: "Hash algorithm:",
5864
+ choices: [
5865
+ { name: "SHA-256 (recommended)", value: "sha256" },
5866
+ { name: "SHA-512", value: "sha512" },
5867
+ { name: "SHA-1", value: "sha1" },
5868
+ { name: "MD5", value: "md5" },
5869
+ { name: "bcrypt", value: "bcrypt" }
5870
+ ]
5871
+ });
5872
+ let hash;
5873
+ if (algorithm === "bcrypt") {
5874
+ hash = await service.hashBcrypt(text, 10);
5875
+ } else {
5876
+ hash = await service.hash(text, algorithm);
5877
+ }
5878
+ console.log("\n\u{1F512} Hash Result:");
5879
+ console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
5880
+ console.log(`Algorithm: ${algorithm.toUpperCase()}`);
5881
+ console.log("");
5882
+ console.log(hash);
5883
+ console.log("");
5884
+ }
5885
+ async function handleBase64EncodeInteractive(service) {
5886
+ const text = await input({
5887
+ message: "Text to encode:"
5888
+ });
5889
+ const encoded = service.base64Encode(text);
5890
+ console.log("\n\u{1F4DD} Base64 Encoded:");
5891
+ console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
5892
+ console.log(encoded);
5893
+ console.log("");
5894
+ }
5895
+ async function handleBase64DecodeInteractive(service) {
5896
+ const text = await input({
5897
+ message: "Base64 string to decode:"
5898
+ });
5899
+ try {
5900
+ const decoded = service.base64Decode(text);
5901
+ console.log("\n\u{1F4DD} Base64 Decoded:");
5902
+ console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
5903
+ console.log(decoded.toString("utf-8"));
5904
+ console.log("");
5905
+ } catch (error) {
5906
+ console.error("\n\u274C Invalid Base64 string");
5907
+ console.log("");
5908
+ }
5909
+ }
5910
+ async function handleHttpInteractive(service) {
5911
+ const url = await input({
5912
+ message: "URL:",
5913
+ default: "https://api.github.com"
5914
+ });
5915
+ const method = await select2({
5916
+ message: "HTTP Method:",
5917
+ choices: [
5918
+ { name: "GET", value: "GET" },
5919
+ { name: "POST", value: "POST" },
5920
+ { name: "PUT", value: "PUT" },
5921
+ { name: "DELETE", value: "DELETE" }
5922
+ ],
5923
+ default: "GET"
5924
+ });
5925
+ const response = await service.httpRequest(url, {
5926
+ method,
5927
+ followRedirects: true
5928
+ });
5929
+ console.log("\n\u{1F310} HTTP Response:");
5930
+ console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
5931
+ console.log(`Status: ${response.status} ${response.statusText}`);
5932
+ console.log(`Time: ${response.timing}ms`);
5933
+ console.log(`Size: ${service.formatBytes(response.size)}`);
5934
+ console.log("");
5935
+ try {
5936
+ const json = JSON.parse(response.body);
5937
+ console.log(JSON.stringify(json, null, 2));
5938
+ } catch {
5939
+ console.log(response.body.substring(0, 500));
5940
+ }
5941
+ console.log("");
5942
+ }
5943
+ async function handleJwtInteractive(service) {
5944
+ const action = await select2({
5945
+ message: "JWT Action:",
5946
+ choices: [
5947
+ { name: "Decode JWT", value: "decode" },
5948
+ { name: "Encode JWT", value: "encode" }
5949
+ ]
5950
+ });
5951
+ if (action === "decode") {
5952
+ const token = await input({
5953
+ message: "JWT token:"
5954
+ });
5955
+ const { header, payload } = service.jwtDecode(token);
5956
+ console.log("\n\u{1F513} JWT Decoded:");
5957
+ console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
5958
+ console.log("\nHeader:");
5959
+ console.log(JSON.stringify(header, null, 2));
5960
+ console.log("\nPayload:");
5961
+ console.log(JSON.stringify(payload, null, 2));
5962
+ console.log("");
5963
+ } else {
5964
+ const payload = await input({
5965
+ message: "Payload (JSON):",
5966
+ default: '{"sub":"123","name":"User"}'
5967
+ });
5968
+ const secret = await input({
5969
+ message: "Secret key:",
5970
+ default: "mysecret"
5971
+ });
5972
+ const token = service.jwtEncode(JSON.parse(payload), secret);
5973
+ console.log("\n\u{1F510} JWT Encoded:");
5974
+ console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
5975
+ console.log(token);
5976
+ console.log("");
5977
+ }
5978
+ }
5979
+ async function handleUnixTimeInteractive(service) {
5980
+ const input_text = await input({
5981
+ message: "Unix timestamp or date (leave empty for current):",
5982
+ default: ""
5983
+ });
5984
+ if (!input_text) {
5985
+ const now = /* @__PURE__ */ new Date();
5986
+ const timestamp = service.dateToUnix(now, false);
5987
+ console.log("\n\u{1F552} Current Unix Timestamp:");
5988
+ console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
5989
+ console.log(`Timestamp: ${timestamp}`);
5990
+ console.log(`ISO: ${now.toISOString()}`);
5991
+ console.log(`Local: ${now.toLocaleString()}`);
5992
+ console.log("");
5993
+ } else if (/^\d+$/.test(input_text)) {
5994
+ const timestamp = parseInt(input_text, 10);
5995
+ const date = service.unixToDate(timestamp, false);
5996
+ console.log("\n\u{1F552} Unix to Date:");
5997
+ console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
5998
+ console.log(`Timestamp: ${timestamp}`);
5999
+ console.log(`ISO: ${date.toISOString()}`);
6000
+ console.log(`Local: ${date.toLocaleString()}`);
6001
+ console.log("");
6002
+ } else {
6003
+ const date = new Date(input_text);
6004
+ const timestamp = service.dateToUnix(date, false);
6005
+ console.log("\n\u{1F552} Date to Unix:");
6006
+ console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
6007
+ console.log(`Input: ${input_text}`);
6008
+ console.log(`Timestamp: ${timestamp}`);
6009
+ console.log("");
6010
+ }
6011
+ }
6012
+ async function handleTimezoneInteractive(service) {
6013
+ const showList = await confirm4({
6014
+ message: "Show available timezones?",
6015
+ default: false
6016
+ });
6017
+ if (showList) {
6018
+ console.log("\n\u{1F30D} Available Timezones:");
6019
+ console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
6020
+ service.getTimezones().forEach((tz) => console.log(` ${tz}`));
6021
+ console.log("");
6022
+ return;
6023
+ }
6024
+ const time = await input({
6025
+ message: "Time to convert:",
6026
+ default: (/* @__PURE__ */ new Date()).toISOString()
6027
+ });
6028
+ const from = await input({
6029
+ message: "From timezone:",
6030
+ default: "UTC"
6031
+ });
6032
+ const to = await input({
6033
+ message: "To timezone:",
6034
+ default: "America/New_York"
6035
+ });
6036
+ const result = service.convertTimezone(time, from, to);
6037
+ console.log("\n\u{1F30D} Timezone Conversion:");
6038
+ console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
6039
+ console.log(`From: ${from}`);
6040
+ console.log(`To: ${to}`);
6041
+ console.log("");
6042
+ console.log(result.time);
6043
+ console.log(`ISO: ${result.iso}`);
6044
+ console.log("");
6045
+ }
6046
+ async function handleUrlEncodeInteractive(service) {
6047
+ const text = await input({
6048
+ message: "Text to encode:"
6049
+ });
6050
+ const encoded = service.urlEncode(text);
6051
+ console.log("\n\u{1F517} URL Encoded:");
6052
+ console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
6053
+ console.log(encoded);
6054
+ console.log("");
6055
+ }
6056
+ async function handleUrlDecodeInteractive(service) {
6057
+ const text = await input({
6058
+ message: "URL encoded text:"
6059
+ });
6060
+ const decoded = service.urlDecode(text);
6061
+ console.log("\n\u{1F517} URL Decoded:");
6062
+ console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
6063
+ console.log(decoded);
6064
+ console.log("");
6065
+ }
6066
+ async function handleCronInteractive(service) {
6067
+ const expression = await input({
6068
+ message: "Cron expression:",
6069
+ default: "0 5 * * *"
6070
+ });
6071
+ const cronstrue2 = await import("cronstrue");
6072
+ const description = cronstrue2.default.toString(expression);
6073
+ console.log("\n\u23F0 Cron Expression:");
6074
+ console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
6075
+ console.log(`Expression: ${expression}`);
6076
+ console.log(`Meaning: ${description}`);
6077
+ console.log("");
6078
+ }
6079
+ async function handleMarkdownInteractive() {
6080
+ const filePath = await input({
6081
+ message: "Markdown file path:",
6082
+ default: "README.md"
6083
+ });
6084
+ console.log("\n\u{1F4A1} Tip: Use the command: jai1 utils markdown-preview " + filePath);
6085
+ console.log("");
6086
+ }
6087
+
5708
6088
  // src/commands/utils/index.ts
5709
6089
  function createUtilsCommand() {
5710
- const utilsCommand = new Command27("utils").description("Developer utilities for common tasks");
6090
+ const utilsCommand = new Command27("utils").description("Developer utilities for common tasks").option("-i, --interactive", "Run in interactive mode").addHelpText("after", `
6091
+ Interactive Mode:
6092
+ $ jai1 utils --interactive
6093
+ $ jai1 utils -i
6094
+
6095
+ Quick Usage:
6096
+ $ jai1 utils password --length 24
6097
+ $ jai1 utils uuid --count 5
6098
+ $ jai1 utils hash "text" --algorithm sha256
6099
+ $ jai1 utils http https://api.example.com
6100
+ `);
5711
6101
  utilsCommand.addCommand(createPasswordCommand());
5712
6102
  utilsCommand.addCommand(createUuidCommand());
5713
6103
  utilsCommand.addCommand(createHashCommand());
@@ -5721,15 +6111,19 @@ function createUtilsCommand() {
5721
6111
  utilsCommand.addCommand(createUrlDecodeCommand());
5722
6112
  utilsCommand.addCommand(createCronCommand());
5723
6113
  utilsCommand.addCommand(createMarkdownPreviewCommand());
5724
- utilsCommand.action(() => {
5725
- utilsCommand.help();
6114
+ utilsCommand.action(async (options) => {
6115
+ if (options.interactive) {
6116
+ await runInteractiveMode();
6117
+ } else {
6118
+ utilsCommand.help();
6119
+ }
5726
6120
  });
5727
6121
  return utilsCommand;
5728
6122
  }
5729
6123
 
5730
6124
  // src/commands/upgrade.ts
5731
6125
  import { Command as Command28 } from "commander";
5732
- import { confirm as confirm4 } from "@inquirer/prompts";
6126
+ import { confirm as confirm5 } from "@inquirer/prompts";
5733
6127
  import { execSync } from "child_process";
5734
6128
  var colors2 = {
5735
6129
  yellow: "\x1B[33m",
@@ -5784,7 +6178,7 @@ ${colors2.bold}Current version:${colors2.reset} ${currentVersion}`);
5784
6178
  return;
5785
6179
  }
5786
6180
  if (!options.force) {
5787
- const shouldUpdate = await confirm4({
6181
+ const shouldUpdate = await confirm5({
5788
6182
  message: "Update to the latest version now?",
5789
6183
  default: true
5790
6184
  });
@@ -5889,7 +6283,7 @@ function getInstallCommand(packageManager2) {
5889
6283
 
5890
6284
  // src/commands/clean.ts
5891
6285
  import { Command as Command29 } from "commander";
5892
- import { confirm as confirm5, select as select2 } from "@inquirer/prompts";
6286
+ import { confirm as confirm6, select as select3 } from "@inquirer/prompts";
5893
6287
  import { join as join4 } from "path";
5894
6288
  function createCleanCommand() {
5895
6289
  return new Command29("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) => {
@@ -5953,7 +6347,7 @@ async function handleClean(options) {
5953
6347
  console.log(` Path: ${target.path}
5954
6348
  `);
5955
6349
  }
5956
- const action = await select2({
6350
+ const action = await select3({
5957
6351
  message: "What do you want to clean?",
5958
6352
  choices: [
5959
6353
  ...availableTargets.map(({ target, info }) => ({
@@ -5987,7 +6381,7 @@ async function cleanTarget(target, skipConfirm) {
5987
6381
  }
5988
6382
  const countStr = info.count ? ` (${info.count} items)` : "";
5989
6383
  if (!skipConfirm) {
5990
- const confirmed = await confirm5({
6384
+ const confirmed = await confirm6({
5991
6385
  message: `Delete ${target.name}${countStr}?`,
5992
6386
  default: false
5993
6387
  });
@@ -6947,7 +7341,7 @@ async function getProjectStatus2() {
6947
7341
 
6948
7342
  // src/commands/self-update.ts
6949
7343
  import { Command as Command34 } from "commander";
6950
- import { confirm as confirm6 } from "@inquirer/prompts";
7344
+ import { confirm as confirm7 } from "@inquirer/prompts";
6951
7345
  import { execSync as execSync2 } from "child_process";
6952
7346
  var colors3 = {
6953
7347
  yellow: "\x1B[33m",
@@ -7002,7 +7396,7 @@ ${colors3.bold}Current version:${colors3.reset} ${currentVersion}`);
7002
7396
  return;
7003
7397
  }
7004
7398
  if (!options.force) {
7005
- const shouldUpdate = await confirm6({
7399
+ const shouldUpdate = await confirm7({
7006
7400
  message: "Update to the latest version now?",
7007
7401
  default: true
7008
7402
  });
@@ -7099,7 +7493,7 @@ function getInstallCommand2(packageManager2) {
7099
7493
 
7100
7494
  // src/commands/clear-backups.ts
7101
7495
  import { Command as Command35 } from "commander";
7102
- import { confirm as confirm7 } from "@inquirer/prompts";
7496
+ import { confirm as confirm8 } from "@inquirer/prompts";
7103
7497
  function createClearBackupsCommand() {
7104
7498
  return new Command35("clear-backups").description("Clear backup files").option("-y, --yes", "Skip confirmation").action(async (options) => {
7105
7499
  const service = new ComponentsService();
@@ -7117,7 +7511,7 @@ function createClearBackupsCommand() {
7117
7511
  }
7118
7512
  console.log();
7119
7513
  if (!options.yes) {
7120
- const ok = await confirm7({ message: "Delete all backups?", default: false });
7514
+ const ok = await confirm8({ message: "Delete all backups?", default: false });
7121
7515
  if (!ok) return;
7122
7516
  }
7123
7517
  await service.clearBackups(process.cwd());
@@ -7127,7 +7521,7 @@ function createClearBackupsCommand() {
7127
7521
 
7128
7522
  // src/commands/vscode/index.ts
7129
7523
  import { Command as Command36 } from "commander";
7130
- import { checkbox as checkbox3, confirm as confirm8, select as select3 } from "@inquirer/prompts";
7524
+ import { checkbox as checkbox3, confirm as confirm9, select as select4 } from "@inquirer/prompts";
7131
7525
  import fs9 from "fs/promises";
7132
7526
  import path5 from "path";
7133
7527
  import { existsSync as existsSync2 } from "fs";
@@ -7310,7 +7704,7 @@ async function interactiveMode2() {
7310
7704
  console.log("\u2502 \u2022 Nh\u1EA5n ENTER \u0111\u1EC3 x\xE1c nh\u1EADn v\xE0 \xE1p d\u1EE5ng \u2502");
7311
7705
  console.log("\u2502 \u2022 Nh\u1EA5n Ctrl+C \u0111\u1EC3 h\u1EE7y \u2502");
7312
7706
  console.log("\u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256F\n");
7313
- const action = await select3({
7707
+ const action = await select4({
7314
7708
  message: "B\u1EA1n mu\u1ED1n l\xE0m g\xEC?",
7315
7709
  choices: [
7316
7710
  { name: "\u2705 Enable c\xE1c nh\xF3m t\u1ED1i \u01B0u", value: "enable" },
@@ -7370,7 +7764,7 @@ async function applyGroups2(groupKeys, action) {
7370
7764
  console.log("\u{1F4C4} \u0110\xE3 \u0111\u1ECDc c\xE0i \u0111\u1EB7t hi\u1EC7n t\u1EA1i t\u1EEB settings.json");
7371
7765
  } catch {
7372
7766
  console.warn("\u26A0\uFE0F Kh\xF4ng th\u1EC3 \u0111\u1ECDc settings.json (c\xF3 th\u1EC3 ch\u1EE9a comments).");
7373
- const confirmOverwrite = await confirm8({
7767
+ const confirmOverwrite = await confirm9({
7374
7768
  message: "Ghi \u0111\xE8 file settings.json hi\u1EC7n t\u1EA1i?",
7375
7769
  default: false
7376
7770
  });
@@ -7417,7 +7811,7 @@ async function resetSettings2(groupKeys) {
7417
7811
  console.log("\n\u26A0\uFE0F Kh\xF4ng t\xECm th\u1EA5y file settings.json");
7418
7812
  return;
7419
7813
  }
7420
- const confirmReset = await confirm8({
7814
+ const confirmReset = await confirm9({
7421
7815
  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(", ")}?`,
7422
7816
  default: false
7423
7817
  });
@@ -7536,7 +7930,7 @@ async function printStats2() {
7536
7930
 
7537
7931
  // src/commands/migrate-ide.ts
7538
7932
  import { Command as Command39 } from "commander";
7539
- import { checkbox as checkbox4, confirm as confirm9 } from "@inquirer/prompts";
7933
+ import { checkbox as checkbox4, confirm as confirm10 } from "@inquirer/prompts";
7540
7934
  function createMigrateIdeCommand() {
7541
7935
  const cmd = new Command39("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) => {
7542
7936
  await runMigrateIde(options);
@@ -7607,7 +8001,7 @@ async function runMigrateIde(options) {
7607
8001
  if (options.dryRun) {
7608
8002
  console.log("\u{1F50D} DRY RUN - No files will be written\n");
7609
8003
  }
7610
- const confirmed = await confirm9({
8004
+ const confirmed = await confirm10({
7611
8005
  message: "Proceed with migration?",
7612
8006
  default: true
7613
8007
  });