@jvittechs/jai1-cli 0.1.64 → 0.1.66

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.64",
36
+ version: "0.1.66",
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((input2, key) => {
897
+ useInput((input, key) => {
898
898
  if (viewState === "summary") {
899
- if (key.return || input2 === "q" || key.escape) {
899
+ if (key.return || input === "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 || input2 === "q") {
913
+ if (key.escape || input === "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 (input2 === " ") {
928
+ } else if (input === " ") {
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 (input2 === "a") {
941
+ } else if (input === "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 (input2 === "c") {
947
+ } else if (input === "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 (input2 === " " || key.return) {
956
+ } else if (input === " " || 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((input2, key) => {
1334
+ useInput2((input, 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((input2, key) => {
1436
+ useInput3((input, 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(input2, 10);
1442
+ const num = parseInt(input, 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((input2, key) => {
1504
+ useInput4((input, 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((input2, key) => {
1556
- if (key.upArrow || input2 === "k") {
1555
+ useInput5((input, key) => {
1556
+ if (key.upArrow || input === "k") {
1557
1557
  setScrollPosition((prev) => Math.max(0, prev - 1));
1558
- } else if (key.downArrow || input2 === "j") {
1558
+ } else if (key.downArrow || input === "j") {
1559
1559
  setScrollPosition((prev) => Math.min(maxScroll, prev + 1));
1560
- } else if (key.pageDown || input2 === "d") {
1560
+ } else if (key.pageDown || input === "d") {
1561
1561
  setScrollPosition((prev) => Math.min(maxScroll, prev + 5));
1562
- } else if (key.pageUp || input2 === "u") {
1562
+ } else if (key.pageUp || input === "u") {
1563
1563
  setScrollPosition((prev) => Math.max(0, prev - 5));
1564
- } else if (input2 === "g") {
1564
+ } else if (input === "g") {
1565
1565
  setScrollPosition(0);
1566
- } else if (input2 === "G") {
1566
+ } else if (input === "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((input2, key) => {
1963
- if (input2 === "q") {
1962
+ useInput6((input, key) => {
1963
+ if (input === "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((input2, key) => {
2890
+ useInput7((input, 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((input2, key) => {
3503
+ useInput8((input, 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((input2, key) => {
3635
+ useInput9((input, 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 (input2 === "q") {
3645
+ if (input === "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((input2, key) => {
4140
+ useInput10((input, 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((input2, key) => {
4262
+ useInput11((input, 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(input2) {
4463
+ async detectInputType(input) {
4464
4464
  try {
4465
- const stat = await fs7.stat(input2);
4465
+ const stat = await fs7.stat(input);
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(input2, options) {
4697
+ async function handleTranslate(input, 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(input2, 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(input2);
4705
+ const inputType = await translationService.detectInputType(input);
4706
4706
  switch (inputType) {
4707
4707
  case "text":
4708
- await handleTextTranslation(translationService, input2, options);
4708
+ await handleTextTranslation(translationService, input, options);
4709
4709
  break;
4710
4710
  case "file":
4711
- await handleFileTranslation(translationService, input2, options);
4711
+ await handleFileTranslation(translationService, input, options);
4712
4712
  break;
4713
4713
  case "folder":
4714
- await handleFolderTranslation(translationService, input2, options);
4714
+ await handleFolderTranslation(translationService, input, 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 (input2, options) => {
4792
- await handleTranslate(input2, 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 (input, options) => {
4792
+ await handleTranslate(input, 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(input2, algorithm) {
4852
+ async hash(input, 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(input2);
4857
+ hash.update(input);
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(input2, rounds = 10) {
4871
- return bcrypt.hash(input2, rounds);
4870
+ async hashBcrypt(input, rounds = 10) {
4871
+ return bcrypt.hash(input, rounds);
4872
4872
  }
4873
4873
  /**
4874
4874
  * Base64 encode
4875
4875
  */
4876
- base64Encode(input2, urlSafe = false) {
4877
- const buffer = typeof input2 === "string" ? Buffer.from(input2, "utf-8") : input2;
4876
+ base64Encode(input, urlSafe = false) {
4877
+ const buffer = typeof input === "string" ? Buffer.from(input, "utf-8") : input;
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(input2) {
4888
- let normalized = input2.replace(/-/g, "+").replace(/_/g, "/");
4887
+ base64Decode(input) {
4888
+ let normalized = input.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(input2, full = false) {
5018
- return full ? encodeURI(input2) : encodeURIComponent(input2);
5017
+ urlEncode(input, full = false) {
5018
+ return full ? encodeURI(input) : encodeURIComponent(input);
5019
5019
  }
5020
5020
  /**
5021
5021
  * URL decode
5022
5022
  */
5023
- urlDecode(input2, full = false) {
5024
- return full ? decodeURI(input2) : decodeURIComponent(input2);
5023
+ urlDecode(input, full = false) {
5024
+ return full ? decodeURI(input) : decodeURIComponent(input);
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(input2, options) {
5134
+ async function handleHashGeneration(input, options) {
5135
5135
  const service = new UtilsService();
5136
5136
  try {
5137
5137
  let hash;
@@ -5142,14 +5142,14 @@ async function handleHashGeneration(input2, options) {
5142
5142
  }
5143
5143
  hash = await service.hashFile(options.file, options.algorithm);
5144
5144
  } else {
5145
- if (!input2) {
5145
+ if (!input) {
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(input2, options.rounds);
5150
+ hash = await service.hashBcrypt(input, options.rounds);
5151
5151
  } else {
5152
- hash = await service.hash(input2, options.algorithm);
5152
+ hash = await service.hash(input, 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 (input2, options) => {
5186
- await handleHashGeneration(input2, {
5185
+ `).action(async (input, options) => {
5186
+ await handleHashGeneration(input, {
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(input2, options) {
5197
+ async function handleBase64Encode(input, options) {
5198
5198
  const service = new UtilsService();
5199
5199
  try {
5200
5200
  let encoded;
@@ -5202,11 +5202,11 @@ async function handleBase64Encode(input2, options) {
5202
5202
  const content = await readFile2(options.file);
5203
5203
  encoded = service.base64Encode(content, options.urlSafe);
5204
5204
  } else {
5205
- if (!input2) {
5205
+ if (!input) {
5206
5206
  console.error("\u274C Please provide input text or use --file option");
5207
5207
  process.exit(1);
5208
5208
  }
5209
- encoded = service.base64Encode(input2, options.urlSafe);
5209
+ encoded = service.base64Encode(input, 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 (input2, options) => {
5235
- await handleBase64Encode(input2, options);
5234
+ `).action(async (input, options) => {
5235
+ await handleBase64Encode(input, 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(input2, options) {
5243
+ async function handleBase64Decode(input, 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 (!input2) {
5250
+ if (!input) {
5251
5251
  console.error("\u274C Please provide Base64 input or use --file option");
5252
5252
  process.exit(1);
5253
5253
  }
5254
- encodedInput = input2;
5254
+ encodedInput = input;
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 (input2, options) => {
5280
- await handleBase64Decode(input2, options);
5279
+ `).action(async (input, options) => {
5280
+ await handleBase64Decode(input, 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(input2, options) {
5431
+ async function handleUnixTime(input, options) {
5432
5432
  const service = new UtilsService();
5433
5433
  try {
5434
- if (!input2) {
5434
+ if (!input) {
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(input2, options) {
5441
5441
  console.log(` ISO: ${now.toISOString()}`);
5442
5442
  console.log(` Local: ${now.toLocaleString()}`);
5443
5443
  console.log();
5444
- } else if (/^\d+$/.test(input2)) {
5445
- const timestamp = parseInt(input2, 10);
5444
+ } else if (/^\d+$/.test(input)) {
5445
+ const timestamp = parseInt(input, 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(input2, options) {
5455
5455
  }
5456
5456
  console.log();
5457
5457
  } else {
5458
- const date = new Date(input2);
5458
+ const date = new Date(input);
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(input2, 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: ${input2}`);
5466
+ console.log(` Input: ${input}`);
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 (input2, options) => {
5487
- await handleUnixTime(input2, options);
5486
+ `).action(async (input, options) => {
5487
+ await handleUnixTime(input, 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(input2, options) {
5544
+ async function handleUrlEncode(input, options) {
5545
5545
  const service = new UtilsService();
5546
5546
  try {
5547
- const encoded = service.urlEncode(input2, options.full);
5547
+ const encoded = service.urlEncode(input, 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 (input2, options) => {
5571
- await handleUrlEncode(input2, options);
5570
+ `).showHelpAfterError("(add --help for additional examples)").action(async (input, options) => {
5571
+ await handleUrlEncode(input, 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(input2, options) {
5578
+ async function handleUrlDecode(input, options) {
5579
5579
  const service = new UtilsService();
5580
5580
  try {
5581
- const decoded = service.urlDecode(input2, options.full);
5581
+ const decoded = service.urlDecode(input, 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 (input2, options) => {
5605
- await handleUrlDecode(input2, options);
5604
+ `).showHelpAfterError("(add --help for additional examples)").action(async (input, options) => {
5605
+ await handleUrlDecode(input, options);
5606
5606
  });
5607
5607
  return cmd;
5608
5608
  }
@@ -5717,372 +5717,140 @@ Examples:
5717
5717
  }
5718
5718
 
5719
5719
  // src/commands/utils/interactive.ts
5720
- import { select as select2, input, confirm as confirm4 } from "@inquirer/prompts";
5720
+ import React28 from "react";
5721
+ import { render as render5 } from "ink";
5722
+
5723
+ // src/ui/utils/UtilsApp.tsx
5724
+ import React27, { useState as useState14 } from "react";
5725
+ import { Box as Box17, Text as Text18, useInput as useInput12, useApp as useApp5 } from "ink";
5721
5726
  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" }
5727
+ { id: "password", icon: "\u{1F510}", label: "Password", description: "Generate secure passwords" },
5728
+ { id: "uuid", icon: "\u{1F194}", label: "UUID", description: "Generate UUID v4" },
5729
+ { id: "hash", icon: "\u{1F512}", label: "Hash", description: "Hash with MD5/SHA/bcrypt" },
5730
+ { id: "base64-encode", icon: "\u{1F4DD}", label: "Base64 Encode", description: "Encode to Base64" },
5731
+ { id: "base64-decode", icon: "\u{1F4DD}", label: "Base64 Decode", description: "Decode Base64" },
5732
+ { id: "http", icon: "\u{1F310}", label: "HTTP Request", description: "Make HTTP requests" },
5733
+ { id: "jwt", icon: "\u{1F511}", label: "JWT", description: "Decode/encode JWT" },
5734
+ { id: "unix-time", icon: "\u{1F552}", label: "Unix Time", description: "Convert timestamps" },
5735
+ { id: "timezone", icon: "\u{1F30D}", label: "Timezone", description: "Convert timezones" },
5736
+ { id: "url-encode", icon: "\u{1F517}", label: "URL Encode", description: "Encode URLs" },
5737
+ { id: "url-decode", icon: "\u{1F517}", label: "URL Decode", description: "Decode URLs" },
5738
+ { id: "cron", icon: "\u23F0", label: "Cron Parser", description: "Parse cron expressions" },
5739
+ { id: "markdown", icon: "\u{1F4C4}", label: "Markdown", description: "Preview markdown" }
5736
5740
  ];
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("");
5741
+ var UtilsApp = ({ onExit }) => {
5742
+ const [selectedIndex, setSelectedIndex] = useState14(0);
5743
+ const [activeView, setActiveView] = useState14(null);
5744
+ const { exit } = useApp5();
5745
+ useInput12((input, key) => {
5746
+ if (activeView) {
5747
+ if (key.escape) {
5748
+ setActiveView(null);
5810
5749
  }
5750
+ return;
5751
+ }
5752
+ if (key.upArrow || input === "k") {
5753
+ setSelectedIndex((prev) => prev > 0 ? prev - 1 : MENU_ITEMS2.length - 1);
5754
+ } else if (key.downArrow || input === "j") {
5755
+ setSelectedIndex((prev) => prev < MENU_ITEMS2.length - 1 ? prev + 1 : 0);
5756
+ } else if (key.return) {
5757
+ setActiveView(MENU_ITEMS2[selectedIndex].id);
5758
+ } else if (input === "q" || key.escape) {
5759
+ onExit();
5760
+ exit();
5811
5761
  }
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
5762
  });
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
5763
+ return /* @__PURE__ */ React27.createElement(Box17, { flexDirection: "column", width: "100%", height: "100%" }, /* @__PURE__ */ React27.createElement(
5764
+ Box17,
5765
+ {
5766
+ borderStyle: "single",
5767
+ borderColor: "cyan",
5768
+ paddingX: 2,
5769
+ paddingY: 0,
5770
+ marginBottom: 1
5771
+ },
5772
+ /* @__PURE__ */ React27.createElement(Text18, { bold: true, color: "cyan" }, "\u{1F6E0}\uFE0F Developer Utilities - Interactive Mode"),
5773
+ /* @__PURE__ */ React27.createElement(Box17, { marginLeft: "auto" }, /* @__PURE__ */ React27.createElement(Text18, { dimColor: true }, "Press 'q' to quit"))
5774
+ ), /* @__PURE__ */ React27.createElement(Box17, { flexGrow: 1 }, /* @__PURE__ */ React27.createElement(
5775
+ Box17,
5776
+ {
5777
+ flexDirection: "column",
5778
+ width: 30,
5779
+ borderStyle: "single",
5780
+ borderColor: "gray",
5781
+ paddingX: 1,
5782
+ paddingY: 1,
5783
+ marginRight: 1
5784
+ },
5785
+ /* @__PURE__ */ React27.createElement(Box17, { marginBottom: 1 }, /* @__PURE__ */ React27.createElement(Text18, { bold: true, color: "yellow" }, "Select Utility:")),
5786
+ MENU_ITEMS2.map((item, index) => /* @__PURE__ */ React27.createElement(Box17, { key: item.id, marginBottom: 0 }, /* @__PURE__ */ React27.createElement(
5787
+ Text18,
5788
+ {
5789
+ color: selectedIndex === index && !activeView ? "green" : void 0,
5790
+ bold: selectedIndex === index && !activeView,
5791
+ dimColor: activeView !== null && activeView !== item.id
5792
+ },
5793
+ selectedIndex === index && !activeView ? "\u25B6 " : " ",
5794
+ item.icon,
5795
+ " ",
5796
+ item.label
5797
+ ))),
5798
+ /* @__PURE__ */ React27.createElement(Box17, { marginTop: 1, borderStyle: "single", borderColor: "gray", paddingX: 1 }, /* @__PURE__ */ React27.createElement(Text18, { dimColor: true, fontSize: 10 }, "\u2191/\u2193: Navigate", "\n", "Enter: Select", "\n", "Esc: Back/Quit"))
5799
+ ), /* @__PURE__ */ React27.createElement(
5800
+ Box17,
5801
+ {
5802
+ flexDirection: "column",
5803
+ flexGrow: 1,
5804
+ borderStyle: "single",
5805
+ borderColor: "gray",
5806
+ paddingX: 2,
5807
+ paddingY: 1
5808
+ },
5809
+ activeView ? /* @__PURE__ */ React27.createElement(ActiveUtilityView, { utilityType: activeView }) : /* @__PURE__ */ React27.createElement(WelcomeView, { selectedItem: MENU_ITEMS2[selectedIndex] })
5810
+ )), /* @__PURE__ */ React27.createElement(
5811
+ Box17,
5812
+ {
5813
+ borderStyle: "single",
5814
+ borderColor: "gray",
5815
+ paddingX: 2,
5816
+ marginTop: 1
5817
+ },
5818
+ /* @__PURE__ */ React27.createElement(Text18, { dimColor: true }, "jai1-cli v0.1.63 | Use arrow keys to navigate")
5819
+ ));
5820
+ };
5821
+ var WelcomeView = ({ selectedItem }) => {
5822
+ return /* @__PURE__ */ React27.createElement(Box17, { flexDirection: "column" }, /* @__PURE__ */ React27.createElement(Box17, { marginBottom: 1 }, /* @__PURE__ */ React27.createElement(Text18, { bold: true, color: "cyan" }, "Welcome to Developer Utilities")), /* @__PURE__ */ React27.createElement(Box17, { marginBottom: 2 }, /* @__PURE__ */ React27.createElement(Text18, null, "Select a utility from the left menu to get started.")), /* @__PURE__ */ React27.createElement(
5823
+ Box17,
5824
+ {
5825
+ borderStyle: "single",
5826
+ borderColor: "yellow",
5827
+ paddingX: 2,
5828
+ paddingY: 1,
5829
+ marginBottom: 2
5830
+ },
5831
+ /* @__PURE__ */ React27.createElement(Box17, { flexDirection: "column" }, /* @__PURE__ */ React27.createElement(Text18, { bold: true, color: "yellow" }, selectedItem.icon, " ", selectedItem.label), /* @__PURE__ */ React27.createElement(Text18, { dimColor: true }, selectedItem.description))
5832
+ ), /* @__PURE__ */ React27.createElement(Box17, { marginBottom: 1 }, /* @__PURE__ */ React27.createElement(Text18, { bold: true }, "Quick Actions:")), /* @__PURE__ */ React27.createElement(Box17, { flexDirection: "column", marginLeft: 2 }, /* @__PURE__ */ React27.createElement(Text18, null, "\u2022 Press ", /* @__PURE__ */ React27.createElement(Text18, { color: "green" }, "Enter"), " to open selected utility"), /* @__PURE__ */ React27.createElement(Text18, null, "\u2022 Use ", /* @__PURE__ */ React27.createElement(Text18, { color: "green" }, "\u2191/\u2193"), " or ", /* @__PURE__ */ React27.createElement(Text18, { color: "green" }, "j/k"), " to navigate"), /* @__PURE__ */ React27.createElement(Text18, null, "\u2022 Press ", /* @__PURE__ */ React27.createElement(Text18, { color: "green" }, "Esc"), " to go back or quit"), /* @__PURE__ */ React27.createElement(Text18, null, "\u2022 Press ", /* @__PURE__ */ React27.createElement(Text18, { color: "green" }, "q"), " to quit anytime")), /* @__PURE__ */ React27.createElement(Box17, { marginTop: 2 }, /* @__PURE__ */ React27.createElement(Text18, { dimColor: true }, "\u{1F4A1} Tip: Each utility provides an interactive interface for easy usage.")));
5833
+ };
5834
+ var ActiveUtilityView = ({ utilityType }) => {
5835
+ const service = new UtilsService();
5836
+ return /* @__PURE__ */ React27.createElement(Box17, { flexDirection: "column" }, /* @__PURE__ */ React27.createElement(Box17, { marginBottom: 1 }, /* @__PURE__ */ React27.createElement(Text18, { bold: true, color: "cyan" }, MENU_ITEMS2.find((item) => item.id === utilityType)?.icon, " ", MENU_ITEMS2.find((item) => item.id === utilityType)?.label)), /* @__PURE__ */ React27.createElement(Box17, { borderStyle: "single", borderColor: "gray", paddingX: 2, paddingY: 1 }, /* @__PURE__ */ React27.createElement(Text18, null, "This utility interface is under construction.", "\n", "\n", "For now, use the command-line version:", "\n", /* @__PURE__ */ React27.createElement(Text18, { color: "green" }, "$ jai1 utils ", utilityType, " --help"), "\n", "\n", "Press ", /* @__PURE__ */ React27.createElement(Text18, { color: "yellow" }, "Esc"), " to return to the menu.")));
5837
+ };
5838
+
5839
+ // src/commands/utils/interactive.ts
5840
+ async function runInteractiveMode() {
5841
+ return new Promise((resolve3) => {
5842
+ const { unmount, waitUntilExit } = render5(
5843
+ React28.createElement(UtilsApp, {
5844
+ onExit: () => {
5845
+ unmount();
5846
+ resolve3();
5847
+ }
5832
5848
  })
5833
5849
  );
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"
5850
+ waitUntilExit().then(() => {
5851
+ resolve3();
5971
5852
  });
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
5853
  });
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
5854
  }
6087
5855
 
6088
5856
  // src/commands/utils/index.ts
@@ -6123,7 +5891,7 @@ Quick Usage:
6123
5891
 
6124
5892
  // src/commands/upgrade.ts
6125
5893
  import { Command as Command28 } from "commander";
6126
- import { confirm as confirm5 } from "@inquirer/prompts";
5894
+ import { confirm as confirm4 } from "@inquirer/prompts";
6127
5895
  import { execSync } from "child_process";
6128
5896
  var colors2 = {
6129
5897
  yellow: "\x1B[33m",
@@ -6178,7 +5946,7 @@ ${colors2.bold}Current version:${colors2.reset} ${currentVersion}`);
6178
5946
  return;
6179
5947
  }
6180
5948
  if (!options.force) {
6181
- const shouldUpdate = await confirm5({
5949
+ const shouldUpdate = await confirm4({
6182
5950
  message: "Update to the latest version now?",
6183
5951
  default: true
6184
5952
  });
@@ -6283,7 +6051,7 @@ function getInstallCommand(packageManager2) {
6283
6051
 
6284
6052
  // src/commands/clean.ts
6285
6053
  import { Command as Command29 } from "commander";
6286
- import { confirm as confirm6, select as select3 } from "@inquirer/prompts";
6054
+ import { confirm as confirm5, select as select2 } from "@inquirer/prompts";
6287
6055
  import { join as join4 } from "path";
6288
6056
  function createCleanCommand() {
6289
6057
  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) => {
@@ -6347,7 +6115,7 @@ async function handleClean(options) {
6347
6115
  console.log(` Path: ${target.path}
6348
6116
  `);
6349
6117
  }
6350
- const action = await select3({
6118
+ const action = await select2({
6351
6119
  message: "What do you want to clean?",
6352
6120
  choices: [
6353
6121
  ...availableTargets.map(({ target, info }) => ({
@@ -6381,7 +6149,7 @@ async function cleanTarget(target, skipConfirm) {
6381
6149
  }
6382
6150
  const countStr = info.count ? ` (${info.count} items)` : "";
6383
6151
  if (!skipConfirm) {
6384
- const confirmed = await confirm6({
6152
+ const confirmed = await confirm5({
6385
6153
  message: `Delete ${target.name}${countStr}?`,
6386
6154
  default: false
6387
6155
  });
@@ -7341,7 +7109,7 @@ async function getProjectStatus2() {
7341
7109
 
7342
7110
  // src/commands/self-update.ts
7343
7111
  import { Command as Command34 } from "commander";
7344
- import { confirm as confirm7 } from "@inquirer/prompts";
7112
+ import { confirm as confirm6 } from "@inquirer/prompts";
7345
7113
  import { execSync as execSync2 } from "child_process";
7346
7114
  var colors3 = {
7347
7115
  yellow: "\x1B[33m",
@@ -7396,7 +7164,7 @@ ${colors3.bold}Current version:${colors3.reset} ${currentVersion}`);
7396
7164
  return;
7397
7165
  }
7398
7166
  if (!options.force) {
7399
- const shouldUpdate = await confirm7({
7167
+ const shouldUpdate = await confirm6({
7400
7168
  message: "Update to the latest version now?",
7401
7169
  default: true
7402
7170
  });
@@ -7493,7 +7261,7 @@ function getInstallCommand2(packageManager2) {
7493
7261
 
7494
7262
  // src/commands/clear-backups.ts
7495
7263
  import { Command as Command35 } from "commander";
7496
- import { confirm as confirm8 } from "@inquirer/prompts";
7264
+ import { confirm as confirm7 } from "@inquirer/prompts";
7497
7265
  function createClearBackupsCommand() {
7498
7266
  return new Command35("clear-backups").description("Clear backup files").option("-y, --yes", "Skip confirmation").action(async (options) => {
7499
7267
  const service = new ComponentsService();
@@ -7511,7 +7279,7 @@ function createClearBackupsCommand() {
7511
7279
  }
7512
7280
  console.log();
7513
7281
  if (!options.yes) {
7514
- const ok = await confirm8({ message: "Delete all backups?", default: false });
7282
+ const ok = await confirm7({ message: "Delete all backups?", default: false });
7515
7283
  if (!ok) return;
7516
7284
  }
7517
7285
  await service.clearBackups(process.cwd());
@@ -7521,7 +7289,7 @@ function createClearBackupsCommand() {
7521
7289
 
7522
7290
  // src/commands/vscode/index.ts
7523
7291
  import { Command as Command36 } from "commander";
7524
- import { checkbox as checkbox3, confirm as confirm9, select as select4 } from "@inquirer/prompts";
7292
+ import { checkbox as checkbox3, confirm as confirm8, select as select3 } from "@inquirer/prompts";
7525
7293
  import fs9 from "fs/promises";
7526
7294
  import path5 from "path";
7527
7295
  import { existsSync as existsSync2 } from "fs";
@@ -7704,7 +7472,7 @@ async function interactiveMode2() {
7704
7472
  console.log("\u2502 \u2022 Nh\u1EA5n ENTER \u0111\u1EC3 x\xE1c nh\u1EADn v\xE0 \xE1p d\u1EE5ng \u2502");
7705
7473
  console.log("\u2502 \u2022 Nh\u1EA5n Ctrl+C \u0111\u1EC3 h\u1EE7y \u2502");
7706
7474
  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");
7707
- const action = await select4({
7475
+ const action = await select3({
7708
7476
  message: "B\u1EA1n mu\u1ED1n l\xE0m g\xEC?",
7709
7477
  choices: [
7710
7478
  { name: "\u2705 Enable c\xE1c nh\xF3m t\u1ED1i \u01B0u", value: "enable" },
@@ -7764,7 +7532,7 @@ async function applyGroups2(groupKeys, action) {
7764
7532
  console.log("\u{1F4C4} \u0110\xE3 \u0111\u1ECDc c\xE0i \u0111\u1EB7t hi\u1EC7n t\u1EA1i t\u1EEB settings.json");
7765
7533
  } catch {
7766
7534
  console.warn("\u26A0\uFE0F Kh\xF4ng th\u1EC3 \u0111\u1ECDc settings.json (c\xF3 th\u1EC3 ch\u1EE9a comments).");
7767
- const confirmOverwrite = await confirm9({
7535
+ const confirmOverwrite = await confirm8({
7768
7536
  message: "Ghi \u0111\xE8 file settings.json hi\u1EC7n t\u1EA1i?",
7769
7537
  default: false
7770
7538
  });
@@ -7811,7 +7579,7 @@ async function resetSettings2(groupKeys) {
7811
7579
  console.log("\n\u26A0\uFE0F Kh\xF4ng t\xECm th\u1EA5y file settings.json");
7812
7580
  return;
7813
7581
  }
7814
- const confirmReset = await confirm9({
7582
+ const confirmReset = await confirm8({
7815
7583
  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(", ")}?`,
7816
7584
  default: false
7817
7585
  });
@@ -7829,13 +7597,13 @@ async function resetSettings2(groupKeys) {
7829
7597
  }
7830
7598
 
7831
7599
  // src/commands/guide.ts
7832
- import React27 from "react";
7833
- import { render as render5 } from "ink";
7600
+ import React29 from "react";
7601
+ import { render as render6 } from "ink";
7834
7602
  import { Command as Command37 } from "commander";
7835
7603
  function createGuideCommand() {
7836
7604
  const cmd = new Command37("guide").description("Interactive guide center for Agentic Coding").option("--topic <topic>", "Open specific topic (intro, rules, workflows, prompts, skills)").action(async (options) => {
7837
- const { waitUntilExit } = render5(
7838
- React27.createElement(GuideApp, {
7605
+ const { waitUntilExit } = render6(
7606
+ React29.createElement(GuideApp, {
7839
7607
  initialTopic: options.topic,
7840
7608
  onExit: () => {
7841
7609
  process.exit(0);
@@ -7848,8 +7616,8 @@ function createGuideCommand() {
7848
7616
  }
7849
7617
 
7850
7618
  // src/commands/context.ts
7851
- import React28 from "react";
7852
- import { render as render6 } from "ink";
7619
+ import React30 from "react";
7620
+ import { render as render7 } from "ink";
7853
7621
  import { Command as Command38 } from "commander";
7854
7622
  function createContextCommand() {
7855
7623
  const cmd = new Command38("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) => {
@@ -7877,8 +7645,8 @@ function createContextCommand() {
7877
7645
  await printStats2();
7878
7646
  return;
7879
7647
  }
7880
- const { waitUntilExit } = render6(
7881
- React28.createElement(ContextApp, {
7648
+ const { waitUntilExit } = render7(
7649
+ React30.createElement(ContextApp, {
7882
7650
  initialIDE,
7883
7651
  initialType,
7884
7652
  onExit: () => {
@@ -7930,7 +7698,7 @@ async function printStats2() {
7930
7698
 
7931
7699
  // src/commands/migrate-ide.ts
7932
7700
  import { Command as Command39 } from "commander";
7933
- import { checkbox as checkbox4, confirm as confirm10 } from "@inquirer/prompts";
7701
+ import { checkbox as checkbox4, confirm as confirm9 } from "@inquirer/prompts";
7934
7702
  function createMigrateIdeCommand() {
7935
7703
  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) => {
7936
7704
  await runMigrateIde(options);
@@ -8001,7 +7769,7 @@ async function runMigrateIde(options) {
8001
7769
  if (options.dryRun) {
8002
7770
  console.log("\u{1F50D} DRY RUN - No files will be written\n");
8003
7771
  }
8004
- const confirmed = await confirm10({
7772
+ const confirmed = await confirm9({
8005
7773
  message: "Proceed with migration?",
8006
7774
  default: true
8007
7775
  });