@jvittechs/j 1.0.14 → 1.0.15

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.
Files changed (3) hide show
  1. package/dist/cli.js +923 -1405
  2. package/dist/cli.js.map +1 -1
  3. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -42,7 +42,7 @@ function checkNodeVersion() {
42
42
  }
43
43
 
44
44
  // src/cli.ts
45
- import { Command as Command79 } from "commander";
45
+ import { Command as Command78 } from "commander";
46
46
 
47
47
  // src/errors/index.ts
48
48
  var Jai1Error = class extends Error {
@@ -169,7 +169,7 @@ import { basename as basename4 } from "path";
169
169
  // package.json
170
170
  var package_default = {
171
171
  name: "@jvittechs/j",
172
- version: "1.0.14",
172
+ version: "1.0.15",
173
173
  description: "A unified CLI tool for JV-IT TECHS developers to manage Jai1 Framework. Supports both `j` and `jai1` commands. Please contact TeamAI for usage instructions.",
174
174
  type: "module",
175
175
  bin: {
@@ -2608,316 +2608,11 @@ async function handleCheck(options) {
2608
2608
 
2609
2609
  // src/commands/ide/index.ts
2610
2610
  import { Command as Command11 } from "commander";
2611
- import chalk6 from "chalk";
2611
+ import chalk7 from "chalk";
2612
2612
 
2613
- // src/commands/ide/context.ts
2614
- import React12 from "react";
2615
- import { render as render3 } from "ink";
2613
+ // src/commands/context.ts
2616
2614
  import { Command as Command7 } from "commander";
2617
-
2618
- // src/ui/context/ContextApp.tsx
2619
- import React11, { useState as useState7, useEffect as useEffect3 } from "react";
2620
- import { Box as Box8, Text as Text9, useInput as useInput7, useApp as useApp3 } from "ink";
2621
-
2622
- // src/ui/context/views/MainMenuView.tsx
2623
- import React7, { useState as useState3 } from "react";
2624
- import { Box as Box4, Text as Text5, useInput as useInput3 } from "ink";
2625
- var MainMenuView = ({ ideContexts, onSelect }) => {
2626
- const [selectedIndex, setSelectedIndex] = useState3(0);
2627
- const menuItems = [
2628
- {
2629
- ide: "cursor",
2630
- icon: "\u{1F52E}",
2631
- title: "Cursor",
2632
- itemCount: ideContexts.find((ctx) => ctx.ide === "cursor")?.stats.totalItems || 0,
2633
- available: ideContexts.some((ctx) => ctx.ide === "cursor")
2634
- },
2635
- {
2636
- ide: "windsurf",
2637
- icon: "\u{1F3C4}",
2638
- title: "Windsurf",
2639
- itemCount: ideContexts.find((ctx) => ctx.ide === "windsurf")?.stats.totalItems || 0,
2640
- available: ideContexts.some((ctx) => ctx.ide === "windsurf")
2641
- },
2642
- {
2643
- ide: "antigravity",
2644
- icon: "\u{1F680}",
2645
- title: "Antigravity",
2646
- itemCount: ideContexts.find((ctx) => ctx.ide === "antigravity")?.stats.totalItems || 0,
2647
- available: ideContexts.some((ctx) => ctx.ide === "antigravity")
2648
- },
2649
- {
2650
- ide: "jai1",
2651
- icon: "\u{1F916}",
2652
- title: "Jai1 Framework",
2653
- itemCount: ideContexts.find((ctx) => ctx.ide === "jai1")?.stats.totalItems || 0,
2654
- available: ideContexts.some((ctx) => ctx.ide === "jai1")
2655
- }
2656
- ];
2657
- useInput3((input5, key) => {
2658
- if (key.upArrow) {
2659
- setSelectedIndex((prev) => Math.max(0, prev - 1));
2660
- } else if (key.downArrow) {
2661
- setSelectedIndex((prev) => Math.min(menuItems.length - 1, prev + 1));
2662
- } else if (key.return) {
2663
- const item = menuItems[selectedIndex];
2664
- if (item && item.available) {
2665
- onSelect(item.ide);
2666
- }
2667
- }
2668
- }, { isActive: true });
2669
- const formatSummary = (item) => {
2670
- if (!item.available) {
2671
- return "Kh\xF4ng c\xF3 context";
2672
- }
2673
- const ctx = ideContexts.find((c) => c.ide === item.ide);
2674
- if (!ctx) return "";
2675
- const parts = [];
2676
- if (ctx.stats.byType.rules) parts.push(`${ctx.stats.byType.rules} rules`);
2677
- if (ctx.stats.byType.workflows) parts.push(`${ctx.stats.byType.workflows} workflows`);
2678
- if (ctx.stats.byType.skills) parts.push(`${ctx.stats.byType.skills} skills`);
2679
- if (ctx.stats.byType.agents) parts.push(`${ctx.stats.byType.agents} agents`);
2680
- if (ctx.stats.byType.prompts) parts.push(`${ctx.stats.byType.prompts} prompts`);
2681
- return parts.join(", ") || `${item.itemCount} items`;
2682
- };
2683
- return /* @__PURE__ */ React7.createElement(Box4, { flexDirection: "column" }, /* @__PURE__ */ React7.createElement(
2684
- Box4,
2685
- {
2686
- flexDirection: "column",
2687
- borderStyle: "round",
2688
- borderColor: "cyan",
2689
- padding: 1,
2690
- marginBottom: 1
2691
- },
2692
- /* @__PURE__ */ React7.createElement(Text5, null, "Ch\xE0o m\u1EEBng \u0111\u1EBFn v\u1EDBi ", /* @__PURE__ */ React7.createElement(Text5, { bold: true, color: "cyan" }, "Jai1 Context"), "!"),
2693
- /* @__PURE__ */ React7.createElement(Text5, { dimColor: true }, "Kh\xE1m ph\xE1 v\xE0 qu\u1EA3n l\xFD context cho c\xE1c IDE h\u1ED7 tr\u1EE3 Agentic Coding.")
2694
- ), /* @__PURE__ */ React7.createElement(Box4, { flexDirection: "column", borderStyle: "round", borderColor: "gray", padding: 1 }, /* @__PURE__ */ React7.createElement(Text5, { bold: true, marginBottom: 1 }, "Ch\u1ECDn IDE \u0111\u1EC3 kh\xE1m ph\xE1:"), menuItems.map((item, index) => {
2695
- const isSelected = index === selectedIndex;
2696
- const dimmed = !item.available;
2697
- return /* @__PURE__ */ React7.createElement(Box4, { key: item.ide, marginY: 0 }, /* @__PURE__ */ React7.createElement(Text5, { color: isSelected ? "cyan" : dimmed ? "gray" : "white", dimColor: dimmed }, isSelected ? "\u276F " : " ", item.icon, " ", item.title), item.available && /* @__PURE__ */ React7.createElement(Text5, { dimColor: true }, " - ", formatSummary(item)), !item.available && /* @__PURE__ */ React7.createElement(Text5, { dimColor: true }, " - Kh\xF4ng c\xF3 context"));
2698
- })), ideContexts.length === 0 && /* @__PURE__ */ React7.createElement(Box4, { marginTop: 1, borderStyle: "round", borderColor: "yellow", padding: 1 }, /* @__PURE__ */ React7.createElement(Text5, { color: "yellow" }, "\u26A0\uFE0F Kh\xF4ng t\xECm th\u1EA5y context n\xE0o"), /* @__PURE__ */ React7.createElement(Text5, { dimColor: true }, "H\xE3y ch\u1EA1y "), /* @__PURE__ */ React7.createElement(Text5, { color: "cyan" }, "jai1 apply"), /* @__PURE__ */ React7.createElement(Text5, { dimColor: true }, " \u0111\u1EC3 c\xE0i \u0111\u1EB7t context cho IDE c\u1EE7a b\u1EA1n.")));
2699
- };
2700
-
2701
- // src/ui/context/views/IDEOverviewView.tsx
2702
- import React8, { useState as useState4 } from "react";
2703
- import { Box as Box5, Text as Text6, useInput as useInput4 } from "ink";
2704
- var IDEOverviewView = ({
2705
- ideContext,
2706
- onSelectType,
2707
- onBack
2708
- }) => {
2709
- const [selectedTabIndex, setSelectedTabIndex] = useState4(0);
2710
- const tabs = [];
2711
- if (ideContext.stats.byType.rules) {
2712
- tabs.push({
2713
- type: "rules",
2714
- label: "Rules",
2715
- icon: "\u{1F4DC}",
2716
- count: ideContext.stats.byType.rules
2717
- });
2718
- }
2719
- if (ideContext.stats.byType.workflows) {
2720
- tabs.push({
2721
- type: "workflows",
2722
- label: "Workflows",
2723
- icon: "\u{1F504}",
2724
- count: ideContext.stats.byType.workflows
2725
- });
2726
- }
2727
- if (ideContext.stats.byType.skills) {
2728
- tabs.push({
2729
- type: "skills",
2730
- label: "Skills",
2731
- icon: "\u{1F6E0}",
2732
- count: ideContext.stats.byType.skills
2733
- });
2734
- }
2735
- if (ideContext.stats.byType.agents) {
2736
- tabs.push({
2737
- type: "agents",
2738
- label: "Agents",
2739
- icon: "\u{1F916}",
2740
- count: ideContext.stats.byType.agents
2741
- });
2742
- }
2743
- if (ideContext.stats.byType.prompts) {
2744
- tabs.push({
2745
- type: "prompts",
2746
- label: "Prompts",
2747
- icon: "\u{1F4AC}",
2748
- count: ideContext.stats.byType.prompts
2749
- });
2750
- }
2751
- if (ideContext.stats.byType.context) {
2752
- tabs.push({
2753
- type: "context",
2754
- label: "Context",
2755
- icon: "\u{1F4CB}",
2756
- count: ideContext.stats.byType.context
2757
- });
2758
- }
2759
- useInput4((input5, key) => {
2760
- if (key.tab || key.rightArrow) {
2761
- setSelectedTabIndex((prev) => Math.min(tabs.length - 1, prev + 1));
2762
- } else if (key.leftArrow) {
2763
- setSelectedTabIndex((prev) => Math.max(0, prev - 1));
2764
- }
2765
- const num = parseInt(input5, 10);
2766
- if (!isNaN(num) && num >= 1 && num <= tabs.length) {
2767
- setSelectedTabIndex(num - 1);
2768
- }
2769
- if (key.return) {
2770
- const tab = tabs[selectedTabIndex];
2771
- if (tab) {
2772
- onSelectType(tab.type);
2773
- }
2774
- }
2775
- }, { isActive: true });
2776
- const currentTab = tabs[selectedTabIndex];
2777
- const currentItems = currentTab ? ideContext?.items?.filter((item) => item.type === currentTab.type) ?? [] : [];
2778
- const formatSize = (bytes) => {
2779
- if (bytes < 1024) return `${bytes}B`;
2780
- if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}KB`;
2781
- return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
2782
- };
2783
- const formatDate = (date) => {
2784
- return date.toLocaleDateString("vi-VN", {
2785
- year: "numeric",
2786
- month: "2-digit",
2787
- day: "2-digit"
2788
- });
2789
- };
2790
- return /* @__PURE__ */ React8.createElement(Box5, { flexDirection: "column" }, /* @__PURE__ */ React8.createElement(Box5, { marginBottom: 1 }, /* @__PURE__ */ React8.createElement(Text6, { bold: true, color: "cyan" }, ideContext.config.icon, " ", ideContext.config.name)), /* @__PURE__ */ React8.createElement(
2791
- Box5,
2792
- {
2793
- flexDirection: "column",
2794
- borderStyle: "round",
2795
- borderColor: "cyan",
2796
- padding: 1,
2797
- marginBottom: 1
2798
- },
2799
- /* @__PURE__ */ React8.createElement(Text6, { bold: true }, "\u{1F4CA} T\u1ED5ng quan"),
2800
- /* @__PURE__ */ React8.createElement(Box5, { marginTop: 1 }, /* @__PURE__ */ React8.createElement(Text6, null, "\u{1F4C1} T\u1ED5ng: ", /* @__PURE__ */ React8.createElement(Text6, { bold: true, color: "cyan" }, ideContext.stats.totalItems, " items")), /* @__PURE__ */ React8.createElement(Text6, { dimColor: true }, " \xB7 "), /* @__PURE__ */ React8.createElement(Text6, null, "\u{1F4BE} K\xEDch th\u01B0\u1EDBc: ", /* @__PURE__ */ React8.createElement(Text6, { bold: true }, formatSize(ideContext.stats.totalSize))), ideContext.stats.lastModified && /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement(Text6, { dimColor: true }, " \xB7 "), /* @__PURE__ */ React8.createElement(Text6, null, "\u{1F550} C\u1EADp nh\u1EADt: ", /* @__PURE__ */ React8.createElement(Text6, { bold: true }, formatDate(ideContext.stats.lastModified)))))
2801
- ), /* @__PURE__ */ React8.createElement(Box5, { flexDirection: "column", borderStyle: "round", borderColor: "gray", padding: 1 }, /* @__PURE__ */ React8.createElement(Box5, { marginBottom: 1 }, tabs.map((tab, index) => {
2802
- const isSelected = index === selectedTabIndex;
2803
- return /* @__PURE__ */ React8.createElement(Box5, { key: tab.type, marginRight: 1 }, /* @__PURE__ */ React8.createElement(
2804
- Text6,
2805
- {
2806
- color: isSelected ? "cyan" : "gray",
2807
- bold: isSelected,
2808
- inverse: isSelected
2809
- },
2810
- " ",
2811
- tab.icon,
2812
- " ",
2813
- tab.label,
2814
- " (",
2815
- tab.count,
2816
- ")",
2817
- " "
2818
- ));
2819
- })), currentTab && currentItems.length > 0 && /* @__PURE__ */ React8.createElement(Box5, { flexDirection: "column" }, /* @__PURE__ */ React8.createElement(Text6, { dimColor: true }, "Preview (nh\u1EA5n Enter \u0111\u1EC3 xem chi ti\u1EBFt):"), /* @__PURE__ */ React8.createElement(Box5, { flexDirection: "column", marginTop: 1 }, currentItems.slice(0, 5).map((item) => /* @__PURE__ */ React8.createElement(Box5, { key: item.id, marginY: 0 }, /* @__PURE__ */ React8.createElement(Text6, null, "\u2022 ", item.name), item.description && /* @__PURE__ */ React8.createElement(Text6, { dimColor: true }, " - ", item.description))), currentItems.length > 5 && /* @__PURE__ */ React8.createElement(Text6, { dimColor: true }, "... v\xE0 ", currentItems.length - 5, " items kh\xE1c"))), currentTab && currentItems.length === 0 && /* @__PURE__ */ React8.createElement(Text6, { dimColor: true }, "Kh\xF4ng c\xF3 items n\xE0o trong ", currentTab.label)));
2820
- };
2821
-
2822
- // src/ui/context/views/ListView.tsx
2823
- import React9, { useState as useState5 } from "react";
2824
- import { Box as Box6, Text as Text7, useInput as useInput5 } from "ink";
2825
- var ListView = ({ items, contentType, onSelect, onBack }) => {
2826
- const [selectedIndex, setSelectedIndex] = useState5(0);
2827
- useInput5((input5, key) => {
2828
- if (key.upArrow) {
2829
- setSelectedIndex((prev) => Math.max(0, prev - 1));
2830
- } else if (key.downArrow) {
2831
- setSelectedIndex((prev) => Math.min(items.length - 1, prev + 1));
2832
- } else if (key.return) {
2833
- const item = items[selectedIndex];
2834
- if (item) {
2835
- onSelect(item);
2836
- }
2837
- }
2838
- }, { isActive: true });
2839
- const getTypeLabel = () => {
2840
- switch (contentType) {
2841
- case "rules":
2842
- return "\u{1F4DC} Rules";
2843
- case "workflows":
2844
- return "\u{1F504} Workflows";
2845
- case "skills":
2846
- return "\u{1F6E0} Skills";
2847
- case "agents":
2848
- return "\u{1F916} Agents";
2849
- case "prompts":
2850
- return "\u{1F4AC} Prompts";
2851
- case "context":
2852
- return "\u{1F4CB} Context";
2853
- default:
2854
- return contentType;
2855
- }
2856
- };
2857
- const formatSize = (bytes) => {
2858
- if (bytes < 1024) return `${bytes}B`;
2859
- if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}KB`;
2860
- return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
2861
- };
2862
- if (items.length === 0) {
2863
- return /* @__PURE__ */ React9.createElement(Box6, { flexDirection: "column" }, /* @__PURE__ */ React9.createElement(Box6, { marginBottom: 1 }, /* @__PURE__ */ React9.createElement(Text7, { bold: true, color: "cyan" }, getTypeLabel())), /* @__PURE__ */ React9.createElement(Box6, { borderStyle: "round", borderColor: "gray", padding: 1 }, /* @__PURE__ */ React9.createElement(Text7, { dimColor: true }, "Kh\xF4ng c\xF3 items n\xE0o")));
2864
- }
2865
- return /* @__PURE__ */ React9.createElement(Box6, { flexDirection: "column" }, /* @__PURE__ */ React9.createElement(Box6, { marginBottom: 1 }, /* @__PURE__ */ React9.createElement(Text7, { bold: true, color: "cyan" }, getTypeLabel()), /* @__PURE__ */ React9.createElement(Text7, { dimColor: true }, " - ", items.length, " items")), /* @__PURE__ */ React9.createElement(Box6, { flexDirection: "column", borderStyle: "round", borderColor: "gray", padding: 1 }, items.map((item, index) => {
2866
- const isSelected = index === selectedIndex;
2867
- return /* @__PURE__ */ React9.createElement(Box6, { key: item.id, flexDirection: "column", marginY: 0 }, /* @__PURE__ */ React9.createElement(Box6, null, /* @__PURE__ */ React9.createElement(Text7, { color: isSelected ? "cyan" : "white" }, isSelected ? "\u276F " : " ", item.name), /* @__PURE__ */ React9.createElement(Text7, { dimColor: true }, " (", formatSize(item.fileSize), ")")), isSelected && /* @__PURE__ */ React9.createElement(Box6, { marginLeft: 3, flexDirection: "column" }, item.description && /* @__PURE__ */ React9.createElement(Text7, { dimColor: true }, "\u{1F4DD} ", item.description), contentType === "rules" && /* @__PURE__ */ React9.createElement(React9.Fragment, null, item.alwaysApply && /* @__PURE__ */ React9.createElement(Text7, { dimColor: true }, "\u2705 Always active"), item.globs && item.globs.length > 0 && /* @__PURE__ */ React9.createElement(Text7, { dimColor: true }, "\u{1F3AF} Globs: ", item.globs.join(", "))), contentType === "skills" && /* @__PURE__ */ React9.createElement(Box6, null, item.hasScripts && /* @__PURE__ */ React9.createElement(Text7, { dimColor: true }, "\u{1F4E6} scripts/ "), item.hasReferences && /* @__PURE__ */ React9.createElement(Text7, { dimColor: true }, "\u{1F4DA} references/ "), item.hasAssets && /* @__PURE__ */ React9.createElement(Text7, { dimColor: true }, "\u{1F3A8} assets/ ")), contentType === "agents" && item.model && /* @__PURE__ */ React9.createElement(Text7, { dimColor: true }, "\u{1F527} Model: ", item.model), /* @__PURE__ */ React9.createElement(Text7, { dimColor: true }, "\u{1F4C1} ", item.relativePath)));
2868
- })));
2869
- };
2870
-
2871
- // src/ui/context/views/DetailView.tsx
2872
- import React10, { useState as useState6 } from "react";
2873
- import { Box as Box7, Text as Text8, useInput as useInput6 } from "ink";
2874
- var DetailView = ({ item, scrollPosition: initialScroll, onBack }) => {
2875
- const [scrollPosition, setScrollPosition] = useState6(initialScroll);
2876
- const maxVisibleLines = 25;
2877
- const maxScroll = Math.max(0, item.previewLines.length - maxVisibleLines);
2878
- useInput6((input5, key) => {
2879
- if (key.upArrow || input5 === "k") {
2880
- setScrollPosition((prev) => Math.max(0, prev - 1));
2881
- } else if (key.downArrow || input5 === "j") {
2882
- setScrollPosition((prev) => Math.min(maxScroll, prev + 1));
2883
- } else if (key.pageDown || input5 === "d") {
2884
- setScrollPosition((prev) => Math.min(maxScroll, prev + 5));
2885
- } else if (key.pageUp || input5 === "u") {
2886
- setScrollPosition((prev) => Math.max(0, prev - 5));
2887
- } else if (input5 === "g") {
2888
- setScrollPosition(0);
2889
- } else if (input5 === "G") {
2890
- setScrollPosition(maxScroll);
2891
- } else if (key.escape || key.backspace) {
2892
- onBack();
2893
- }
2894
- }, { isActive: true });
2895
- const formatSize = (bytes) => {
2896
- if (bytes < 1024) return `${bytes}B`;
2897
- if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}KB`;
2898
- return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
2899
- };
2900
- const formatDate = (date) => {
2901
- return date.toLocaleString("vi-VN", {
2902
- year: "numeric",
2903
- month: "2-digit",
2904
- day: "2-digit",
2905
- hour: "2-digit",
2906
- minute: "2-digit"
2907
- });
2908
- };
2909
- const visibleLines = item.previewLines.slice(
2910
- scrollPosition,
2911
- scrollPosition + maxVisibleLines
2912
- );
2913
- const hasMoreAbove = scrollPosition > 0;
2914
- const hasMoreBelow = scrollPosition + maxVisibleLines < item.previewLines.length;
2915
- const scrollPercentage = item.previewLines.length <= maxVisibleLines ? 100 : Math.round(scrollPosition / maxScroll * 100);
2916
- return /* @__PURE__ */ React10.createElement(Box7, { flexDirection: "column" }, /* @__PURE__ */ React10.createElement(Box7, { flexDirection: "column", marginBottom: 1 }, /* @__PURE__ */ React10.createElement(Text8, { bold: true, color: "cyan" }, item.name), /* @__PURE__ */ React10.createElement(Box7, null, /* @__PURE__ */ React10.createElement(Text8, { dimColor: true }, item.relativePath, " \u2022 ", formatSize(item.fileSize)), item.description && /* @__PURE__ */ React10.createElement(Text8, { dimColor: true }, " \u2022 ", item.description)), /* @__PURE__ */ React10.createElement(Box7, null, item.type === "rules" && item.globs && item.globs.length > 0 && /* @__PURE__ */ React10.createElement(Text8, { dimColor: true }, "globs: ", item.globs.join(", ")), item.type === "agents" && item.model && /* @__PURE__ */ React10.createElement(Text8, { dimColor: true }, "model: ", item.model), item.type === "skills" && /* @__PURE__ */ React10.createElement(Text8, { dimColor: true }, item.hasScripts && "\u{1F4E6} scripts ", item.hasReferences && "\u{1F4DA} refs ", item.hasAssets && "\u{1F3A8} assets"))), /* @__PURE__ */ React10.createElement(Box7, { flexDirection: "column", borderStyle: "round", borderColor: "gray", padding: 1 }, /* @__PURE__ */ React10.createElement(Box7, { justifyContent: "space-between" }, /* @__PURE__ */ React10.createElement(Text8, { bold: true }, "\u{1F441}\uFE0F Preview"), item.previewLines.length > maxVisibleLines && /* @__PURE__ */ React10.createElement(Text8, { dimColor: true }, "[", scrollPosition + 1, "-", Math.min(scrollPosition + maxVisibleLines, item.previewLines.length), "/", item.lineCount, "] ", scrollPercentage, "%")), hasMoreAbove && /* @__PURE__ */ React10.createElement(Box7, { justifyContent: "center" }, /* @__PURE__ */ React10.createElement(Text8, { dimColor: true }, "\u25B2 \u25B2 \u25B2 (", scrollPosition, " d\xF2ng \u1EDF tr\xEAn) \u25B2 \u25B2 \u25B2")), /* @__PURE__ */ React10.createElement(Box7, { flexDirection: "column", marginTop: 1 }, visibleLines.map((line, index) => {
2917
- const lineNumber = scrollPosition + index + 1;
2918
- return /* @__PURE__ */ React10.createElement(Box7, { key: index }, /* @__PURE__ */ React10.createElement(Text8, { dimColor: true }, lineNumber.toString().padStart(3, " "), "\u2502 "), /* @__PURE__ */ React10.createElement(Text8, null, line));
2919
- })), hasMoreBelow && /* @__PURE__ */ React10.createElement(Box7, { justifyContent: "center", marginTop: 1 }, /* @__PURE__ */ React10.createElement(Text8, { dimColor: true }, "\u25BC \u25BC \u25BC (", item.lineCount - scrollPosition - visibleLines.length, " d\xF2ng \u1EDF d\u01B0\u1EDBi) \u25BC \u25BC \u25BC")), item.previewLines.length === 0 && /* @__PURE__ */ React10.createElement(Text8, { dimColor: true }, "Kh\xF4ng c\xF3 n\u1ED9i dung \u0111\u1EC3 hi\u1EC3n th\u1ECB")));
2920
- };
2615
+ import chalk6 from "chalk";
2921
2616
 
2922
2617
  // src/services/context-scanner.service.ts
2923
2618
  import { promises as fs6 } from "fs";
@@ -3267,201 +2962,105 @@ var ContextScannerService = class {
3267
2962
  }
3268
2963
  };
3269
2964
 
3270
- // src/ui/context/ContextApp.tsx
3271
- var ContextApp = ({ initialIDE, initialType, onExit }) => {
3272
- const { exit } = useApp3();
3273
- const [screen, setScreen] = useState7("menu");
3274
- const [selectedIDE, setSelectedIDE] = useState7(initialIDE || null);
3275
- const [selectedType, setSelectedType] = useState7(initialType || null);
3276
- const [selectedItem, setSelectedItem] = useState7(null);
3277
- const [ideContexts, setIdeContexts] = useState7([]);
3278
- const [loading, setLoading] = useState7(true);
3279
- const [scrollPosition, setScrollPosition] = useState7(0);
3280
- useEffect3(() => {
3281
- const scanner = new ContextScannerService();
3282
- scanner.scanAll().then((result) => {
3283
- setIdeContexts(result.ides);
3284
- setLoading(false);
3285
- if (initialIDE) {
3286
- setScreen("overview");
3287
- }
3288
- }).catch((error) => {
3289
- console.error("Failed to scan context:", error);
3290
- setLoading(false);
3291
- });
3292
- }, [initialIDE]);
3293
- useInput7((input5, key) => {
3294
- if (input5 === "q") {
3295
- onExit();
3296
- return;
3297
- }
3298
- if (screen !== "detail" && (key.escape || key.backspace)) {
3299
- handleBack();
3300
- return;
3301
- }
3302
- });
3303
- const handleBack = () => {
3304
- if (screen === "detail") {
3305
- setScreen("list");
3306
- setSelectedItem(null);
3307
- setScrollPosition(0);
3308
- } else if (screen === "list") {
3309
- setScreen("overview");
3310
- setSelectedType(null);
3311
- } else if (screen === "overview") {
3312
- setScreen("menu");
3313
- setSelectedIDE(null);
3314
- } else {
3315
- onExit();
3316
- }
3317
- };
3318
- const handleSelectIDE = (ide) => {
3319
- setSelectedIDE(ide);
3320
- setScreen("overview");
3321
- };
3322
- const handleSelectType = (type) => {
3323
- setSelectedType(type);
3324
- setScreen("list");
3325
- };
3326
- const handleSelectItem = (item) => {
3327
- setSelectedItem(item);
3328
- setScreen("detail");
3329
- setScrollPosition(0);
3330
- };
3331
- const currentIDEContext = ideContexts.find((ctx) => ctx.ide === selectedIDE);
3332
- const currentItems = currentIDEContext?.items?.filter((item) => item.type === selectedType) ?? [];
3333
- const renderContent = () => {
3334
- if (loading) {
3335
- return /* @__PURE__ */ React11.createElement(Box8, { padding: 1 }, /* @__PURE__ */ React11.createElement(Text9, null, "\u0110ang qu\xE9t context..."));
3336
- }
3337
- switch (screen) {
3338
- case "menu":
3339
- return /* @__PURE__ */ React11.createElement(MainMenuView, { ideContexts, onSelect: handleSelectIDE });
3340
- case "overview":
3341
- return currentIDEContext ? /* @__PURE__ */ React11.createElement(
3342
- IDEOverviewView,
3343
- {
3344
- ideContext: currentIDEContext,
3345
- onSelectType: handleSelectType,
3346
- onBack: handleBack
3347
- }
3348
- ) : null;
3349
- case "list":
3350
- return /* @__PURE__ */ React11.createElement(
3351
- ListView,
3352
- {
3353
- items: currentItems,
3354
- contentType: selectedType,
3355
- onSelect: handleSelectItem,
3356
- onBack: handleBack
3357
- }
3358
- );
3359
- case "detail":
3360
- return selectedItem ? /* @__PURE__ */ React11.createElement(
3361
- DetailView,
3362
- {
3363
- item: selectedItem,
3364
- scrollPosition,
3365
- onBack: handleBack
3366
- }
3367
- ) : null;
3368
- default:
3369
- return /* @__PURE__ */ React11.createElement(MainMenuView, { ideContexts, onSelect: handleSelectIDE });
3370
- }
3371
- };
3372
- const getFooterHints = () => {
3373
- switch (screen) {
3374
- case "menu":
3375
- return "[\u2191\u2193] Ch\u1ECDn \xB7 [Enter] M\u1EDF \xB7 [q] Tho\xE1t";
3376
- case "overview":
3377
- return "[Tab/1-6] Chuy\u1EC3n tab \xB7 [Enter] Xem danh s\xE1ch \xB7 [Esc/\u2190] Quay l\u1EA1i \xB7 [q] Tho\xE1t";
3378
- case "list":
3379
- return "[\u2191\u2193] Ch\u1ECDn \xB7 [Enter] Chi ti\u1EBFt \xB7 [Esc/\u2190] Quay l\u1EA1i \xB7 [q] Tho\xE1t";
3380
- case "detail":
3381
- return "[\u2191\u2193/j/k] Cu\u1ED9n \xB7 [PgUp/u PgDn/d] Cu\u1ED9n nhanh \xB7 [g/G] \u0110\u1EA7u/Cu\u1ED1i \xB7 [Esc/\u2190] Quay l\u1EA1i \xB7 [q] Tho\xE1t";
3382
- default:
3383
- return "[q] Tho\xE1t";
2965
+ // src/commands/context.ts
2966
+ var MAX_TOKENS = 256e3;
2967
+ var SYSTEM_PROMPT_TOKENS = 1e4;
2968
+ var COMPACT_BUFFER_TOKENS = 56e3;
2969
+ var BAR_WIDTH = 40;
2970
+ var CHARS_PER_TOKEN = 4;
2971
+ function estimateTokens(bytes) {
2972
+ return Math.ceil(bytes / CHARS_PER_TOKEN);
2973
+ }
2974
+ function formatNumber(n) {
2975
+ return n.toLocaleString("en-US");
2976
+ }
2977
+ function renderBar(value, total, width, color) {
2978
+ const filled = Math.round(value / total * width);
2979
+ const empty = width - filled;
2980
+ return color("\u2588".repeat(filled)) + chalk6.gray("\u2591".repeat(empty));
2981
+ }
2982
+ function renderPercentage(value, total) {
2983
+ return (value / total * 100).toFixed(1) + "%";
2984
+ }
2985
+ function renderIDEContext(ideContext) {
2986
+ const { config, items } = ideContext;
2987
+ const ruleItems = items.filter((item) => item.type === "rules");
2988
+ const rulesTotalBytes = ruleItems.reduce((sum, item) => sum + item.fileSize, 0);
2989
+ const rulesTokens = estimateTokens(rulesTotalBytes);
2990
+ const userPromptTokens = Math.max(0, MAX_TOKENS - SYSTEM_PROMPT_TOKENS - rulesTokens - COMPACT_BUFFER_TOKENS);
2991
+ console.log("");
2992
+ console.log(chalk6.bold(`${config.icon} ${config.name} Context Window (${formatNumber(MAX_TOKENS)} tokens)`));
2993
+ console.log(chalk6.dim("\u2501".repeat(55)));
2994
+ const segments = [
2995
+ { icon: "\u{1F4D0}", label: "System Prompt", tokens: SYSTEM_PROMPT_TOKENS, color: chalk6.blue },
2996
+ { icon: "\u{1F4CF}", label: "IDE Rules", tokens: rulesTokens, color: chalk6.yellow },
2997
+ { icon: "\u{1F4AC}", label: "User Prompt", tokens: userPromptTokens, color: chalk6.green },
2998
+ { icon: "\u{1F504}", label: "Compact Buffer", tokens: COMPACT_BUFFER_TOKENS, color: chalk6.magenta }
2999
+ ];
3000
+ const maxLabelLen = Math.max(...segments.map((s) => s.label.length));
3001
+ for (const seg of segments) {
3002
+ const label = seg.label.padEnd(maxLabelLen);
3003
+ const bar = renderBar(seg.tokens, MAX_TOKENS, BAR_WIDTH, seg.color);
3004
+ const pct = renderPercentage(seg.tokens, MAX_TOKENS);
3005
+ console.log(` ${seg.icon} ${label} ${bar} ${chalk6.white(formatNumber(seg.tokens).padStart(7))} tokens ${chalk6.dim(`(${pct})`)}`);
3006
+ }
3007
+ if (ruleItems.length > 0) {
3008
+ console.log("");
3009
+ console.log(chalk6.dim(` Rules breakdown (${config.basePath}):`));
3010
+ const sorted = [...ruleItems].sort((a, b) => b.fileSize - a.fileSize);
3011
+ for (const rule of sorted) {
3012
+ const tokens = estimateTokens(rule.fileSize);
3013
+ const name = typeof rule.name === "string" ? rule.name : rule.relativePath;
3014
+ const badge = rule.alwaysApply ? chalk6.cyan(" [always]") : "";
3015
+ console.log(` \u2022 ${chalk6.white(name)}${badge} ${chalk6.dim(formatNumber(tokens) + " tokens")}`);
3384
3016
  }
3385
- };
3386
- return /* @__PURE__ */ React11.createElement(Box8, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React11.createElement(Box8, { marginBottom: 1 }, /* @__PURE__ */ React11.createElement(Text9, { bold: true, color: "cyan" }, "\u{1F4CB} Jai1 Context"), /* @__PURE__ */ React11.createElement(Text9, { dimColor: true }, " - Kh\xE1m ph\xE1 context d\u1EF1 \xE1n")), renderContent(), /* @__PURE__ */ React11.createElement(Box8, { marginTop: 1, borderStyle: "single", borderColor: "gray", paddingX: 1 }, /* @__PURE__ */ React11.createElement(Text9, { dimColor: true }, getFooterHints())));
3387
- };
3388
-
3389
- // src/commands/ide/context.ts
3390
- function createContextSubcommand() {
3391
- const cmd = new Command7("context").description("Browse and explore IDE context (rules, workflows, skills)").option("--target <ide>", "Open specific IDE context (cursor, windsurf, antigravity, jai1)").option("--type <type>", "Show specific content type (rules, workflows, skills, agents, prompts)").option("--stats", "Show context statistics (non-interactive)").action(async (options) => {
3392
- let initialIDE;
3393
- if (options.target) {
3394
- const validIDEs = ["cursor", "windsurf", "antigravity", "jai1"];
3395
- if (!validIDEs.includes(options.target)) {
3396
- console.error(`\u274C Invalid IDE: ${options.target}`);
3397
- console.error(` Valid IDEs: ${validIDEs.join(", ")}`);
3017
+ } else {
3018
+ console.log("");
3019
+ console.log(chalk6.dim(" No rules found."));
3020
+ }
3021
+ console.log("");
3022
+ }
3023
+ function createContextCommand() {
3024
+ const cmd = new Command7("context").description("Visualize IDE context window token budget").argument("[ide]", "Show specific IDE only (cursor, windsurf, antigravity)").action(async (ideArg) => {
3025
+ const name = getCliName();
3026
+ const validIDEs = ["cursor", "windsurf", "antigravity"];
3027
+ if (ideArg) {
3028
+ if (!validIDEs.includes(ideArg)) {
3029
+ console.error(chalk6.red(`\u274C Invalid IDE: ${ideArg}`));
3030
+ console.error(chalk6.dim(` Valid IDEs: ${validIDEs.join(", ")}`));
3031
+ console.error(chalk6.dim(` Usage: ${name} context [ide]`));
3398
3032
  process.exit(1);
3399
3033
  }
3400
- initialIDE = options.target;
3401
3034
  }
3402
- let initialType;
3403
- if (options.type) {
3404
- const validTypes = ["rules", "workflows", "skills", "agents", "prompts", "context"];
3405
- if (!validTypes.includes(options.type)) {
3406
- console.error(`\u274C Invalid content type: ${options.type}`);
3407
- console.error(` Valid types: ${validTypes.join(", ")}`);
3408
- process.exit(1);
3035
+ const scanner = new ContextScannerService();
3036
+ const targetIDEs = ideArg ? [ideArg] : validIDEs;
3037
+ console.log(chalk6.bold.cyan("\n\u{1F9E0} Context Window Analysis"));
3038
+ console.log(chalk6.dim(` Max context: ${formatNumber(MAX_TOKENS)} tokens
3039
+ `));
3040
+ let found = false;
3041
+ for (const ide of targetIDEs) {
3042
+ try {
3043
+ const ideContext = await scanner.scanIDE(ide);
3044
+ const config = IDE_CONFIGS[ide];
3045
+ if (config) {
3046
+ renderIDEContext(ideContext);
3047
+ found = true;
3048
+ }
3049
+ } catch {
3409
3050
  }
3410
- initialType = options.type;
3411
3051
  }
3412
- if (options.stats) {
3413
- await printStats();
3414
- return;
3052
+ if (!found) {
3053
+ console.log(chalk6.yellow("\u26A0\uFE0F No IDEs detected in this project."));
3054
+ console.log(chalk6.dim(` Run "${name} apply" to install context for your IDE.
3055
+ `));
3415
3056
  }
3416
- const { waitUntilExit } = render3(
3417
- React12.createElement(ContextApp, {
3418
- initialIDE,
3419
- initialType,
3420
- onExit: () => {
3421
- process.exit(0);
3422
- }
3423
- })
3424
- );
3425
- await waitUntilExit();
3426
3057
  });
3427
3058
  return cmd;
3428
3059
  }
3429
- async function printStats() {
3430
- const scanner = new ContextScannerService();
3431
- console.log("\u{1F50D} Scanning context...\n");
3432
- try {
3433
- const context = await scanner.scanAll();
3434
- if (context.ides.length === 0) {
3435
- console.log("\u26A0\uFE0F No context found");
3436
- console.log(" Run `jai1 apply` to install context for your IDE.\n");
3437
- return;
3438
- }
3439
- console.log("\u{1F4CA} Context Statistics\n");
3440
- console.log(`\u{1F4C1} Project: ${context.projectPath}`);
3441
- console.log(`\u{1F550} Scan time: ${context.scanTime.toLocaleString("en-US")}
3442
- `);
3443
- for (const ideContext of context.ides) {
3444
- console.log(`${ideContext.config.icon} ${ideContext.config.name}`);
3445
- console.log(` Path: ${ideContext.config.basePath}`);
3446
- console.log(` Items: ${ideContext.stats.totalItems}`);
3447
- const types = [];
3448
- if (ideContext.stats.byType.rules) types.push(`${ideContext.stats.byType.rules} rules`);
3449
- if (ideContext.stats.byType.workflows) types.push(`${ideContext.stats.byType.workflows} workflows`);
3450
- if (ideContext.stats.byType.skills) types.push(`${ideContext.stats.byType.skills} skills`);
3451
- if (ideContext.stats.byType.agents) types.push(`${ideContext.stats.byType.agents} agents`);
3452
- if (ideContext.stats.byType.prompts) types.push(`${ideContext.stats.byType.prompts} prompts`);
3453
- if (ideContext.stats.byType.context) types.push(`${ideContext.stats.byType.context} context`);
3454
- if (types.length > 0) {
3455
- console.log(` Breakdown: ${types.join(", ")}`);
3456
- }
3457
- console.log("");
3458
- }
3459
- console.log(`\u2705 Total: ${context.totalItems} items
3460
- `);
3461
- } catch (error) {
3462
- console.error("\u274C Error scanning context:", error);
3463
- process.exit(1);
3464
- }
3060
+
3061
+ // src/commands/ide/context.ts
3062
+ function createContextSubcommand() {
3063
+ return createContextCommand();
3465
3064
  }
3466
3065
 
3467
3066
  // src/commands/ide/setup.ts
@@ -4342,24 +3941,24 @@ function getConfidenceEmoji(confidence) {
4342
3941
 
4343
3942
  // src/commands/ide/index.ts
4344
3943
  function showIdeHelp() {
4345
- console.log(chalk6.bold.cyan("\u{1F5A5}\uFE0F jai1 ide") + chalk6.dim(" - IDE integration v\xE0 c\u1EA5u h\xECnh"));
3944
+ console.log(chalk7.bold.cyan("\u{1F5A5}\uFE0F jai1 ide") + chalk7.dim(" - IDE integration v\xE0 c\u1EA5u h\xECnh"));
4346
3945
  console.log();
4347
- console.log(chalk6.bold("C\xE1c l\u1EC7nh:"));
4348
- console.log(` ${chalk6.cyan("context")} Duy\u1EC7t v\xE0 kh\xE1m ph\xE1 IDE context`);
4349
- console.log(` ${chalk6.cyan("setup")} C\u1EA5u h\xECnh IDE settings (VSCode optimizations)`);
4350
- console.log(` ${chalk6.cyan("sync")} \u0110\u1ED3ng b\u1ED9 .jai1 content \u0111\u1EBFn IDE directories`);
4351
- console.log(` ${chalk6.cyan("status")} Hi\u1EC3n th\u1ECB c\xE1c IDE \u0111\u01B0\u1EE3c ph\xE1t hi\u1EC7n v\xE0 tr\u1EA1ng th\xE1i`);
3946
+ console.log(chalk7.bold("C\xE1c l\u1EC7nh:"));
3947
+ console.log(` ${chalk7.cyan("context")} Duy\u1EC7t v\xE0 kh\xE1m ph\xE1 IDE context`);
3948
+ console.log(` ${chalk7.cyan("setup")} C\u1EA5u h\xECnh IDE settings (VSCode optimizations)`);
3949
+ console.log(` ${chalk7.cyan("sync")} \u0110\u1ED3ng b\u1ED9 .jai1 content \u0111\u1EBFn IDE directories`);
3950
+ console.log(` ${chalk7.cyan("status")} Hi\u1EC3n th\u1ECB c\xE1c IDE \u0111\u01B0\u1EE3c ph\xE1t hi\u1EC7n v\xE0 tr\u1EA1ng th\xE1i`);
4352
3951
  console.log();
4353
- console.log(chalk6.bold("IDEs \u0111\u01B0\u1EE3c h\u1ED7 tr\u1EE3:"));
4354
- console.log(chalk6.dim(" Cursor, Windsurf, VSCode, Trae, Claude"));
3952
+ console.log(chalk7.bold("IDEs \u0111\u01B0\u1EE3c h\u1ED7 tr\u1EE3:"));
3953
+ console.log(chalk7.dim(" Cursor, Windsurf, VSCode, Trae, Claude"));
4355
3954
  console.log();
4356
- console.log(chalk6.bold("V\xED d\u1EE5:"));
4357
- console.log(chalk6.dim(" $ jai1 ide status"));
4358
- console.log(chalk6.dim(" $ jai1 ide setup --optimize"));
4359
- console.log(chalk6.dim(" $ jai1 ide sync"));
4360
- console.log(chalk6.dim(" $ jai1 ide context"));
3955
+ console.log(chalk7.bold("V\xED d\u1EE5:"));
3956
+ console.log(chalk7.dim(" $ jai1 ide status"));
3957
+ console.log(chalk7.dim(" $ jai1 ide setup --optimize"));
3958
+ console.log(chalk7.dim(" $ jai1 ide sync"));
3959
+ console.log(chalk7.dim(" $ jai1 ide context"));
4361
3960
  console.log();
4362
- console.log(chalk6.dim('Ch\u1EA1y "jai1 ide <l\u1EC7nh> --help" \u0111\u1EC3 xem chi ti\u1EBFt'));
3961
+ console.log(chalk7.dim('Ch\u1EA1y "jai1 ide <l\u1EC7nh> --help" \u0111\u1EC3 xem chi ti\u1EBFt'));
4363
3962
  }
4364
3963
  function createIdeCommand() {
4365
3964
  const ideCommand = new Command11("ide").description("IDE integration and configuration commands").action(() => {
@@ -4374,7 +3973,7 @@ function createIdeCommand() {
4374
3973
 
4375
3974
  // src/commands/guide.ts
4376
3975
  import { Command as Command12 } from "commander";
4377
- import chalk7 from "chalk";
3976
+ import chalk8 from "chalk";
4378
3977
  function createGuideCommand() {
4379
3978
  const cmd = new Command12("guide").description("H\u01B0\u1EDBng d\u1EABn s\u1EED d\u1EE5ng nhanh").action(() => {
4380
3979
  const name = getCliName();
@@ -4383,66 +3982,66 @@ function createGuideCommand() {
4383
3982
  return cmd;
4384
3983
  }
4385
3984
  function showGuide(name) {
4386
- console.log(chalk7.cyan.bold("\n\u{1F4D6} Jai1 Framework - H\u01B0\u1EDBng d\u1EABn s\u1EED d\u1EE5ng nhanh\n"));
4387
- console.log(chalk7.bold("\u2501\u2501\u2501 THI\u1EBET L\u1EACP \u2501\u2501\u2501"));
4388
- console.log(` ${chalk7.cyan(`${name} auth`)} X\xE1c th\u1EF1c v\xE0 c\u1EA5u h\xECnh client`);
4389
- console.log(` ${chalk7.cyan(`${name} status`)} Hi\u1EC3n th\u1ECB tr\u1EA1ng th\xE1i c\u1EA5u h\xECnh`);
4390
- console.log(` ${chalk7.cyan(`${name} doctor`)} Chu\u1EA9n \u0111o\xE1n project hi\u1EC7n t\u1EA1i`);
3985
+ console.log(chalk8.cyan.bold("\n\u{1F4D6} Jai1 Framework - H\u01B0\u1EDBng d\u1EABn s\u1EED d\u1EE5ng nhanh\n"));
3986
+ console.log(chalk8.bold("\u2501\u2501\u2501 THI\u1EBET L\u1EACP \u2501\u2501\u2501"));
3987
+ console.log(` ${chalk8.cyan(`${name} auth`)} X\xE1c th\u1EF1c v\xE0 c\u1EA5u h\xECnh client`);
3988
+ console.log(` ${chalk8.cyan(`${name} status`)} Hi\u1EC3n th\u1ECB tr\u1EA1ng th\xE1i c\u1EA5u h\xECnh`);
3989
+ console.log(` ${chalk8.cyan(`${name} doctor`)} Chu\u1EA9n \u0111o\xE1n project hi\u1EC7n t\u1EA1i`);
4391
3990
  console.log();
4392
- console.log(chalk7.bold("\u2501\u2501\u2501 CORE PACKAGE \u2501\u2501\u2501"));
4393
- console.log(` ${chalk7.cyan(`${name} apply`)} C\xE0i \u0111\u1EB7t components (interactive)`);
4394
- console.log(` ${chalk7.cyan(`${name} apply core`)} C\xE0i core package (headless)`);
4395
- console.log(` ${chalk7.cyan(`${name} check`)} Ki\u1EC3m tra c\u1EADp nh\u1EADt t\u1EEB server`);
4396
- console.log(` ${chalk7.cyan(`${name} update`)} C\u1EADp nh\u1EADt components \u0111\xE3 c\xE0i`);
4397
- console.log(` ${chalk7.cyan(`${name} upgrade`)} C\u1EADp nh\u1EADt CLI client`);
3991
+ console.log(chalk8.bold("\u2501\u2501\u2501 CORE PACKAGE \u2501\u2501\u2501"));
3992
+ console.log(` ${chalk8.cyan(`${name} apply`)} C\xE0i \u0111\u1EB7t components (interactive)`);
3993
+ console.log(` ${chalk8.cyan(`${name} apply core`)} C\xE0i core package (headless)`);
3994
+ console.log(` ${chalk8.cyan(`${name} check`)} Ki\u1EC3m tra c\u1EADp nh\u1EADt t\u1EEB server`);
3995
+ console.log(` ${chalk8.cyan(`${name} update`)} C\u1EADp nh\u1EADt components \u0111\xE3 c\xE0i`);
3996
+ console.log(` ${chalk8.cyan(`${name} upgrade`)} C\u1EADp nh\u1EADt CLI client`);
4398
3997
  console.log();
4399
- console.log(chalk7.dim(" Workflow ph\u1ED5 bi\u1EBFn:"));
4400
- console.log(chalk7.dim(` 1. ${name} auth # \u0110\u0103ng nh\u1EADp l\u1EA7n \u0111\u1EA7u`));
4401
- console.log(chalk7.dim(` 2. ${name} apply core # C\xE0i core package`));
4402
- console.log(chalk7.dim(` 3. ${name} rules apply # C\u1EA5u h\xECnh rules cho IDE`));
4403
- console.log(chalk7.dim(` 4. ${name} ide sync # \u0110\u1ED3ng b\u1ED9 sang IDE`));
4404
- console.log(chalk7.dim(` 5. ${name} check # Ki\u1EC3m tra c\u1EADp nh\u1EADt \u0111\u1ECBnh k\u1EF3`));
3998
+ console.log(chalk8.dim(" Workflow ph\u1ED5 bi\u1EBFn:"));
3999
+ console.log(chalk8.dim(` 1. ${name} auth # \u0110\u0103ng nh\u1EADp l\u1EA7n \u0111\u1EA7u`));
4000
+ console.log(chalk8.dim(` 2. ${name} apply core # C\xE0i core package`));
4001
+ console.log(chalk8.dim(` 3. ${name} rules apply # C\u1EA5u h\xECnh rules cho IDE`));
4002
+ console.log(chalk8.dim(` 4. ${name} ide sync # \u0110\u1ED3ng b\u1ED9 sang IDE`));
4003
+ console.log(chalk8.dim(` 5. ${name} check # Ki\u1EC3m tra c\u1EADp nh\u1EADt \u0111\u1ECBnh k\u1EF3`));
4405
4004
  console.log();
4406
- console.log(chalk7.bold("\u2501\u2501\u2501 IDE \u2501\u2501\u2501"));
4407
- console.log(` ${chalk7.cyan(`${name} ide status`)} C\xE1c IDE \u0111\u01B0\u1EE3c ph\xE1t hi\u1EC7n`);
4408
- console.log(` ${chalk7.cyan(`${name} ide setup`)} C\u1EA5u h\xECnh IDE (VSCode optimizations)`);
4409
- console.log(` ${chalk7.cyan(`${name} ide sync`)} \u0110\u1ED3ng b\u1ED9 .jai1 content \u0111\u1EBFn IDE`);
4410
- console.log(` ${chalk7.cyan(`${name} rules apply`)} C\u1EA5u h\xECnh rules cho IDE`);
4005
+ console.log(chalk8.bold("\u2501\u2501\u2501 IDE \u2501\u2501\u2501"));
4006
+ console.log(` ${chalk8.cyan(`${name} ide status`)} C\xE1c IDE \u0111\u01B0\u1EE3c ph\xE1t hi\u1EC7n`);
4007
+ console.log(` ${chalk8.cyan(`${name} ide setup`)} C\u1EA5u h\xECnh IDE (VSCode optimizations)`);
4008
+ console.log(` ${chalk8.cyan(`${name} ide sync`)} \u0110\u1ED3ng b\u1ED9 .jai1 content \u0111\u1EBFn IDE`);
4009
+ console.log(` ${chalk8.cyan(`${name} rules apply`)} C\u1EA5u h\xECnh rules cho IDE`);
4411
4010
  console.log();
4412
- console.log(chalk7.bold("\u2501\u2501\u2501 TASK MANAGEMENT \u2501\u2501\u2501"));
4413
- console.log(` ${chalk7.cyan(`${name} t add`)} ${chalk7.dim('"title"')} ${chalk7.dim("[-p 0-3] [-P parent]")} T\u1EA1o task`);
4414
- console.log(` ${chalk7.cyan(`${name} t list`)} ${chalk7.dim("[-s status] [-P parent]")} Li\u1EC7t k\xEA tasks`);
4415
- console.log(` ${chalk7.cyan(`${name} t ready`)} Tasks s\u1EB5n s\xE0ng`);
4416
- console.log(` ${chalk7.cyan(`${name} t pick`)} Claim & b\u1EAFt \u0111\u1EA7u`);
4417
- console.log(` ${chalk7.cyan(`${name} t done`)} ${chalk7.dim("<id>")} Ho\xE0n th\xE0nh task`);
4418
- console.log(` ${chalk7.cyan(`${name} t summary`)} Dashboard t\u1ED5ng quan`);
4419
- console.log(` ${chalk7.cyan(`${name} t guide`)} H\u01B0\u1EDBng d\u1EABn chi ti\u1EBFt`);
4011
+ console.log(chalk8.bold("\u2501\u2501\u2501 TASK MANAGEMENT \u2501\u2501\u2501"));
4012
+ console.log(` ${chalk8.cyan(`${name} t add`)} ${chalk8.dim('"title"')} ${chalk8.dim("[-p 0-3] [-P parent]")} T\u1EA1o task`);
4013
+ console.log(` ${chalk8.cyan(`${name} t list`)} ${chalk8.dim("[-s status] [-P parent]")} Li\u1EC7t k\xEA tasks`);
4014
+ console.log(` ${chalk8.cyan(`${name} t ready`)} Tasks s\u1EB5n s\xE0ng`);
4015
+ console.log(` ${chalk8.cyan(`${name} t pick`)} Claim & b\u1EAFt \u0111\u1EA7u`);
4016
+ console.log(` ${chalk8.cyan(`${name} t done`)} ${chalk8.dim("<id>")} Ho\xE0n th\xE0nh task`);
4017
+ console.log(` ${chalk8.cyan(`${name} t summary`)} Dashboard t\u1ED5ng quan`);
4018
+ console.log(` ${chalk8.cyan(`${name} t guide`)} H\u01B0\u1EDBng d\u1EABn chi ti\u1EBFt`);
4420
4019
  console.log();
4421
- console.log(chalk7.bold("\u2501\u2501\u2501 WORKFLOWS (d\xF9ng trong IDE) \u2501\u2501\u2501"));
4422
- console.log(` ${chalk7.cyan("/improve")} ${chalk7.dim("[feature]")} Ph\xE2n t\xEDch & \u0111\u1EC1 xu\u1EA5t c\u1EA3i thi\u1EC7n project`);
4423
- console.log(` ${chalk7.cyan("/plan")} ${chalk7.dim("[task]")} L\xEAn k\u1EBF ho\u1EA1ch nhanh \u2192 tasks \u2192 implement`);
4424
- console.log(` ${chalk7.cyan("/develop-feature")} ${chalk7.dim("[feature]")} Ph\xE1t tri\u1EC3n t\xEDnh n\u0103ng (FRD \u2192 TDD \u2192 Code)`);
4425
- console.log(` ${chalk7.cyan("/fix-bug")} ${chalk7.dim("[bug]")} Ph\xE2n t\xEDch & s\u1EEDa bug`);
4426
- console.log(` ${chalk7.cyan("/commit-it")} Commit an to\xE0n v\u1EDBi message chi ti\u1EBFt`);
4020
+ console.log(chalk8.bold("\u2501\u2501\u2501 WORKFLOWS (d\xF9ng trong IDE) \u2501\u2501\u2501"));
4021
+ console.log(` ${chalk8.cyan("/improve")} ${chalk8.dim("[feature]")} Ph\xE2n t\xEDch & \u0111\u1EC1 xu\u1EA5t c\u1EA3i thi\u1EC7n project`);
4022
+ console.log(` ${chalk8.cyan("/plan")} ${chalk8.dim("[task]")} L\xEAn k\u1EBF ho\u1EA1ch nhanh \u2192 tasks \u2192 implement`);
4023
+ console.log(` ${chalk8.cyan("/develop-feature")} ${chalk8.dim("[feature]")} Ph\xE1t tri\u1EC3n t\xEDnh n\u0103ng (FRD \u2192 TDD \u2192 Code)`);
4024
+ console.log(` ${chalk8.cyan("/fix-bug")} ${chalk8.dim("[bug]")} Ph\xE2n t\xEDch & s\u1EEDa bug`);
4025
+ console.log(` ${chalk8.cyan("/commit-it")} Commit an to\xE0n v\u1EDBi message chi ti\u1EBFt`);
4427
4026
  console.log();
4428
- console.log(chalk7.dim(" Workflow c\u1EA3i thi\u1EC7n project:"));
4429
- console.log(chalk7.dim(" 1. /improve # Ph\xE2n t\xEDch & \u0111\u1EC1 xu\u1EA5t"));
4430
- console.log(chalk7.dim(" 2. Ch\u1ECDn improvements c\u1EA7n l\xE0m # User x\xE1c nh\u1EADn"));
4431
- console.log(chalk7.dim(" 3. \u2192 T\u1EF1 \u0111\u1ED9ng g\u1ECDi /plan # T\u1EA1o tasks & implement"));
4027
+ console.log(chalk8.dim(" Workflow c\u1EA3i thi\u1EC7n project:"));
4028
+ console.log(chalk8.dim(" 1. /improve # Ph\xE2n t\xEDch & \u0111\u1EC1 xu\u1EA5t"));
4029
+ console.log(chalk8.dim(" 2. Ch\u1ECDn improvements c\u1EA7n l\xE0m # User x\xE1c nh\u1EADn"));
4030
+ console.log(chalk8.dim(" 3. \u2192 T\u1EF1 \u0111\u1ED9ng g\u1ECDi /plan # T\u1EA1o tasks & implement"));
4432
4031
  console.log();
4433
- console.log(chalk7.bold("\u2501\u2501\u2501 AI TOOLS \u2501\u2501\u2501"));
4434
- console.log(` ${chalk7.cyan(`${name} chat`)} Chat AI qua Jai1 LLM Proxy`);
4435
- console.log(` ${chalk7.cyan(`${name} translate`)} D\u1ECBch v\u0103n b\u1EA3n/file b\u1EB1ng AI`);
4436
- console.log(` ${chalk7.cyan(`${name} image`)} T\u1EA1o \u1EA3nh b\u1EB1ng AI`);
4032
+ console.log(chalk8.bold("\u2501\u2501\u2501 AI TOOLS \u2501\u2501\u2501"));
4033
+ console.log(` ${chalk8.cyan(`${name} chat`)} Chat AI qua Jai1 LLM Proxy`);
4034
+ console.log(` ${chalk8.cyan(`${name} translate`)} D\u1ECBch v\u0103n b\u1EA3n/file b\u1EB1ng AI`);
4035
+ console.log(` ${chalk8.cyan(`${name} image`)} T\u1EA1o \u1EA3nh b\u1EB1ng AI`);
4437
4036
  console.log();
4438
- console.log(chalk7.dim(`\u{1F4A1} Ch\u1EA1y "${name} <l\u1EC7nh> --help" \u0111\u1EC3 xem chi ti\u1EBFt t\u1EEBng l\u1EC7nh.`));
4439
- console.log(chalk7.dim(`\u{1F4A1} Ch\u1EA1y "${name} t guide" \u0111\u1EC3 xem h\u01B0\u1EDBng d\u1EABn task management \u0111\u1EA7y \u0111\u1EE7.`));
4037
+ console.log(chalk8.dim(`\u{1F4A1} Ch\u1EA1y "${name} <l\u1EC7nh> --help" \u0111\u1EC3 xem chi ti\u1EBFt t\u1EEBng l\u1EC7nh.`));
4038
+ console.log(chalk8.dim(`\u{1F4A1} Ch\u1EA1y "${name} t guide" \u0111\u1EC3 xem h\u01B0\u1EDBng d\u1EABn task management \u0111\u1EA7y \u0111\u1EE7.`));
4440
4039
  console.log();
4441
4040
  }
4442
4041
 
4443
4042
  // src/commands/doctor.ts
4444
4043
  import { Command as Command13 } from "commander";
4445
- import chalk8 from "chalk";
4044
+ import chalk9 from "chalk";
4446
4045
  import { promises as fs9 } from "fs";
4447
4046
  import { join as join6 } from "path";
4448
4047
  var CORE_FILES = [
@@ -4470,8 +4069,8 @@ async function runDoctor(options) {
4470
4069
  const name = getCliName();
4471
4070
  const results = [];
4472
4071
  if (!options.json) {
4473
- console.log(chalk8.cyan.bold("\n\u{1FA7A} Jai1 Doctor\n"));
4474
- console.log(chalk8.dim(` \u0110ang ki\u1EC3m tra project t\u1EA1i: ${process.cwd()}
4072
+ console.log(chalk9.cyan.bold("\n\u{1FA7A} Jai1 Doctor\n"));
4073
+ console.log(chalk9.dim(` \u0110ang ki\u1EC3m tra project t\u1EA1i: ${process.cwd()}
4475
4074
  `));
4476
4075
  }
4477
4076
  results.push(await checkAuth(name));
@@ -4484,27 +4083,27 @@ async function runDoctor(options) {
4484
4083
  return;
4485
4084
  }
4486
4085
  for (const result of results) {
4487
- const icon = result.passed ? chalk8.green("\u2713") : chalk8.red("\u2717");
4488
- const label = result.passed ? chalk8.green(result.message) : chalk8.red(result.message);
4489
- console.log(` ${icon} ${chalk8.bold(result.name)}: ${label}`);
4086
+ const icon = result.passed ? chalk9.green("\u2713") : chalk9.red("\u2717");
4087
+ const label = result.passed ? chalk9.green(result.message) : chalk9.red(result.message);
4088
+ console.log(` ${icon} ${chalk9.bold(result.name)}: ${label}`);
4490
4089
  if (result.details && result.details.length > 0) {
4491
4090
  for (const detail of result.details) {
4492
- console.log(chalk8.dim(` ${detail}`));
4091
+ console.log(chalk9.dim(` ${detail}`));
4493
4092
  }
4494
4093
  }
4495
4094
  if (!result.passed && result.suggestion) {
4496
- console.log(chalk8.yellow(` \u{1F4A1} ${result.suggestion}`));
4095
+ console.log(chalk9.yellow(` \u{1F4A1} ${result.suggestion}`));
4497
4096
  }
4498
4097
  console.log();
4499
4098
  }
4500
4099
  const passed = results.filter((r) => r.passed).length;
4501
4100
  const total = results.length;
4502
4101
  if (passed === total) {
4503
- console.log(chalk8.green.bold(` \u2705 T\u1EA5t c\u1EA3 ${total} ki\u1EC3m tra \u0111\xE3 pass!
4102
+ console.log(chalk9.green.bold(` \u2705 T\u1EA5t c\u1EA3 ${total} ki\u1EC3m tra \u0111\xE3 pass!
4504
4103
  `));
4505
4104
  } else {
4506
4105
  console.log(
4507
- chalk8.yellow(` \u26A0\uFE0F ${passed}/${total} ki\u1EC3m tra pass. Xem g\u1EE3i \xFD \u1EDF tr\xEAn \u0111\u1EC3 s\u1EEDa.
4106
+ chalk9.yellow(` \u26A0\uFE0F ${passed}/${total} ki\u1EC3m tra pass. Xem g\u1EE3i \xFD \u1EDF tr\xEAn \u0111\u1EC3 s\u1EEDa.
4508
4107
  `)
4509
4108
  );
4510
4109
  }
@@ -4656,8 +4255,8 @@ async function checkIde(cliName) {
4656
4255
 
4657
4256
  // src/commands/chat.ts
4658
4257
  import { Command as Command14 } from "commander";
4659
- import React18 from "react";
4660
- import { render as render4 } from "ink";
4258
+ import React12 from "react";
4259
+ import { render as render3 } from "ink";
4661
4260
 
4662
4261
  // src/services/llm-proxy.service.ts
4663
4262
  var LlmProxyService = class {
@@ -4884,16 +4483,16 @@ var LlmProxyService = class {
4884
4483
  };
4885
4484
 
4886
4485
  // src/ui/llm/LlmApp.tsx
4887
- import React17, { useState as useState11, useEffect as useEffect5, useMemo as useMemo3, useCallback as useCallback3, useRef as useRef2 } from "react";
4888
- import { Box as Box13, Text as Text14, useInput as useInput9, useApp as useApp4, useStdout } from "ink";
4486
+ import React11, { useState as useState6, useEffect as useEffect4, useMemo as useMemo3, useCallback as useCallback3, useRef as useRef2 } from "react";
4487
+ import { Box as Box8, Text as Text9, useInput as useInput4, useApp as useApp3, useStdout } from "ink";
4889
4488
  import Spinner4 from "ink-spinner";
4890
4489
 
4891
4490
  // src/ui/llm/hooks/useChat.ts
4892
- import { useState as useState8, useCallback } from "react";
4491
+ import { useState as useState3, useCallback } from "react";
4893
4492
  function useChat(service) {
4894
- const [messages, setMessages] = useState8([]);
4895
- const [isStreaming, setIsStreaming] = useState8(false);
4896
- const [error, setError] = useState8(null);
4493
+ const [messages, setMessages] = useState3([]);
4494
+ const [isStreaming, setIsStreaming] = useState3(false);
4495
+ const [error, setError] = useState3(null);
4897
4496
  const sendMessage = useCallback(
4898
4497
  async (content, model) => {
4899
4498
  if (!content.trim() || isStreaming) return;
@@ -4962,9 +4561,9 @@ function useChat(service) {
4962
4561
  }
4963
4562
 
4964
4563
  // src/ui/llm/hooks/useLlmApi.ts
4965
- import { useState as useState9, useEffect as useEffect4, useCallback as useCallback2, useRef } from "react";
4564
+ import { useState as useState4, useEffect as useEffect3, useCallback as useCallback2, useRef } from "react";
4966
4565
  function useLlmApi(service) {
4967
- const [state, setState] = useState9({
4566
+ const [state, setState] = useState4({
4968
4567
  models: [],
4969
4568
  limits: null,
4970
4569
  usage: null,
@@ -4997,7 +4596,7 @@ function useLlmApi(service) {
4997
4596
  }));
4998
4597
  }
4999
4598
  }, [service]);
5000
- useEffect4(() => {
4599
+ useEffect3(() => {
5001
4600
  if (!hasFetched.current) {
5002
4601
  hasFetched.current = true;
5003
4602
  fetchData(true);
@@ -5013,26 +4612,26 @@ function useLlmApi(service) {
5013
4612
  }
5014
4613
 
5015
4614
  // src/ui/llm/components/ChatPanel.tsx
5016
- import React15, { memo as memo3 } from "react";
5017
- import { Box as Box11, Text as Text12 } from "ink";
4615
+ import React9, { memo as memo3 } from "react";
4616
+ import { Box as Box6, Text as Text7 } from "ink";
5018
4617
  import Spinner3 from "ink-spinner";
5019
4618
 
5020
4619
  // src/ui/llm/components/MessageItem.tsx
5021
- import React13, { memo } from "react";
5022
- import { Box as Box9, Text as Text10 } from "ink";
4620
+ import React7, { memo } from "react";
4621
+ import { Box as Box4, Text as Text5 } from "ink";
5023
4622
  var MessageItem = memo(({ message }) => {
5024
4623
  if (message.role === "user") {
5025
- return /* @__PURE__ */ React13.createElement(Box9, { flexDirection: "column", marginBottom: 1 }, /* @__PURE__ */ React13.createElement(Text10, { color: "cyan", bold: true }, "You:"), /* @__PURE__ */ React13.createElement(Text10, { wrap: "wrap" }, message.content));
4624
+ return /* @__PURE__ */ React7.createElement(Box4, { flexDirection: "column", marginBottom: 1 }, /* @__PURE__ */ React7.createElement(Text5, { color: "cyan", bold: true }, "You:"), /* @__PURE__ */ React7.createElement(Text5, { wrap: "wrap" }, message.content));
5026
4625
  }
5027
4626
  if (message.role === "assistant") {
5028
- return /* @__PURE__ */ React13.createElement(Box9, { flexDirection: "column", marginBottom: 1 }, /* @__PURE__ */ React13.createElement(Text10, { color: "green", bold: true }, "Jai1:"), /* @__PURE__ */ React13.createElement(Text10, { wrap: "wrap" }, message.content));
4627
+ return /* @__PURE__ */ React7.createElement(Box4, { flexDirection: "column", marginBottom: 1 }, /* @__PURE__ */ React7.createElement(Text5, { color: "green", bold: true }, "Jai1:"), /* @__PURE__ */ React7.createElement(Text5, { wrap: "wrap" }, message.content));
5029
4628
  }
5030
- return /* @__PURE__ */ React13.createElement(Box9, { marginBottom: 1 }, /* @__PURE__ */ React13.createElement(Text10, { dimColor: true, italic: true }, message.content));
4629
+ return /* @__PURE__ */ React7.createElement(Box4, { marginBottom: 1 }, /* @__PURE__ */ React7.createElement(Text5, { dimColor: true, italic: true }, message.content));
5031
4630
  });
5032
4631
 
5033
4632
  // src/ui/llm/components/InputBox.tsx
5034
- import React14, { memo as memo2 } from "react";
5035
- import { Box as Box10, Text as Text11 } from "ink";
4633
+ import React8, { memo as memo2 } from "react";
4634
+ import { Box as Box5, Text as Text6 } from "ink";
5036
4635
  import TextInput3 from "ink-text-input";
5037
4636
  var InputBox = memo2(({
5038
4637
  value,
@@ -5040,7 +4639,7 @@ var InputBox = memo2(({
5040
4639
  onSubmit,
5041
4640
  disabled = false,
5042
4641
  focused = true
5043
- }) => /* @__PURE__ */ React14.createElement(Box10, { borderStyle: "round", borderColor: "cyan", paddingX: 1 }, /* @__PURE__ */ React14.createElement(Text11, { color: "cyan" }, "\u276F "), !disabled ? /* @__PURE__ */ React14.createElement(
4642
+ }) => /* @__PURE__ */ React8.createElement(Box5, { borderStyle: "round", borderColor: "cyan", paddingX: 1 }, /* @__PURE__ */ React8.createElement(Text6, { color: "cyan" }, "\u276F "), !disabled ? /* @__PURE__ */ React8.createElement(
5044
4643
  TextInput3,
5045
4644
  {
5046
4645
  value,
@@ -5049,19 +4648,19 @@ var InputBox = memo2(({
5049
4648
  placeholder: "Type your message...",
5050
4649
  focus: focused
5051
4650
  }
5052
- ) : /* @__PURE__ */ React14.createElement(Text11, { dimColor: true }, "Waiting...")));
4651
+ ) : /* @__PURE__ */ React8.createElement(Text6, { dimColor: true }, "Waiting...")));
5053
4652
 
5054
4653
  // src/ui/llm/components/ChatPanel.tsx
5055
4654
  var MessageList = memo3(({ messages }) => {
5056
4655
  const visible = messages.slice(-8);
5057
4656
  const hidden = messages.length - visible.length;
5058
4657
  if (visible.length === 0) {
5059
- return /* @__PURE__ */ React15.createElement(Box11, { flexDirection: "column", alignItems: "center", padding: 1 }, /* @__PURE__ */ React15.createElement(Text12, { dimColor: true }, "Start a conversation..."), /* @__PURE__ */ React15.createElement(Text12, { dimColor: true }, "Type / for commands"));
4658
+ return /* @__PURE__ */ React9.createElement(Box6, { flexDirection: "column", alignItems: "center", padding: 1 }, /* @__PURE__ */ React9.createElement(Text7, { dimColor: true }, "Start a conversation..."), /* @__PURE__ */ React9.createElement(Text7, { dimColor: true }, "Type / for commands"));
5060
4659
  }
5061
- return /* @__PURE__ */ React15.createElement(React15.Fragment, null, hidden > 0 && /* @__PURE__ */ React15.createElement(Text12, { dimColor: true }, "(", hidden, " earlier)"), visible.map((m) => /* @__PURE__ */ React15.createElement(MessageItem, { key: m.id, message: m })));
4660
+ return /* @__PURE__ */ React9.createElement(React9.Fragment, null, hidden > 0 && /* @__PURE__ */ React9.createElement(Text7, { dimColor: true }, "(", hidden, " earlier)"), visible.map((m) => /* @__PURE__ */ React9.createElement(MessageItem, { key: m.id, message: m })));
5062
4661
  });
5063
- var SlashMenu = memo3(({ commands, index }) => /* @__PURE__ */ React15.createElement(Box11, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1 }, /* @__PURE__ */ React15.createElement(Text12, { bold: true, color: "cyan" }, "Commands"), commands.map((cmd, i) => /* @__PURE__ */ React15.createElement(
5064
- Text12,
4662
+ var SlashMenu = memo3(({ commands, index }) => /* @__PURE__ */ React9.createElement(Box6, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1 }, /* @__PURE__ */ React9.createElement(Text7, { bold: true, color: "cyan" }, "Commands"), commands.map((cmd, i) => /* @__PURE__ */ React9.createElement(
4663
+ Text7,
5065
4664
  {
5066
4665
  key: cmd.name,
5067
4666
  backgroundColor: i === index ? "cyan" : void 0,
@@ -5086,7 +4685,7 @@ var ChatPanel = ({
5086
4685
  minHeight = 15
5087
4686
  }) => {
5088
4687
  const messagesMinHeight = Math.max(5, minHeight - 4 - (showSlashMenu ? 5 : 0));
5089
- return /* @__PURE__ */ React15.createElement(Box11, { flexDirection: "column" }, /* @__PURE__ */ React15.createElement(Box11, { flexDirection: "column", borderStyle: "round", borderColor: "gray", padding: 1, minHeight: messagesMinHeight }, /* @__PURE__ */ React15.createElement(MessageList, { messages }), isStreaming && /* @__PURE__ */ React15.createElement(Text12, { color: "green" }, /* @__PURE__ */ React15.createElement(Spinner3, { type: "dots" }), " Responding...")), showSlashMenu && slashCommands.length > 0 && /* @__PURE__ */ React15.createElement(SlashMenu, { commands: slashCommands, index: slashMenuIndex }), /* @__PURE__ */ React15.createElement(
4688
+ return /* @__PURE__ */ React9.createElement(Box6, { flexDirection: "column" }, /* @__PURE__ */ React9.createElement(Box6, { flexDirection: "column", borderStyle: "round", borderColor: "gray", padding: 1, minHeight: messagesMinHeight }, /* @__PURE__ */ React9.createElement(MessageList, { messages }), isStreaming && /* @__PURE__ */ React9.createElement(Text7, { color: "green" }, /* @__PURE__ */ React9.createElement(Spinner3, { type: "dots" }), " Responding...")), showSlashMenu && slashCommands.length > 0 && /* @__PURE__ */ React9.createElement(SlashMenu, { commands: slashCommands, index: slashMenuIndex }), /* @__PURE__ */ React9.createElement(
5090
4689
  InputBox,
5091
4690
  {
5092
4691
  value: inputValue,
@@ -5099,8 +4698,8 @@ var ChatPanel = ({
5099
4698
  };
5100
4699
 
5101
4700
  // src/ui/llm/components/ModelSelector.tsx
5102
- import React16, { useState as useState10 } from "react";
5103
- import { Box as Box12, Text as Text13, useInput as useInput8 } from "ink";
4701
+ import React10, { useState as useState5 } from "react";
4702
+ import { Box as Box7, Text as Text8, useInput as useInput3 } from "ink";
5104
4703
  var ModelSelector = ({
5105
4704
  models,
5106
4705
  currentModel,
@@ -5109,8 +4708,8 @@ var ModelSelector = ({
5109
4708
  }) => {
5110
4709
  const allowedModels = models.filter((m) => m.allowed);
5111
4710
  const currentIndex = allowedModels.findIndex((m) => m.id === currentModel);
5112
- const [selectedIndex, setSelectedIndex] = useState10(Math.max(0, currentIndex));
5113
- useInput8((input5, key) => {
4711
+ const [selectedIndex, setSelectedIndex] = useState5(Math.max(0, currentIndex));
4712
+ useInput3((input5, key) => {
5114
4713
  if (key.escape) {
5115
4714
  onCancel();
5116
4715
  return;
@@ -5127,8 +4726,8 @@ var ModelSelector = ({
5127
4726
  }
5128
4727
  });
5129
4728
  if (allowedModels.length === 0) {
5130
- return /* @__PURE__ */ React16.createElement(
5131
- Box12,
4729
+ return /* @__PURE__ */ React10.createElement(
4730
+ Box7,
5132
4731
  {
5133
4732
  flexDirection: "column",
5134
4733
  borderStyle: "round",
@@ -5136,12 +4735,12 @@ var ModelSelector = ({
5136
4735
  padding: 1,
5137
4736
  width: 60
5138
4737
  },
5139
- /* @__PURE__ */ React16.createElement(Text13, { color: "red", bold: true }, "No models available"),
5140
- /* @__PURE__ */ React16.createElement(Text13, { dimColor: true }, "Press Esc to close")
4738
+ /* @__PURE__ */ React10.createElement(Text8, { color: "red", bold: true }, "No models available"),
4739
+ /* @__PURE__ */ React10.createElement(Text8, { dimColor: true }, "Press Esc to close")
5141
4740
  );
5142
4741
  }
5143
- return /* @__PURE__ */ React16.createElement(
5144
- Box12,
4742
+ return /* @__PURE__ */ React10.createElement(
4743
+ Box7,
5145
4744
  {
5146
4745
  flexDirection: "column",
5147
4746
  borderStyle: "round",
@@ -5149,8 +4748,8 @@ var ModelSelector = ({
5149
4748
  padding: 1,
5150
4749
  width: 70
5151
4750
  },
5152
- /* @__PURE__ */ React16.createElement(Box12, { marginBottom: 1 }, /* @__PURE__ */ React16.createElement(Text13, { bold: true, color: "cyan" }, "\u2699\uFE0F Select Model")),
5153
- /* @__PURE__ */ React16.createElement(Box12, { flexDirection: "column", marginBottom: 1 }, allowedModels.map((model, i) => {
4751
+ /* @__PURE__ */ React10.createElement(Box7, { marginBottom: 1 }, /* @__PURE__ */ React10.createElement(Text8, { bold: true, color: "cyan" }, "\u2699\uFE0F Select Model")),
4752
+ /* @__PURE__ */ React10.createElement(Box7, { flexDirection: "column", marginBottom: 1 }, allowedModels.map((model, i) => {
5154
4753
  const isSelected = i === selectedIndex;
5155
4754
  const isCurrent = model.id === currentModel;
5156
4755
  const icon = isSelected ? "\u25CF" : "\u25CB";
@@ -5158,8 +4757,8 @@ var ModelSelector = ({
5158
4757
  if (model.dailyLimit !== void 0 && model.usedToday !== void 0) {
5159
4758
  usageText = ` (${model.usedToday}/${model.dailyLimit})`;
5160
4759
  }
5161
- return /* @__PURE__ */ React16.createElement(Box12, { key: model.id, marginY: 0 }, /* @__PURE__ */ React16.createElement(
5162
- Text13,
4760
+ return /* @__PURE__ */ React10.createElement(Box7, { key: model.id, marginY: 0 }, /* @__PURE__ */ React10.createElement(
4761
+ Text8,
5163
4762
  {
5164
4763
  backgroundColor: isSelected ? "cyan" : void 0,
5165
4764
  color: isSelected ? "black" : "white"
@@ -5172,7 +4771,7 @@ var ModelSelector = ({
5172
4771
  usageText
5173
4772
  ));
5174
4773
  })),
5175
- /* @__PURE__ */ React16.createElement(Box12, { borderStyle: "single", borderColor: "gray", paddingX: 1 }, /* @__PURE__ */ React16.createElement(Text13, { dimColor: true }, "[\u2191\u2193] Navigate [Enter] Select [Esc] Cancel"))
4774
+ /* @__PURE__ */ React10.createElement(Box7, { borderStyle: "single", borderColor: "gray", paddingX: 1 }, /* @__PURE__ */ React10.createElement(Text8, { dimColor: true }, "[\u2191\u2193] Navigate [Enter] Select [Esc] Cancel"))
5176
4775
  );
5177
4776
  };
5178
4777
 
@@ -5183,17 +4782,17 @@ var SLASH_COMMANDS = [
5183
4782
  { name: "quit", description: "Exit the chat", aliases: ["q", "exit"] }
5184
4783
  ];
5185
4784
  var ChatApp = ({ service, initialModel }) => {
5186
- const { exit } = useApp4();
4785
+ const { exit } = useApp3();
5187
4786
  const { stdout } = useStdout();
5188
4787
  const contentHeight = useRef2(Math.max(10, (stdout?.rows || 24) - 6));
5189
- const [currentView, setCurrentView] = useState11("loading");
5190
- const [showSlashMenu, setShowSlashMenu] = useState11(false);
5191
- const [slashMenuIndex, setSlashMenuIndex] = useState11(0);
5192
- const [inputValue, setInputValue] = useState11("");
5193
- const [selectedModel, setSelectedModel] = useState11("");
4788
+ const [currentView, setCurrentView] = useState6("loading");
4789
+ const [showSlashMenu, setShowSlashMenu] = useState6(false);
4790
+ const [slashMenuIndex, setSlashMenuIndex] = useState6(0);
4791
+ const [inputValue, setInputValue] = useState6("");
4792
+ const [selectedModel, setSelectedModel] = useState6("");
5194
4793
  const { models, loading, error, refetch } = useLlmApi(service);
5195
4794
  const { messages, isStreaming, sendMessage } = useChat(service);
5196
- useEffect5(() => {
4795
+ useEffect4(() => {
5197
4796
  if (error && !loading) {
5198
4797
  setCurrentView("error");
5199
4798
  return;
@@ -5236,7 +4835,7 @@ var ChatApp = ({ service, initialModel }) => {
5236
4835
  }
5237
4836
  return false;
5238
4837
  }, [refetch, exit]);
5239
- useInput9((input5, key) => {
4838
+ useInput4((input5, key) => {
5240
4839
  if (showSlashMenu) {
5241
4840
  if (key.upArrow) {
5242
4841
  setSlashMenuIndex((i) => Math.max(0, i - 1));
@@ -5297,16 +4896,16 @@ var ChatApp = ({ service, initialModel }) => {
5297
4896
  }, []);
5298
4897
  const statsView = useMemo3(() => {
5299
4898
  const allowed = models.filter((m) => m.allowed);
5300
- return /* @__PURE__ */ React17.createElement(Box13, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", padding: 1 }, /* @__PURE__ */ React17.createElement(Text14, { bold: true, color: "cyan" }, "\u{1F4CA} Model Usage Statistics"), allowed.map((m) => {
4899
+ return /* @__PURE__ */ React11.createElement(Box8, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", padding: 1 }, /* @__PURE__ */ React11.createElement(Text9, { bold: true, color: "cyan" }, "\u{1F4CA} Model Usage Statistics"), allowed.map((m) => {
5301
4900
  const limit = m.dailyLimit ?? 0;
5302
4901
  const used = m.usedToday ?? 0;
5303
4902
  const pct = limit > 0 ? Math.round(used / limit * 100) : 0;
5304
4903
  const bar = "\u2588".repeat(Math.round(pct / 5)) + "\u2591".repeat(20 - Math.round(pct / 5));
5305
- return /* @__PURE__ */ React17.createElement(Box13, { key: m.id, flexDirection: "column" }, /* @__PURE__ */ React17.createElement(Text14, { color: m.id === selectedModel ? "yellow" : "white" }, m.id === selectedModel ? "\u25BA " : " ", m.id), /* @__PURE__ */ React17.createElement(Text14, { color: pct > 80 ? "red" : pct > 50 ? "yellow" : "green" }, " ", bar, " ", /* @__PURE__ */ React17.createElement(Text14, { dimColor: true }, used, "/", limit)));
5306
- }), /* @__PURE__ */ React17.createElement(Text14, { dimColor: true }, "[Esc] Back"));
4904
+ return /* @__PURE__ */ React11.createElement(Box8, { key: m.id, flexDirection: "column" }, /* @__PURE__ */ React11.createElement(Text9, { color: m.id === selectedModel ? "yellow" : "white" }, m.id === selectedModel ? "\u25BA " : " ", m.id), /* @__PURE__ */ React11.createElement(Text9, { color: pct > 80 ? "red" : pct > 50 ? "yellow" : "green" }, " ", bar, " ", /* @__PURE__ */ React11.createElement(Text9, { dimColor: true }, used, "/", limit)));
4905
+ }), /* @__PURE__ */ React11.createElement(Text9, { dimColor: true }, "[Esc] Back"));
5307
4906
  }, [models, selectedModel]);
5308
4907
  const footer = currentView === "error" ? "[Enter/r] Retry \u2022 [Esc] Quit" : currentView === "model" || currentView === "stats" ? "[\u2191\u2193] Navigate \u2022 [Enter] Select \u2022 [Esc] Back" : showSlashMenu ? "[\u2191\u2193] Navigate \u2022 [Enter] Select \u2022 [Esc] Cancel" : "[Tab] Next Model \u2022 [/] Commands \u2022 [Esc] Quit";
5309
- return /* @__PURE__ */ React17.createElement(Box13, { flexDirection: "column" }, /* @__PURE__ */ React17.createElement(Box13, { borderStyle: "double", borderColor: "magenta", paddingX: 1 }, /* @__PURE__ */ React17.createElement(Text14, { bold: true, color: "magenta" }, "\u{1F916} Jai1 Chat"), /* @__PURE__ */ React17.createElement(Box13, { flexGrow: 1 }), /* @__PURE__ */ React17.createElement(Text14, { dimColor: true }, "Model: "), /* @__PURE__ */ React17.createElement(Text14, { color: "yellow", bold: true }, selectedModel || "...")), currentView === "loading" ? /* @__PURE__ */ React17.createElement(Box13, { padding: 2, minHeight: contentHeight.current, alignItems: "center", justifyContent: "center" }, /* @__PURE__ */ React17.createElement(Text14, null, /* @__PURE__ */ React17.createElement(Spinner4, { type: "dots" }), " Loading...")) : currentView === "error" ? /* @__PURE__ */ React17.createElement(Box13, { padding: 2, minHeight: contentHeight.current, alignItems: "center", justifyContent: "center", flexDirection: "column" }, /* @__PURE__ */ React17.createElement(Text14, { color: "red", bold: true }, "Connection Error"), /* @__PURE__ */ React17.createElement(Text14, { color: "red" }, error), /* @__PURE__ */ React17.createElement(Text14, { dimColor: true }, " "), /* @__PURE__ */ React17.createElement(Text14, { dimColor: true }, "Press Enter or 'r' to retry")) : currentView === "model" ? /* @__PURE__ */ React17.createElement(Box13, { padding: 1, minHeight: contentHeight.current, justifyContent: "center", alignItems: "center" }, /* @__PURE__ */ React17.createElement(
4908
+ return /* @__PURE__ */ React11.createElement(Box8, { flexDirection: "column" }, /* @__PURE__ */ React11.createElement(Box8, { borderStyle: "double", borderColor: "magenta", paddingX: 1 }, /* @__PURE__ */ React11.createElement(Text9, { bold: true, color: "magenta" }, "\u{1F916} Jai1 Chat"), /* @__PURE__ */ React11.createElement(Box8, { flexGrow: 1 }), /* @__PURE__ */ React11.createElement(Text9, { dimColor: true }, "Model: "), /* @__PURE__ */ React11.createElement(Text9, { color: "yellow", bold: true }, selectedModel || "...")), currentView === "loading" ? /* @__PURE__ */ React11.createElement(Box8, { padding: 2, minHeight: contentHeight.current, alignItems: "center", justifyContent: "center" }, /* @__PURE__ */ React11.createElement(Text9, null, /* @__PURE__ */ React11.createElement(Spinner4, { type: "dots" }), " Loading...")) : currentView === "error" ? /* @__PURE__ */ React11.createElement(Box8, { padding: 2, minHeight: contentHeight.current, alignItems: "center", justifyContent: "center", flexDirection: "column" }, /* @__PURE__ */ React11.createElement(Text9, { color: "red", bold: true }, "Connection Error"), /* @__PURE__ */ React11.createElement(Text9, { color: "red" }, error), /* @__PURE__ */ React11.createElement(Text9, { dimColor: true }, " "), /* @__PURE__ */ React11.createElement(Text9, { dimColor: true }, "Press Enter or 'r' to retry")) : currentView === "model" ? /* @__PURE__ */ React11.createElement(Box8, { padding: 1, minHeight: contentHeight.current, justifyContent: "center", alignItems: "center" }, /* @__PURE__ */ React11.createElement(
5310
4909
  ModelSelector,
5311
4910
  {
5312
4911
  models,
@@ -5314,7 +4913,7 @@ var ChatApp = ({ service, initialModel }) => {
5314
4913
  onSelect: onSelectModel,
5315
4914
  onCancel: () => setCurrentView("chat")
5316
4915
  }
5317
- )) : currentView === "stats" ? /* @__PURE__ */ React17.createElement(Box13, { padding: 1, minHeight: contentHeight.current, justifyContent: "center", alignItems: "center" }, statsView) : /* @__PURE__ */ React17.createElement(
4916
+ )) : currentView === "stats" ? /* @__PURE__ */ React11.createElement(Box8, { padding: 1, minHeight: contentHeight.current, justifyContent: "center", alignItems: "center" }, statsView) : /* @__PURE__ */ React11.createElement(
5318
4917
  ChatPanel,
5319
4918
  {
5320
4919
  messages,
@@ -5328,7 +4927,7 @@ var ChatApp = ({ service, initialModel }) => {
5328
4927
  slashMenuIndex,
5329
4928
  minHeight: contentHeight.current
5330
4929
  }
5331
- ), /* @__PURE__ */ React17.createElement(Box13, { borderStyle: "single", borderColor: "gray", paddingX: 1 }, /* @__PURE__ */ React17.createElement(Text14, { dimColor: true }, footer)));
4930
+ ), /* @__PURE__ */ React11.createElement(Box8, { borderStyle: "single", borderColor: "gray", paddingX: 1 }, /* @__PURE__ */ React11.createElement(Text9, { dimColor: true }, footer)));
5332
4931
  };
5333
4932
 
5334
4933
  // src/server/web-chat-server.ts
@@ -6232,8 +5831,8 @@ async function handleTerminalChat(options) {
6232
5831
  throw new ValidationError('Not initialized. Run "jai1 auth" first.');
6233
5832
  }
6234
5833
  const service = new LlmProxyService(config);
6235
- const { waitUntilExit, clear } = render4(
6236
- React18.createElement(ChatApp, {
5834
+ const { waitUntilExit, clear } = render3(
5835
+ React12.createElement(ChatApp, {
6237
5836
  service,
6238
5837
  initialModel: options.model
6239
5838
  }),
@@ -6305,7 +5904,7 @@ function createChatCommand() {
6305
5904
 
6306
5905
  // src/commands/openai-keys.ts
6307
5906
  import { Command as Command15 } from "commander";
6308
- import chalk9 from "chalk";
5907
+ import chalk10 from "chalk";
6309
5908
  import boxen3 from "boxen";
6310
5909
  function maskKey2(key) {
6311
5910
  if (key.length <= 8) return "****";
@@ -6319,17 +5918,17 @@ async function handleOpenAiKeysCommand(options) {
6319
5918
  }
6320
5919
  const service = new LlmProxyService(config);
6321
5920
  console.log(
6322
- boxen3(chalk9.cyan.bold("\u{1F4E1} Jai1 LLM Proxy - OpenAI Compatible API"), {
5921
+ boxen3(chalk10.cyan.bold("\u{1F4E1} Jai1 LLM Proxy - OpenAI Compatible API"), {
6323
5922
  padding: { top: 0, bottom: 0, left: 1, right: 1 },
6324
5923
  borderStyle: "round",
6325
5924
  borderColor: "cyan"
6326
5925
  })
6327
5926
  );
6328
5927
  console.log();
6329
- console.log(chalk9.bold("\u{1F511} API Credentials"));
6330
- console.log(` ${chalk9.dim("BASE_URL:")} ${chalk9.white(service.getBaseUrl())}`);
5928
+ console.log(chalk10.bold("\u{1F511} API Credentials"));
5929
+ console.log(` ${chalk10.dim("BASE_URL:")} ${chalk10.white(service.getBaseUrl())}`);
6331
5930
  console.log(
6332
- ` ${chalk9.dim("API_KEY:")} ${options.full ? chalk9.green(service.getApiKey()) : chalk9.yellow(maskKey2(service.getApiKey()))}`
5931
+ ` ${chalk10.dim("API_KEY:")} ${options.full ? chalk10.green(service.getApiKey()) : chalk10.yellow(maskKey2(service.getApiKey()))}`
6333
5932
  );
6334
5933
  console.log();
6335
5934
  try {
@@ -6338,39 +5937,39 @@ async function handleOpenAiKeysCommand(options) {
6338
5937
  service.getLimits()
6339
5938
  ]);
6340
5939
  const allowedModels = models.filter((m) => m.allowed);
6341
- console.log(chalk9.bold("\u{1F4E6} Available Models"));
5940
+ console.log(chalk10.bold("\u{1F4E6} Available Models"));
6342
5941
  if (allowedModels.length === 0) {
6343
- console.log(chalk9.dim(" Kh\xF4ng c\xF3 models kh\u1EA3 d\u1EE5ng"));
5942
+ console.log(chalk10.dim(" Kh\xF4ng c\xF3 models kh\u1EA3 d\u1EE5ng"));
6344
5943
  } else {
6345
5944
  for (const model of allowedModels) {
6346
- const usageText = model.dailyLimit !== void 0 && model.usedToday !== void 0 ? chalk9.dim(` (${model.usedToday}/${model.dailyLimit} h\xF4m nay)`) : "";
6347
- console.log(` ${chalk9.green("\u2713")} ${chalk9.white(model.id)}${usageText}`);
5945
+ const usageText = model.dailyLimit !== void 0 && model.usedToday !== void 0 ? chalk10.dim(` (${model.usedToday}/${model.dailyLimit} h\xF4m nay)`) : "";
5946
+ console.log(` ${chalk10.green("\u2713")} ${chalk10.white(model.id)}${usageText}`);
6348
5947
  }
6349
5948
  }
6350
5949
  console.log();
6351
5950
  const defaultModel = allowedModels[0]?.id || "gpt-4o";
6352
- console.log(chalk9.bold("\u{1F4DD} Sample cURL"));
5951
+ console.log(chalk10.bold("\u{1F4DD} Sample cURL"));
6353
5952
  console.log();
6354
5953
  const curlSample = options.full ? service.generateFullCurlSample(defaultModel) : service.generateCurlSample(defaultModel);
6355
5954
  const curlLines = curlSample.split("\n");
6356
5955
  for (const line of curlLines) {
6357
- console.log(chalk9.dim(` ${line}`));
5956
+ console.log(chalk10.dim(` ${line}`));
6358
5957
  }
6359
5958
  console.log();
6360
- console.log(chalk9.bold("\u{1F4A1} C\xE1ch s\u1EED d\u1EE5ng"));
6361
- console.log(chalk9.dim(" - Thay th\u1EBF OpenAI API URL v\xE0 API Key"));
6362
- console.log(chalk9.dim(" - T\u01B0\u01A1ng th\xEDch: OpenAI SDK, LangChain, LlamaIndex, v.v."));
6363
- console.log(chalk9.dim(' - Ch\u1EA1y "jai1 chat" \u0111\u1EC3 chat tr\u1EF1c ti\u1EBFp'));
5959
+ console.log(chalk10.bold("\u{1F4A1} C\xE1ch s\u1EED d\u1EE5ng"));
5960
+ console.log(chalk10.dim(" - Thay th\u1EBF OpenAI API URL v\xE0 API Key"));
5961
+ console.log(chalk10.dim(" - T\u01B0\u01A1ng th\xEDch: OpenAI SDK, LangChain, LlamaIndex, v.v."));
5962
+ console.log(chalk10.dim(' - Ch\u1EA1y "jai1 chat" \u0111\u1EC3 chat tr\u1EF1c ti\u1EBFp'));
6364
5963
  if (!options.full) {
6365
- console.log(chalk9.dim(' - Ch\u1EA1y "jai1 openai-keys --full" \u0111\u1EC3 hi\u1EC3n th\u1ECB API key \u0111\u1EA7y \u0111\u1EE7'));
5964
+ console.log(chalk10.dim(' - Ch\u1EA1y "jai1 openai-keys --full" \u0111\u1EC3 hi\u1EC3n th\u1ECB API key \u0111\u1EA7y \u0111\u1EE7'));
6366
5965
  }
6367
5966
  } catch (error) {
6368
5967
  console.log();
6369
5968
  console.log(
6370
- chalk9.red("\u274C L\u1ED7i khi l\u1EA5y th\xF4ng tin API:"),
6371
- chalk9.dim(error instanceof Error ? error.message : String(error))
5969
+ chalk10.red("\u274C L\u1ED7i khi l\u1EA5y th\xF4ng tin API:"),
5970
+ chalk10.dim(error instanceof Error ? error.message : String(error))
6372
5971
  );
6373
- console.log(chalk9.dim('\n\u{1F4A1} Ki\u1EC3m tra API URL v\xE0 access key v\u1EDBi "jai1 status"'));
5972
+ console.log(chalk10.dim('\n\u{1F4A1} Ki\u1EC3m tra API URL v\xE0 access key v\u1EDBi "jai1 status"'));
6374
5973
  }
6375
5974
  }
6376
5975
  function createOpenAiKeysCommand() {
@@ -6383,7 +5982,7 @@ function createOpenAiKeysCommand() {
6383
5982
  // src/commands/stats.ts
6384
5983
  import { Command as Command16 } from "commander";
6385
5984
  import Table2 from "cli-table3";
6386
- import chalk10 from "chalk";
5985
+ import chalk11 from "chalk";
6387
5986
  async function handleStatsCommand() {
6388
5987
  const configService = new ConfigService();
6389
5988
  const config = await configService.load();
@@ -6393,8 +5992,8 @@ async function handleStatsCommand() {
6393
5992
  );
6394
5993
  }
6395
5994
  const service = new LlmProxyService(config);
6396
- console.log(chalk10.bold("\n\u{1F4CA} Th\u1ED1ng K\xEA S\u1EED D\u1EE5ng LLM"));
6397
- console.log(chalk10.dim("\u2500".repeat(45)));
5995
+ console.log(chalk11.bold("\n\u{1F4CA} Th\u1ED1ng K\xEA S\u1EED D\u1EE5ng LLM"));
5996
+ console.log(chalk11.dim("\u2500".repeat(45)));
6398
5997
  try {
6399
5998
  const [limits, usage7Days, usageToday] = await Promise.all([
6400
5999
  service.getLimits(),
@@ -6404,7 +6003,7 @@ async function handleStatsCommand() {
6404
6003
  const today = (/* @__PURE__ */ new Date()).toLocaleDateString("en-CA", {
6405
6004
  timeZone: "Asia/Ho_Chi_Minh"
6406
6005
  });
6407
- console.log(chalk10.cyan("\n\u{1F4C5} Kho\u1EA3ng th\u1EDDi gian: 7 ng\xE0y qua\n"));
6006
+ console.log(chalk11.cyan("\n\u{1F4C5} Kho\u1EA3ng th\u1EDDi gian: 7 ng\xE0y qua\n"));
6408
6007
  const usageByModel = /* @__PURE__ */ new Map();
6409
6008
  let total7DaysRequests = 0;
6410
6009
  usage7Days.data?.forEach((record) => {
@@ -6424,16 +6023,16 @@ async function handleStatsCommand() {
6424
6023
  modelData.today = record.count;
6425
6024
  }
6426
6025
  });
6427
- console.log(chalk10.bold("\u{1F4C8} T\u1ED5ng quan s\u1EED d\u1EE5ng"));
6428
- console.log(` T\u1ED5ng s\u1ED1 y\xEAu c\u1EA7u (7 ng\xE0y): ${chalk10.green(total7DaysRequests)}
6026
+ console.log(chalk11.bold("\u{1F4C8} T\u1ED5ng quan s\u1EED d\u1EE5ng"));
6027
+ console.log(` T\u1ED5ng s\u1ED1 y\xEAu c\u1EA7u (7 ng\xE0y): ${chalk11.green(total7DaysRequests)}
6429
6028
  `);
6430
- console.log(chalk10.bold("\u{1F4E6} Th\u1ED1ng k\xEA theo model\n"));
6029
+ console.log(chalk11.bold("\u{1F4E6} Th\u1ED1ng k\xEA theo model\n"));
6431
6030
  const table = new Table2({
6432
6031
  head: [
6433
- chalk10.bold("Model"),
6434
- chalk10.bold("H\xF4m nay"),
6435
- chalk10.bold("Gi\u1EDBi h\u1EA1n"),
6436
- chalk10.bold("T\u1ED5ng 7 ng\xE0y")
6032
+ chalk11.bold("Model"),
6033
+ chalk11.bold("H\xF4m nay"),
6034
+ chalk11.bold("Gi\u1EDBi h\u1EA1n"),
6035
+ chalk11.bold("T\u1ED5ng 7 ng\xE0y")
6437
6036
  ],
6438
6037
  style: {
6439
6038
  head: ["cyan"],
@@ -6445,7 +6044,7 @@ async function handleStatsCommand() {
6445
6044
  const rateLimits = limits.effectiveRateLimits || {};
6446
6045
  if (allowedModels.length === 0) {
6447
6046
  table.push([
6448
- { colSpan: 4, content: chalk10.yellow("Kh\xF4ng c\xF3 model n\xE0o kh\u1EA3 d\u1EE5ng") }
6047
+ { colSpan: 4, content: chalk11.yellow("Kh\xF4ng c\xF3 model n\xE0o kh\u1EA3 d\u1EE5ng") }
6449
6048
  ]);
6450
6049
  } else {
6451
6050
  allowedModels.forEach((modelId) => {
@@ -6454,25 +6053,25 @@ async function handleStatsCommand() {
6454
6053
  const usagePercent = limit > 0 ? usage.today / limit : 0;
6455
6054
  let todayDisplay = `${usage.today}/${limit}`;
6456
6055
  if (usagePercent >= 0.9) {
6457
- todayDisplay = chalk10.red(todayDisplay);
6056
+ todayDisplay = chalk11.red(todayDisplay);
6458
6057
  } else if (usagePercent >= 0.7) {
6459
- todayDisplay = chalk10.yellow(todayDisplay);
6058
+ todayDisplay = chalk11.yellow(todayDisplay);
6460
6059
  } else {
6461
- todayDisplay = chalk10.green(todayDisplay);
6060
+ todayDisplay = chalk11.green(todayDisplay);
6462
6061
  }
6463
6062
  table.push([modelId, todayDisplay, `${limit}/ng\xE0y`, String(usage.total7Days)]);
6464
6063
  });
6465
6064
  }
6466
6065
  console.log(table.toString());
6467
6066
  console.log(
6468
- chalk10.dim('\n\u{1F4A1} M\u1EB9o: Ch\u1EA1y "jai1 openai-keys" \u0111\u1EC3 xem danh s\xE1ch model kh\u1EA3 d\u1EE5ng')
6067
+ chalk11.dim('\n\u{1F4A1} M\u1EB9o: Ch\u1EA1y "jai1 openai-keys" \u0111\u1EC3 xem danh s\xE1ch model kh\u1EA3 d\u1EE5ng')
6469
6068
  );
6470
6069
  } catch (error) {
6471
6070
  console.error(
6472
- chalk10.red("\n\u274C Kh\xF4ng th\u1EC3 l\u1EA5y th\u1ED1ng k\xEA:"),
6071
+ chalk11.red("\n\u274C Kh\xF4ng th\u1EC3 l\u1EA5y th\u1ED1ng k\xEA:"),
6473
6072
  error instanceof Error ? error.message : String(error)
6474
6073
  );
6475
- console.log(chalk10.dim('\n\u{1F4A1} Ki\u1EC3m tra k\u1EBFt n\u1ED1i API v\u1EDBi "jai1 status"'));
6074
+ console.log(chalk11.dim('\n\u{1F4A1} Ki\u1EC3m tra k\u1EBFt n\u1ED1i API v\u1EDBi "jai1 status"'));
6476
6075
  }
6477
6076
  }
6478
6077
  function createStatsCommand() {
@@ -6839,7 +6438,7 @@ function createTranslateCommand() {
6839
6438
 
6840
6439
  // src/commands/image/index.ts
6841
6440
  import { Command as Command22 } from "commander";
6842
- import chalk11 from "chalk";
6441
+ import chalk12 from "chalk";
6843
6442
 
6844
6443
  // src/commands/image/gen.ts
6845
6444
  import { Command as Command18 } from "commander";
@@ -7114,22 +6713,22 @@ function createImageDeleteCommand() {
7114
6713
 
7115
6714
  // src/commands/image/index.ts
7116
6715
  function showImageHelp() {
7117
- console.log(chalk11.bold.cyan("\u{1F3A8} jai1 image") + chalk11.dim(" - Image generation commands"));
6716
+ console.log(chalk12.bold.cyan("\u{1F3A8} jai1 image") + chalk12.dim(" - Image generation commands"));
7118
6717
  console.log();
7119
- console.log(chalk11.yellow("\u26A0\uFE0F Coming Soon - T\xEDnh n\u0103ng \u0111ang ph\xE1t tri\u1EC3n"));
6718
+ console.log(chalk12.yellow("\u26A0\uFE0F Coming Soon - T\xEDnh n\u0103ng \u0111ang ph\xE1t tri\u1EC3n"));
7120
6719
  console.log();
7121
- console.log(chalk11.bold("C\xE1c l\u1EC7nh:"));
7122
- console.log(` ${chalk11.cyan("gen")} T\u1EA1o \u1EA3nh t\u1EEB prompt`);
7123
- console.log(` ${chalk11.cyan("list")} Li\u1EC7t k\xEA c\xE1c \u1EA3nh \u0111\xE3 t\u1EA1o`);
7124
- console.log(` ${chalk11.cyan("info")} Xem th\xF4ng tin \u1EA3nh`);
7125
- console.log(` ${chalk11.cyan("delete")} X\xF3a \u1EA3nh`);
6720
+ console.log(chalk12.bold("C\xE1c l\u1EC7nh:"));
6721
+ console.log(` ${chalk12.cyan("gen")} T\u1EA1o \u1EA3nh t\u1EEB prompt`);
6722
+ console.log(` ${chalk12.cyan("list")} Li\u1EC7t k\xEA c\xE1c \u1EA3nh \u0111\xE3 t\u1EA1o`);
6723
+ console.log(` ${chalk12.cyan("info")} Xem th\xF4ng tin \u1EA3nh`);
6724
+ console.log(` ${chalk12.cyan("delete")} X\xF3a \u1EA3nh`);
7126
6725
  console.log();
7127
- console.log(chalk11.bold("V\xED d\u1EE5:"));
7128
- console.log(chalk11.dim(' $ jai1 image gen "a cute cat"'));
7129
- console.log(chalk11.dim(" $ jai1 image list"));
7130
- console.log(chalk11.dim(" $ jai1 image info <image-id>"));
6726
+ console.log(chalk12.bold("V\xED d\u1EE5:"));
6727
+ console.log(chalk12.dim(' $ jai1 image gen "a cute cat"'));
6728
+ console.log(chalk12.dim(" $ jai1 image list"));
6729
+ console.log(chalk12.dim(" $ jai1 image info <image-id>"));
7131
6730
  console.log();
7132
- console.log(chalk11.dim('Ch\u1EA1y "jai1 image <l\u1EC7nh> --help" \u0111\u1EC3 xem chi ti\u1EBFt'));
6731
+ console.log(chalk12.dim('Ch\u1EA1y "jai1 image <l\u1EC7nh> --help" \u0111\u1EC3 xem chi ti\u1EBFt'));
7133
6732
  }
7134
6733
  function createImageCommand() {
7135
6734
  const cmd = new Command22("image").description("Image generation commands (Coming Soon)").action(() => {
@@ -7630,11 +7229,11 @@ async function confirmSubmit(summary, jsonMode) {
7630
7229
 
7631
7230
  // src/commands/errors/index.ts
7632
7231
  import { Command as Command28 } from "commander";
7633
- import chalk13 from "chalk";
7232
+ import chalk14 from "chalk";
7634
7233
 
7635
7234
  // src/commands/errors/list.ts
7636
7235
  import { Command as Command25 } from "commander";
7637
- import chalk12 from "chalk";
7236
+ import chalk13 from "chalk";
7638
7237
  import Table3 from "cli-table3";
7639
7238
  function createErrorsListSubcommand() {
7640
7239
  return new Command25("list").description("Danh s\xE1ch error logs").option("--json", "Output JSON format").action(async (options) => {
@@ -7671,7 +7270,7 @@ function createErrorsListSubcommand() {
7671
7270
  });
7672
7271
  for (const log of logs) {
7673
7272
  table.push([
7674
- chalk12.cyan(log.id),
7273
+ chalk13.cyan(log.id),
7675
7274
  log.timestamp || "-",
7676
7275
  log.command || "-",
7677
7276
  log.message || "-"
@@ -7750,19 +7349,19 @@ function createErrorsClearSubcommand() {
7750
7349
 
7751
7350
  // src/commands/errors/index.ts
7752
7351
  function showErrorsHelp() {
7753
- console.log(chalk13.bold.cyan("\u{1F9FE} jai1 errors") + chalk13.dim(" - Qu\u1EA3n l\xFD error logs c\u1EE5c b\u1ED9"));
7352
+ console.log(chalk14.bold.cyan("\u{1F9FE} jai1 errors") + chalk14.dim(" - Qu\u1EA3n l\xFD error logs c\u1EE5c b\u1ED9"));
7754
7353
  console.log();
7755
- console.log(chalk13.bold("C\xE1c l\u1EC7nh:"));
7756
- console.log(` ${chalk13.cyan("list")} Danh s\xE1ch error logs`);
7757
- console.log(` ${chalk13.cyan("show")} Xem chi ti\u1EBFt error log`);
7758
- console.log(` ${chalk13.cyan("clear")} Xo\xE1 error logs`);
7354
+ console.log(chalk14.bold("C\xE1c l\u1EC7nh:"));
7355
+ console.log(` ${chalk14.cyan("list")} Danh s\xE1ch error logs`);
7356
+ console.log(` ${chalk14.cyan("show")} Xem chi ti\u1EBFt error log`);
7357
+ console.log(` ${chalk14.cyan("clear")} Xo\xE1 error logs`);
7759
7358
  console.log();
7760
- console.log(chalk13.bold("V\xED d\u1EE5:"));
7761
- console.log(chalk13.dim(" $ jai1 errors list"));
7762
- console.log(chalk13.dim(" $ jai1 errors show <id>"));
7763
- console.log(chalk13.dim(" $ jai1 errors clear --all"));
7359
+ console.log(chalk14.bold("V\xED d\u1EE5:"));
7360
+ console.log(chalk14.dim(" $ jai1 errors list"));
7361
+ console.log(chalk14.dim(" $ jai1 errors show <id>"));
7362
+ console.log(chalk14.dim(" $ jai1 errors clear --all"));
7764
7363
  console.log();
7765
- console.log(chalk13.dim('Ch\u1EA1y "jai1 errors <l\u1EC7nh> --help" \u0111\u1EC3 xem chi ti\u1EBFt'));
7364
+ console.log(chalk14.dim('Ch\u1EA1y "jai1 errors <l\u1EC7nh> --help" \u0111\u1EC3 xem chi ti\u1EBFt'));
7766
7365
  }
7767
7366
  function createErrorsCommand() {
7768
7367
  const errorsCommand = new Command28("errors").description("Manage local error logs").action(() => {
@@ -7776,7 +7375,7 @@ function createErrorsCommand() {
7776
7375
 
7777
7376
  // src/commands/utils/index.ts
7778
7377
  import { Command as Command42 } from "commander";
7779
- import chalk14 from "chalk";
7378
+ import chalk15 from "chalk";
7780
7379
 
7781
7380
  // src/commands/utils/password.ts
7782
7381
  import { Command as Command29 } from "commander";
@@ -8698,28 +8297,28 @@ Examples:
8698
8297
  }
8699
8298
 
8700
8299
  // src/commands/utils/interactive.ts
8701
- import React31 from "react";
8702
- import { render as render5 } from "ink";
8300
+ import React25 from "react";
8301
+ import { render as render4 } from "ink";
8703
8302
 
8704
8303
  // src/ui/utils/UtilsApp.tsx
8705
- import React30, { useState as useState23 } from "react";
8706
- import { Box as Box25, Text as Text26, useInput as useInput21, useApp as useApp5 } from "ink";
8304
+ import React24, { useState as useState18 } from "react";
8305
+ import { Box as Box20, Text as Text21, useInput as useInput16, useApp as useApp4 } from "ink";
8707
8306
 
8708
8307
  // src/ui/utils/views/PasswordView.tsx
8709
- import React19, { useState as useState12 } from "react";
8710
- import { Box as Box14, Text as Text15, useInput as useInput10 } from "ink";
8308
+ import React13, { useState as useState7 } from "react";
8309
+ import { Box as Box9, Text as Text10, useInput as useInput5 } from "ink";
8711
8310
  import TextInput4 from "ink-text-input";
8712
8311
  var PasswordView = () => {
8713
- const [length, setLength] = useState12("16");
8714
- const [count, setCount] = useState12("1");
8715
- const [passwords, setPasswords] = useState12([]);
8716
- const [focusedField, setFocusedField] = useState12("length");
8717
- const [copiedIndex, setCopiedIndex] = useState12(null);
8312
+ const [length, setLength] = useState7("16");
8313
+ const [count, setCount] = useState7("1");
8314
+ const [passwords, setPasswords] = useState7([]);
8315
+ const [focusedField, setFocusedField] = useState7("length");
8316
+ const [copiedIndex, setCopiedIndex] = useState7(null);
8718
8317
  const service = new UtilsService();
8719
- React19.useEffect(() => {
8318
+ React13.useEffect(() => {
8720
8319
  handleGenerate();
8721
8320
  }, []);
8722
- useInput10((input5, key) => {
8321
+ useInput5((input5, key) => {
8723
8322
  if (key.tab) {
8724
8323
  if (focusedField === "length") setFocusedField("count");
8725
8324
  else if (focusedField === "count") setFocusedField("generate");
@@ -8757,8 +8356,8 @@ var PasswordView = () => {
8757
8356
  } catch (error) {
8758
8357
  }
8759
8358
  };
8760
- return /* @__PURE__ */ React19.createElement(Box14, { flexDirection: "column" }, /* @__PURE__ */ React19.createElement(Box14, { marginBottom: 1 }, /* @__PURE__ */ React19.createElement(Text15, { bold: true, color: "cyan" }, "\u{1F510} Password Generator")), /* @__PURE__ */ React19.createElement(
8761
- Box14,
8359
+ return /* @__PURE__ */ React13.createElement(Box9, { flexDirection: "column" }, /* @__PURE__ */ React13.createElement(Box9, { marginBottom: 1 }, /* @__PURE__ */ React13.createElement(Text10, { bold: true, color: "cyan" }, "\u{1F510} Password Generator")), /* @__PURE__ */ React13.createElement(
8360
+ Box9,
8762
8361
  {
8763
8362
  flexDirection: "column",
8764
8363
  borderStyle: "single",
@@ -8767,11 +8366,11 @@ var PasswordView = () => {
8767
8366
  paddingY: 1,
8768
8367
  marginBottom: 1
8769
8368
  },
8770
- /* @__PURE__ */ React19.createElement(Text15, { bold: true, color: "yellow", marginBottom: 1 }, "Options:"),
8771
- /* @__PURE__ */ React19.createElement(Box14, { marginBottom: 1 }, /* @__PURE__ */ React19.createElement(Box14, { width: 20 }, /* @__PURE__ */ React19.createElement(Text15, { color: focusedField === "length" ? "green" : void 0 }, focusedField === "length" ? "\u25B6 " : " ", "Length:")), /* @__PURE__ */ React19.createElement(Box14, { width: 10 }, focusedField === "length" ? /* @__PURE__ */ React19.createElement(TextInput4, { value: length, onChange: setLength }) : /* @__PURE__ */ React19.createElement(Text15, null, length)), /* @__PURE__ */ React19.createElement(Text15, { dimColor: true }, "(characters)")),
8772
- /* @__PURE__ */ React19.createElement(Box14, { marginBottom: 1 }, /* @__PURE__ */ React19.createElement(Box14, { width: 20 }, /* @__PURE__ */ React19.createElement(Text15, { color: focusedField === "count" ? "green" : void 0 }, focusedField === "count" ? "\u25B6 " : " ", "Count:")), /* @__PURE__ */ React19.createElement(Box14, { width: 10 }, focusedField === "count" ? /* @__PURE__ */ React19.createElement(TextInput4, { value: count, onChange: setCount }) : /* @__PURE__ */ React19.createElement(Text15, null, count)), /* @__PURE__ */ React19.createElement(Text15, { dimColor: true }, "(passwords to generate)")),
8773
- /* @__PURE__ */ React19.createElement(Box14, { marginTop: 1 }, /* @__PURE__ */ React19.createElement(
8774
- Text15,
8369
+ /* @__PURE__ */ React13.createElement(Text10, { bold: true, color: "yellow", marginBottom: 1 }, "Options:"),
8370
+ /* @__PURE__ */ React13.createElement(Box9, { marginBottom: 1 }, /* @__PURE__ */ React13.createElement(Box9, { width: 20 }, /* @__PURE__ */ React13.createElement(Text10, { color: focusedField === "length" ? "green" : void 0 }, focusedField === "length" ? "\u25B6 " : " ", "Length:")), /* @__PURE__ */ React13.createElement(Box9, { width: 10 }, focusedField === "length" ? /* @__PURE__ */ React13.createElement(TextInput4, { value: length, onChange: setLength }) : /* @__PURE__ */ React13.createElement(Text10, null, length)), /* @__PURE__ */ React13.createElement(Text10, { dimColor: true }, "(characters)")),
8371
+ /* @__PURE__ */ React13.createElement(Box9, { marginBottom: 1 }, /* @__PURE__ */ React13.createElement(Box9, { width: 20 }, /* @__PURE__ */ React13.createElement(Text10, { color: focusedField === "count" ? "green" : void 0 }, focusedField === "count" ? "\u25B6 " : " ", "Count:")), /* @__PURE__ */ React13.createElement(Box9, { width: 10 }, focusedField === "count" ? /* @__PURE__ */ React13.createElement(TextInput4, { value: count, onChange: setCount }) : /* @__PURE__ */ React13.createElement(Text10, null, count)), /* @__PURE__ */ React13.createElement(Text10, { dimColor: true }, "(passwords to generate)")),
8372
+ /* @__PURE__ */ React13.createElement(Box9, { marginTop: 1 }, /* @__PURE__ */ React13.createElement(
8373
+ Text10,
8775
8374
  {
8776
8375
  bold: true,
8777
8376
  backgroundColor: focusedField === "generate" ? "green" : void 0,
@@ -8780,8 +8379,8 @@ var PasswordView = () => {
8780
8379
  focusedField === "generate" ? "\u25B6 " : " ",
8781
8380
  "[ Generate Passwords ]"
8782
8381
  ))
8783
- ), passwords.length > 0 && /* @__PURE__ */ React19.createElement(
8784
- Box14,
8382
+ ), passwords.length > 0 && /* @__PURE__ */ React13.createElement(
8383
+ Box9,
8785
8384
  {
8786
8385
  flexDirection: "column",
8787
8386
  borderStyle: "single",
@@ -8789,27 +8388,27 @@ var PasswordView = () => {
8789
8388
  paddingX: 2,
8790
8389
  paddingY: 1
8791
8390
  },
8792
- /* @__PURE__ */ React19.createElement(Text15, { bold: true, color: "green", marginBottom: 1 }, "\u2713 Generated Passwords:"),
8793
- passwords.map((password, index) => /* @__PURE__ */ React19.createElement(Box14, { key: index, marginBottom: 0 }, /* @__PURE__ */ React19.createElement(Box14, { width: 4 }, /* @__PURE__ */ React19.createElement(Text15, { dimColor: true }, index + 1, ".")), /* @__PURE__ */ React19.createElement(Box14, { flexGrow: 1 }, /* @__PURE__ */ React19.createElement(Text15, null, password)), copiedIndex === index && /* @__PURE__ */ React19.createElement(Text15, { color: "green" }, " \u2713 Copied!")))
8794
- ), /* @__PURE__ */ React19.createElement(Box14, { marginTop: 1, borderStyle: "single", borderColor: "gray", paddingX: 2 }, /* @__PURE__ */ React19.createElement(Text15, { dimColor: true }, "Tab: Next field | Enter: Generate | C: Copy | Esc: Back")));
8391
+ /* @__PURE__ */ React13.createElement(Text10, { bold: true, color: "green", marginBottom: 1 }, "\u2713 Generated Passwords:"),
8392
+ passwords.map((password, index) => /* @__PURE__ */ React13.createElement(Box9, { key: index, marginBottom: 0 }, /* @__PURE__ */ React13.createElement(Box9, { width: 4 }, /* @__PURE__ */ React13.createElement(Text10, { dimColor: true }, index + 1, ".")), /* @__PURE__ */ React13.createElement(Box9, { flexGrow: 1 }, /* @__PURE__ */ React13.createElement(Text10, null, password)), copiedIndex === index && /* @__PURE__ */ React13.createElement(Text10, { color: "green" }, " \u2713 Copied!")))
8393
+ ), /* @__PURE__ */ React13.createElement(Box9, { marginTop: 1, borderStyle: "single", borderColor: "gray", paddingX: 2 }, /* @__PURE__ */ React13.createElement(Text10, { dimColor: true }, "Tab: Next field | Enter: Generate | C: Copy | Esc: Back")));
8795
8394
  };
8796
8395
 
8797
8396
  // src/ui/utils/views/UuidView.tsx
8798
- import React20, { useState as useState13 } from "react";
8799
- import { Box as Box15, Text as Text16, useInput as useInput11 } from "ink";
8397
+ import React14, { useState as useState8 } from "react";
8398
+ import { Box as Box10, Text as Text11, useInput as useInput6 } from "ink";
8800
8399
  import TextInput5 from "ink-text-input";
8801
8400
  var UuidView = () => {
8802
- const [count, setCount] = useState13("1");
8803
- const [uppercase, setUppercase] = useState13(false);
8804
- const [noHyphens, setNoHyphens] = useState13(false);
8805
- const [uuids, setUuids] = useState13([]);
8806
- const [focusedField, setFocusedField] = useState13("count");
8807
- const [copiedIndex, setCopiedIndex] = useState13(null);
8401
+ const [count, setCount] = useState8("1");
8402
+ const [uppercase, setUppercase] = useState8(false);
8403
+ const [noHyphens, setNoHyphens] = useState8(false);
8404
+ const [uuids, setUuids] = useState8([]);
8405
+ const [focusedField, setFocusedField] = useState8("count");
8406
+ const [copiedIndex, setCopiedIndex] = useState8(null);
8808
8407
  const service = new UtilsService();
8809
- React20.useEffect(() => {
8408
+ React14.useEffect(() => {
8810
8409
  handleGenerate();
8811
8410
  }, []);
8812
- useInput11((input5, key) => {
8411
+ useInput6((input5, key) => {
8813
8412
  if (key.tab) {
8814
8413
  const fields = ["count", "uppercase", "hyphens", "generate"];
8815
8414
  const currentIndex = fields.indexOf(focusedField);
@@ -8844,8 +8443,8 @@ var UuidView = () => {
8844
8443
  } catch (error) {
8845
8444
  }
8846
8445
  };
8847
- return /* @__PURE__ */ React20.createElement(Box15, { flexDirection: "column" }, /* @__PURE__ */ React20.createElement(Box15, { marginBottom: 1 }, /* @__PURE__ */ React20.createElement(Text16, { bold: true, color: "cyan" }, "\u{1F194} UUID Generator")), /* @__PURE__ */ React20.createElement(
8848
- Box15,
8446
+ return /* @__PURE__ */ React14.createElement(Box10, { flexDirection: "column" }, /* @__PURE__ */ React14.createElement(Box10, { marginBottom: 1 }, /* @__PURE__ */ React14.createElement(Text11, { bold: true, color: "cyan" }, "\u{1F194} UUID Generator")), /* @__PURE__ */ React14.createElement(
8447
+ Box10,
8849
8448
  {
8850
8449
  flexDirection: "column",
8851
8450
  borderStyle: "single",
@@ -8854,12 +8453,12 @@ var UuidView = () => {
8854
8453
  paddingY: 1,
8855
8454
  marginBottom: 1
8856
8455
  },
8857
- /* @__PURE__ */ React20.createElement(Text16, { bold: true, color: "yellow", marginBottom: 1 }, "Options:"),
8858
- /* @__PURE__ */ React20.createElement(Box15, { marginBottom: 1 }, /* @__PURE__ */ React20.createElement(Box15, { width: 20 }, /* @__PURE__ */ React20.createElement(Text16, { color: focusedField === "count" ? "green" : void 0 }, focusedField === "count" ? "\u25B6 " : " ", "Count:")), /* @__PURE__ */ React20.createElement(Box15, { width: 10 }, focusedField === "count" ? /* @__PURE__ */ React20.createElement(TextInput5, { value: count, onChange: setCount }) : /* @__PURE__ */ React20.createElement(Text16, null, count))),
8859
- /* @__PURE__ */ React20.createElement(Box15, { marginBottom: 1 }, /* @__PURE__ */ React20.createElement(Text16, { color: focusedField === "uppercase" ? "green" : void 0 }, focusedField === "uppercase" ? "\u25B6 " : " ", "[", uppercase ? "\u2713" : " ", "] Uppercase")),
8860
- /* @__PURE__ */ React20.createElement(Box15, { marginBottom: 1 }, /* @__PURE__ */ React20.createElement(Text16, { color: focusedField === "hyphens" ? "green" : void 0 }, focusedField === "hyphens" ? "\u25B6 " : " ", "[", noHyphens ? "\u2713" : " ", "] No Hyphens")),
8861
- /* @__PURE__ */ React20.createElement(Box15, { marginTop: 1 }, /* @__PURE__ */ React20.createElement(
8862
- Text16,
8456
+ /* @__PURE__ */ React14.createElement(Text11, { bold: true, color: "yellow", marginBottom: 1 }, "Options:"),
8457
+ /* @__PURE__ */ React14.createElement(Box10, { marginBottom: 1 }, /* @__PURE__ */ React14.createElement(Box10, { width: 20 }, /* @__PURE__ */ React14.createElement(Text11, { color: focusedField === "count" ? "green" : void 0 }, focusedField === "count" ? "\u25B6 " : " ", "Count:")), /* @__PURE__ */ React14.createElement(Box10, { width: 10 }, focusedField === "count" ? /* @__PURE__ */ React14.createElement(TextInput5, { value: count, onChange: setCount }) : /* @__PURE__ */ React14.createElement(Text11, null, count))),
8458
+ /* @__PURE__ */ React14.createElement(Box10, { marginBottom: 1 }, /* @__PURE__ */ React14.createElement(Text11, { color: focusedField === "uppercase" ? "green" : void 0 }, focusedField === "uppercase" ? "\u25B6 " : " ", "[", uppercase ? "\u2713" : " ", "] Uppercase")),
8459
+ /* @__PURE__ */ React14.createElement(Box10, { marginBottom: 1 }, /* @__PURE__ */ React14.createElement(Text11, { color: focusedField === "hyphens" ? "green" : void 0 }, focusedField === "hyphens" ? "\u25B6 " : " ", "[", noHyphens ? "\u2713" : " ", "] No Hyphens")),
8460
+ /* @__PURE__ */ React14.createElement(Box10, { marginTop: 1 }, /* @__PURE__ */ React14.createElement(
8461
+ Text11,
8863
8462
  {
8864
8463
  bold: true,
8865
8464
  backgroundColor: focusedField === "generate" ? "green" : void 0,
@@ -8868,8 +8467,8 @@ var UuidView = () => {
8868
8467
  focusedField === "generate" ? "\u25B6 " : " ",
8869
8468
  "[ Generate UUIDs ]"
8870
8469
  ))
8871
- ), uuids.length > 0 && /* @__PURE__ */ React20.createElement(
8872
- Box15,
8470
+ ), uuids.length > 0 && /* @__PURE__ */ React14.createElement(
8471
+ Box10,
8873
8472
  {
8874
8473
  flexDirection: "column",
8875
8474
  borderStyle: "single",
@@ -8877,27 +8476,27 @@ var UuidView = () => {
8877
8476
  paddingX: 2,
8878
8477
  paddingY: 1
8879
8478
  },
8880
- /* @__PURE__ */ React20.createElement(Text16, { bold: true, color: "green", marginBottom: 1 }, "\u2713 Generated UUIDs:"),
8881
- uuids.map((uuid, index) => /* @__PURE__ */ React20.createElement(Box15, { key: index, marginBottom: 0 }, /* @__PURE__ */ React20.createElement(Box15, { width: 4 }, /* @__PURE__ */ React20.createElement(Text16, { dimColor: true }, index + 1, ".")), /* @__PURE__ */ React20.createElement(Box15, { flexGrow: 1 }, /* @__PURE__ */ React20.createElement(Text16, null, uuid)), copiedIndex === index && /* @__PURE__ */ React20.createElement(Text16, { color: "green" }, " \u2713 Copied!")))
8882
- ), /* @__PURE__ */ React20.createElement(Box15, { marginTop: 1, borderStyle: "single", borderColor: "gray", paddingX: 2 }, /* @__PURE__ */ React20.createElement(Text16, { dimColor: true }, "Tab: Next | Enter: Toggle/Generate | C: Copy | Esc: Back")));
8479
+ /* @__PURE__ */ React14.createElement(Text11, { bold: true, color: "green", marginBottom: 1 }, "\u2713 Generated UUIDs:"),
8480
+ uuids.map((uuid, index) => /* @__PURE__ */ React14.createElement(Box10, { key: index, marginBottom: 0 }, /* @__PURE__ */ React14.createElement(Box10, { width: 4 }, /* @__PURE__ */ React14.createElement(Text11, { dimColor: true }, index + 1, ".")), /* @__PURE__ */ React14.createElement(Box10, { flexGrow: 1 }, /* @__PURE__ */ React14.createElement(Text11, null, uuid)), copiedIndex === index && /* @__PURE__ */ React14.createElement(Text11, { color: "green" }, " \u2713 Copied!")))
8481
+ ), /* @__PURE__ */ React14.createElement(Box10, { marginTop: 1, borderStyle: "single", borderColor: "gray", paddingX: 2 }, /* @__PURE__ */ React14.createElement(Text11, { dimColor: true }, "Tab: Next | Enter: Toggle/Generate | C: Copy | Esc: Back")));
8883
8482
  };
8884
8483
 
8885
8484
  // src/ui/utils/views/HashView.tsx
8886
- import React21, { useState as useState14 } from "react";
8887
- import { Box as Box16, Text as Text17, useInput as useInput12 } from "ink";
8485
+ import React15, { useState as useState9 } from "react";
8486
+ import { Box as Box11, Text as Text12, useInput as useInput7 } from "ink";
8888
8487
  import TextInput6 from "ink-text-input";
8889
8488
  var ALGORITHMS = ["sha256", "sha512", "sha1", "md5", "bcrypt"];
8890
8489
  var HashView = () => {
8891
- const [text, setText] = useState14("hello world");
8892
- const [algorithm, setAlgorithm] = useState14("sha256");
8893
- const [hash, setHash] = useState14("");
8894
- const [focusedField, setFocusedField] = useState14("text");
8895
- const [copied, setCopied] = useState14(false);
8490
+ const [text, setText] = useState9("hello world");
8491
+ const [algorithm, setAlgorithm] = useState9("sha256");
8492
+ const [hash, setHash] = useState9("");
8493
+ const [focusedField, setFocusedField] = useState9("text");
8494
+ const [copied, setCopied] = useState9(false);
8896
8495
  const service = new UtilsService();
8897
- React21.useEffect(() => {
8496
+ React15.useEffect(() => {
8898
8497
  handleGenerate();
8899
8498
  }, []);
8900
- useInput12((input5, key) => {
8499
+ useInput7((input5, key) => {
8901
8500
  if (key.tab) {
8902
8501
  const fields = ["text", "algorithm", "generate"];
8903
8502
  const currentIndex = fields.indexOf(focusedField);
@@ -8934,8 +8533,8 @@ var HashView = () => {
8934
8533
  } catch (error) {
8935
8534
  }
8936
8535
  };
8937
- return /* @__PURE__ */ React21.createElement(Box16, { flexDirection: "column" }, /* @__PURE__ */ React21.createElement(Box16, { marginBottom: 1 }, /* @__PURE__ */ React21.createElement(Text17, { bold: true, color: "cyan" }, "\u{1F512} Hash Generator")), /* @__PURE__ */ React21.createElement(
8938
- Box16,
8536
+ return /* @__PURE__ */ React15.createElement(Box11, { flexDirection: "column" }, /* @__PURE__ */ React15.createElement(Box11, { marginBottom: 1 }, /* @__PURE__ */ React15.createElement(Text12, { bold: true, color: "cyan" }, "\u{1F512} Hash Generator")), /* @__PURE__ */ React15.createElement(
8537
+ Box11,
8939
8538
  {
8940
8539
  flexDirection: "column",
8941
8540
  borderStyle: "single",
@@ -8944,11 +8543,11 @@ var HashView = () => {
8944
8543
  paddingY: 1,
8945
8544
  marginBottom: 1
8946
8545
  },
8947
- /* @__PURE__ */ React21.createElement(Text17, { bold: true, color: "yellow", marginBottom: 1 }, "Options:"),
8948
- /* @__PURE__ */ React21.createElement(Box16, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React21.createElement(Box16, { marginBottom: 0 }, /* @__PURE__ */ React21.createElement(Text17, { color: focusedField === "text" ? "green" : void 0 }, focusedField === "text" ? "\u25B6 " : " ", "Text to hash:")), /* @__PURE__ */ React21.createElement(Box16, { marginLeft: 2, width: 60 }, focusedField === "text" ? /* @__PURE__ */ React21.createElement(TextInput6, { value: text, onChange: setText, placeholder: "Enter text..." }) : /* @__PURE__ */ React21.createElement(Text17, { dimColor: !text }, text || "(empty)"))),
8949
- /* @__PURE__ */ React21.createElement(Box16, { marginBottom: 1 }, /* @__PURE__ */ React21.createElement(Box16, { width: 20 }, /* @__PURE__ */ React21.createElement(Text17, { color: focusedField === "algorithm" ? "green" : void 0 }, focusedField === "algorithm" ? "\u25B6 " : " ", "Algorithm:")), /* @__PURE__ */ React21.createElement(Text17, { bold: true, color: focusedField === "algorithm" ? "yellow" : void 0 }, algorithm.toUpperCase()), focusedField === "algorithm" && /* @__PURE__ */ React21.createElement(Text17, { dimColor: true }, " (\u2190 \u2192 to change)")),
8950
- /* @__PURE__ */ React21.createElement(Box16, { marginTop: 1 }, /* @__PURE__ */ React21.createElement(
8951
- Text17,
8546
+ /* @__PURE__ */ React15.createElement(Text12, { bold: true, color: "yellow", marginBottom: 1 }, "Options:"),
8547
+ /* @__PURE__ */ React15.createElement(Box11, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React15.createElement(Box11, { marginBottom: 0 }, /* @__PURE__ */ React15.createElement(Text12, { color: focusedField === "text" ? "green" : void 0 }, focusedField === "text" ? "\u25B6 " : " ", "Text to hash:")), /* @__PURE__ */ React15.createElement(Box11, { marginLeft: 2, width: 60 }, focusedField === "text" ? /* @__PURE__ */ React15.createElement(TextInput6, { value: text, onChange: setText, placeholder: "Enter text..." }) : /* @__PURE__ */ React15.createElement(Text12, { dimColor: !text }, text || "(empty)"))),
8548
+ /* @__PURE__ */ React15.createElement(Box11, { marginBottom: 1 }, /* @__PURE__ */ React15.createElement(Box11, { width: 20 }, /* @__PURE__ */ React15.createElement(Text12, { color: focusedField === "algorithm" ? "green" : void 0 }, focusedField === "algorithm" ? "\u25B6 " : " ", "Algorithm:")), /* @__PURE__ */ React15.createElement(Text12, { bold: true, color: focusedField === "algorithm" ? "yellow" : void 0 }, algorithm.toUpperCase()), focusedField === "algorithm" && /* @__PURE__ */ React15.createElement(Text12, { dimColor: true }, " (\u2190 \u2192 to change)")),
8549
+ /* @__PURE__ */ React15.createElement(Box11, { marginTop: 1 }, /* @__PURE__ */ React15.createElement(
8550
+ Text12,
8952
8551
  {
8953
8552
  bold: true,
8954
8553
  backgroundColor: focusedField === "generate" ? "green" : void 0,
@@ -8957,8 +8556,8 @@ var HashView = () => {
8957
8556
  focusedField === "generate" ? "\u25B6 " : " ",
8958
8557
  "[ Generate Hash ]"
8959
8558
  ))
8960
- ), hash && /* @__PURE__ */ React21.createElement(
8961
- Box16,
8559
+ ), hash && /* @__PURE__ */ React15.createElement(
8560
+ Box11,
8962
8561
  {
8963
8562
  flexDirection: "column",
8964
8563
  borderStyle: "single",
@@ -8966,25 +8565,25 @@ var HashView = () => {
8966
8565
  paddingX: 2,
8967
8566
  paddingY: 1
8968
8567
  },
8969
- /* @__PURE__ */ React21.createElement(Box16, { marginBottom: 1 }, /* @__PURE__ */ React21.createElement(Text17, { bold: true, color: "green" }, "\u2713 Hash Result:"), copied && /* @__PURE__ */ React21.createElement(Box16, { marginLeft: 2 }, /* @__PURE__ */ React21.createElement(Text17, { color: "green" }, "\u2713 Copied to clipboard!"))),
8970
- /* @__PURE__ */ React21.createElement(Box16, { flexDirection: "column" }, /* @__PURE__ */ React21.createElement(Text17, { dimColor: true }, "Algorithm: ", algorithm.toUpperCase()), /* @__PURE__ */ React21.createElement(Box16, { marginTop: 1 }, /* @__PURE__ */ React21.createElement(Text17, { wrap: "wrap" }, hash)))
8971
- ), /* @__PURE__ */ React21.createElement(Box16, { marginTop: 1, borderStyle: "single", borderColor: "gray", paddingX: 2 }, /* @__PURE__ */ React21.createElement(Text17, { dimColor: true }, "Tab: Next | \u2190/\u2192: Change algorithm | Enter: Generate | C: Copy | Esc: Back")));
8568
+ /* @__PURE__ */ React15.createElement(Box11, { marginBottom: 1 }, /* @__PURE__ */ React15.createElement(Text12, { bold: true, color: "green" }, "\u2713 Hash Result:"), copied && /* @__PURE__ */ React15.createElement(Box11, { marginLeft: 2 }, /* @__PURE__ */ React15.createElement(Text12, { color: "green" }, "\u2713 Copied to clipboard!"))),
8569
+ /* @__PURE__ */ React15.createElement(Box11, { flexDirection: "column" }, /* @__PURE__ */ React15.createElement(Text12, { dimColor: true }, "Algorithm: ", algorithm.toUpperCase()), /* @__PURE__ */ React15.createElement(Box11, { marginTop: 1 }, /* @__PURE__ */ React15.createElement(Text12, { wrap: "wrap" }, hash)))
8570
+ ), /* @__PURE__ */ React15.createElement(Box11, { marginTop: 1, borderStyle: "single", borderColor: "gray", paddingX: 2 }, /* @__PURE__ */ React15.createElement(Text12, { dimColor: true }, "Tab: Next | \u2190/\u2192: Change algorithm | Enter: Generate | C: Copy | Esc: Back")));
8972
8571
  };
8973
8572
 
8974
8573
  // src/ui/utils/views/Base64View.tsx
8975
- import React22, { useState as useState15 } from "react";
8976
- import { Box as Box17, Text as Text18, useInput as useInput13 } from "ink";
8574
+ import React16, { useState as useState10 } from "react";
8575
+ import { Box as Box12, Text as Text13, useInput as useInput8 } from "ink";
8977
8576
  import TextInput7 from "ink-text-input";
8978
8577
  var Base64View = () => {
8979
- const [input5, setInput] = useState15("");
8980
- const [mode, setMode] = useState15("encode");
8981
- const [urlSafe, setUrlSafe] = useState15(false);
8982
- const [result, setResult] = useState15("");
8983
- const [error, setError] = useState15("");
8984
- const [focusedField, setFocusedField] = useState15("input");
8985
- const [copied, setCopied] = useState15(false);
8578
+ const [input5, setInput] = useState10("");
8579
+ const [mode, setMode] = useState10("encode");
8580
+ const [urlSafe, setUrlSafe] = useState10(false);
8581
+ const [result, setResult] = useState10("");
8582
+ const [error, setError] = useState10("");
8583
+ const [focusedField, setFocusedField] = useState10("input");
8584
+ const [copied, setCopied] = useState10(false);
8986
8585
  const service = new UtilsService();
8987
- useInput13((input6, key) => {
8586
+ useInput8((input6, key) => {
8988
8587
  if (key.tab) {
8989
8588
  const fields = ["input", "mode", "urlsafe", "convert"];
8990
8589
  const currentIndex = fields.indexOf(focusedField);
@@ -9032,8 +8631,8 @@ var Base64View = () => {
9032
8631
  } catch (error2) {
9033
8632
  }
9034
8633
  };
9035
- return /* @__PURE__ */ React22.createElement(Box17, { flexDirection: "column" }, /* @__PURE__ */ React22.createElement(Box17, { marginBottom: 1 }, /* @__PURE__ */ React22.createElement(Text18, { bold: true, color: "cyan" }, "\u{1F4DD} Base64 Encoder/Decoder")), /* @__PURE__ */ React22.createElement(
9036
- Box17,
8634
+ return /* @__PURE__ */ React16.createElement(Box12, { flexDirection: "column" }, /* @__PURE__ */ React16.createElement(Box12, { marginBottom: 1 }, /* @__PURE__ */ React16.createElement(Text13, { bold: true, color: "cyan" }, "\u{1F4DD} Base64 Encoder/Decoder")), /* @__PURE__ */ React16.createElement(
8635
+ Box12,
9037
8636
  {
9038
8637
  flexDirection: "column",
9039
8638
  borderStyle: "single",
@@ -9042,12 +8641,12 @@ var Base64View = () => {
9042
8641
  paddingY: 1,
9043
8642
  marginBottom: 1
9044
8643
  },
9045
- /* @__PURE__ */ React22.createElement(Text18, { bold: true, color: "yellow", marginBottom: 1 }, "Options:"),
9046
- /* @__PURE__ */ React22.createElement(Box17, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React22.createElement(Box17, { marginBottom: 0 }, /* @__PURE__ */ React22.createElement(Text18, { color: focusedField === "input" ? "green" : void 0 }, focusedField === "input" ? "\u25B6 " : " ", "Input text:")), /* @__PURE__ */ React22.createElement(Box17, { marginLeft: 2, width: 60 }, focusedField === "input" ? /* @__PURE__ */ React22.createElement(TextInput7, { value: input5, onChange: setInput, placeholder: "Enter text..." }) : /* @__PURE__ */ React22.createElement(Text18, { dimColor: !input5 }, input5 || "(empty)"))),
9047
- /* @__PURE__ */ React22.createElement(Box17, { marginBottom: 1 }, /* @__PURE__ */ React22.createElement(Box17, { width: 20 }, /* @__PURE__ */ React22.createElement(Text18, { color: focusedField === "mode" ? "green" : void 0 }, focusedField === "mode" ? "\u25B6 " : " ", "Mode:")), /* @__PURE__ */ React22.createElement(Text18, { bold: true, color: focusedField === "mode" ? "yellow" : void 0 }, mode === "encode" ? "ENCODE" : "DECODE"), focusedField === "mode" && /* @__PURE__ */ React22.createElement(Text18, { dimColor: true }, " (Enter to toggle)")),
9048
- mode === "encode" && /* @__PURE__ */ React22.createElement(Box17, { marginBottom: 1 }, /* @__PURE__ */ React22.createElement(Text18, { color: focusedField === "urlsafe" ? "green" : void 0 }, focusedField === "urlsafe" ? "\u25B6 " : " ", "[", urlSafe ? "\u2713" : " ", "] URL-Safe (+ \u2192 -, / \u2192 _)")),
9049
- /* @__PURE__ */ React22.createElement(Box17, { marginTop: 1 }, /* @__PURE__ */ React22.createElement(
9050
- Text18,
8644
+ /* @__PURE__ */ React16.createElement(Text13, { bold: true, color: "yellow", marginBottom: 1 }, "Options:"),
8645
+ /* @__PURE__ */ React16.createElement(Box12, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React16.createElement(Box12, { marginBottom: 0 }, /* @__PURE__ */ React16.createElement(Text13, { color: focusedField === "input" ? "green" : void 0 }, focusedField === "input" ? "\u25B6 " : " ", "Input text:")), /* @__PURE__ */ React16.createElement(Box12, { marginLeft: 2, width: 60 }, focusedField === "input" ? /* @__PURE__ */ React16.createElement(TextInput7, { value: input5, onChange: setInput, placeholder: "Enter text..." }) : /* @__PURE__ */ React16.createElement(Text13, { dimColor: !input5 }, input5 || "(empty)"))),
8646
+ /* @__PURE__ */ React16.createElement(Box12, { marginBottom: 1 }, /* @__PURE__ */ React16.createElement(Box12, { width: 20 }, /* @__PURE__ */ React16.createElement(Text13, { color: focusedField === "mode" ? "green" : void 0 }, focusedField === "mode" ? "\u25B6 " : " ", "Mode:")), /* @__PURE__ */ React16.createElement(Text13, { bold: true, color: focusedField === "mode" ? "yellow" : void 0 }, mode === "encode" ? "ENCODE" : "DECODE"), focusedField === "mode" && /* @__PURE__ */ React16.createElement(Text13, { dimColor: true }, " (Enter to toggle)")),
8647
+ mode === "encode" && /* @__PURE__ */ React16.createElement(Box12, { marginBottom: 1 }, /* @__PURE__ */ React16.createElement(Text13, { color: focusedField === "urlsafe" ? "green" : void 0 }, focusedField === "urlsafe" ? "\u25B6 " : " ", "[", urlSafe ? "\u2713" : " ", "] URL-Safe (+ \u2192 -, / \u2192 _)")),
8648
+ /* @__PURE__ */ React16.createElement(Box12, { marginTop: 1 }, /* @__PURE__ */ React16.createElement(
8649
+ Text13,
9051
8650
  {
9052
8651
  bold: true,
9053
8652
  backgroundColor: focusedField === "convert" ? "green" : void 0,
@@ -9058,8 +8657,8 @@ var Base64View = () => {
9058
8657
  mode === "encode" ? "Encode" : "Decode",
9059
8658
  " ]"
9060
8659
  ))
9061
- ), error && /* @__PURE__ */ React22.createElement(
9062
- Box17,
8660
+ ), error && /* @__PURE__ */ React16.createElement(
8661
+ Box12,
9063
8662
  {
9064
8663
  flexDirection: "column",
9065
8664
  borderStyle: "single",
@@ -9068,9 +8667,9 @@ var Base64View = () => {
9068
8667
  paddingY: 1,
9069
8668
  marginBottom: 1
9070
8669
  },
9071
- /* @__PURE__ */ React22.createElement(Text18, { color: "red" }, "\u2717 Error: ", error)
9072
- ), result && /* @__PURE__ */ React22.createElement(
9073
- Box17,
8670
+ /* @__PURE__ */ React16.createElement(Text13, { color: "red" }, "\u2717 Error: ", error)
8671
+ ), result && /* @__PURE__ */ React16.createElement(
8672
+ Box12,
9074
8673
  {
9075
8674
  flexDirection: "column",
9076
8675
  borderStyle: "single",
@@ -9078,24 +8677,24 @@ var Base64View = () => {
9078
8677
  paddingX: 2,
9079
8678
  paddingY: 1
9080
8679
  },
9081
- /* @__PURE__ */ React22.createElement(Box17, { marginBottom: 1 }, /* @__PURE__ */ React22.createElement(Text18, { bold: true, color: "green" }, "\u2713 Result:"), copied && /* @__PURE__ */ React22.createElement(Box17, { marginLeft: 2 }, /* @__PURE__ */ React22.createElement(Text18, { color: "green" }, "\u2713 Copied to clipboard!"))),
9082
- /* @__PURE__ */ React22.createElement(Box17, { flexDirection: "column" }, /* @__PURE__ */ React22.createElement(Text18, { dimColor: true }, "Mode: ", mode.toUpperCase()), /* @__PURE__ */ React22.createElement(Box17, { marginTop: 1 }, /* @__PURE__ */ React22.createElement(Text18, { wrap: "wrap" }, result)))
9083
- ), /* @__PURE__ */ React22.createElement(Box17, { marginTop: 1, borderStyle: "single", borderColor: "gray", paddingX: 2 }, /* @__PURE__ */ React22.createElement(Text18, { dimColor: true }, "Tab: Next | Enter: Toggle/Convert | C: Copy | Esc: Back")));
8680
+ /* @__PURE__ */ React16.createElement(Box12, { marginBottom: 1 }, /* @__PURE__ */ React16.createElement(Text13, { bold: true, color: "green" }, "\u2713 Result:"), copied && /* @__PURE__ */ React16.createElement(Box12, { marginLeft: 2 }, /* @__PURE__ */ React16.createElement(Text13, { color: "green" }, "\u2713 Copied to clipboard!"))),
8681
+ /* @__PURE__ */ React16.createElement(Box12, { flexDirection: "column" }, /* @__PURE__ */ React16.createElement(Text13, { dimColor: true }, "Mode: ", mode.toUpperCase()), /* @__PURE__ */ React16.createElement(Box12, { marginTop: 1 }, /* @__PURE__ */ React16.createElement(Text13, { wrap: "wrap" }, result)))
8682
+ ), /* @__PURE__ */ React16.createElement(Box12, { marginTop: 1, borderStyle: "single", borderColor: "gray", paddingX: 2 }, /* @__PURE__ */ React16.createElement(Text13, { dimColor: true }, "Tab: Next | Enter: Toggle/Convert | C: Copy | Esc: Back")));
9084
8683
  };
9085
8684
 
9086
8685
  // src/ui/utils/views/UrlView.tsx
9087
- import React23, { useState as useState16 } from "react";
9088
- import { Box as Box18, Text as Text19, useInput as useInput14 } from "ink";
8686
+ import React17, { useState as useState11 } from "react";
8687
+ import { Box as Box13, Text as Text14, useInput as useInput9 } from "ink";
9089
8688
  import TextInput8 from "ink-text-input";
9090
8689
  var UrlView = () => {
9091
- const [input5, setInput] = useState16("");
9092
- const [mode, setMode] = useState16("encode");
9093
- const [fullUrl, setFullUrl] = useState16(false);
9094
- const [result, setResult] = useState16("");
9095
- const [focusedField, setFocusedField] = useState16("input");
9096
- const [copied, setCopied] = useState16(false);
8690
+ const [input5, setInput] = useState11("");
8691
+ const [mode, setMode] = useState11("encode");
8692
+ const [fullUrl, setFullUrl] = useState11(false);
8693
+ const [result, setResult] = useState11("");
8694
+ const [focusedField, setFocusedField] = useState11("input");
8695
+ const [copied, setCopied] = useState11(false);
9097
8696
  const service = new UtilsService();
9098
- useInput14((input6, key) => {
8697
+ useInput9((input6, key) => {
9099
8698
  if (key.tab) {
9100
8699
  const fields = ["input", "mode", "full", "convert"];
9101
8700
  const currentIndex = fields.indexOf(focusedField);
@@ -9133,8 +8732,8 @@ var UrlView = () => {
9133
8732
  } catch (error) {
9134
8733
  }
9135
8734
  };
9136
- return /* @__PURE__ */ React23.createElement(Box18, { flexDirection: "column" }, /* @__PURE__ */ React23.createElement(Box18, { marginBottom: 1 }, /* @__PURE__ */ React23.createElement(Text19, { bold: true, color: "cyan" }, "\u{1F517} URL Encoder/Decoder")), /* @__PURE__ */ React23.createElement(
9137
- Box18,
8735
+ return /* @__PURE__ */ React17.createElement(Box13, { flexDirection: "column" }, /* @__PURE__ */ React17.createElement(Box13, { marginBottom: 1 }, /* @__PURE__ */ React17.createElement(Text14, { bold: true, color: "cyan" }, "\u{1F517} URL Encoder/Decoder")), /* @__PURE__ */ React17.createElement(
8736
+ Box13,
9138
8737
  {
9139
8738
  flexDirection: "column",
9140
8739
  borderStyle: "single",
@@ -9143,12 +8742,12 @@ var UrlView = () => {
9143
8742
  paddingY: 1,
9144
8743
  marginBottom: 1
9145
8744
  },
9146
- /* @__PURE__ */ React23.createElement(Text19, { bold: true, color: "yellow", marginBottom: 1 }, "Options:"),
9147
- /* @__PURE__ */ React23.createElement(Box18, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React23.createElement(Box18, { marginBottom: 0 }, /* @__PURE__ */ React23.createElement(Text19, { color: focusedField === "input" ? "green" : void 0 }, focusedField === "input" ? "\u25B6 " : " ", "Input text:")), /* @__PURE__ */ React23.createElement(Box18, { marginLeft: 2, width: 60 }, focusedField === "input" ? /* @__PURE__ */ React23.createElement(TextInput8, { value: input5, onChange: setInput, placeholder: "Enter text or URL..." }) : /* @__PURE__ */ React23.createElement(Text19, { dimColor: !input5 }, input5 || "(empty)"))),
9148
- /* @__PURE__ */ React23.createElement(Box18, { marginBottom: 1 }, /* @__PURE__ */ React23.createElement(Box18, { width: 20 }, /* @__PURE__ */ React23.createElement(Text19, { color: focusedField === "mode" ? "green" : void 0 }, focusedField === "mode" ? "\u25B6 " : " ", "Mode:")), /* @__PURE__ */ React23.createElement(Text19, { bold: true, color: focusedField === "mode" ? "yellow" : void 0 }, mode === "encode" ? "ENCODE" : "DECODE"), focusedField === "mode" && /* @__PURE__ */ React23.createElement(Text19, { dimColor: true }, " (Enter to toggle)")),
9149
- /* @__PURE__ */ React23.createElement(Box18, { marginBottom: 1 }, /* @__PURE__ */ React23.createElement(Text19, { color: focusedField === "full" ? "green" : void 0 }, focusedField === "full" ? "\u25B6 " : " ", "[", fullUrl ? "\u2713" : " ", "] Full URL (encode/decode entire URL)")),
9150
- /* @__PURE__ */ React23.createElement(Box18, { marginTop: 1 }, /* @__PURE__ */ React23.createElement(
9151
- Text19,
8745
+ /* @__PURE__ */ React17.createElement(Text14, { bold: true, color: "yellow", marginBottom: 1 }, "Options:"),
8746
+ /* @__PURE__ */ React17.createElement(Box13, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React17.createElement(Box13, { marginBottom: 0 }, /* @__PURE__ */ React17.createElement(Text14, { color: focusedField === "input" ? "green" : void 0 }, focusedField === "input" ? "\u25B6 " : " ", "Input text:")), /* @__PURE__ */ React17.createElement(Box13, { marginLeft: 2, width: 60 }, focusedField === "input" ? /* @__PURE__ */ React17.createElement(TextInput8, { value: input5, onChange: setInput, placeholder: "Enter text or URL..." }) : /* @__PURE__ */ React17.createElement(Text14, { dimColor: !input5 }, input5 || "(empty)"))),
8747
+ /* @__PURE__ */ React17.createElement(Box13, { marginBottom: 1 }, /* @__PURE__ */ React17.createElement(Box13, { width: 20 }, /* @__PURE__ */ React17.createElement(Text14, { color: focusedField === "mode" ? "green" : void 0 }, focusedField === "mode" ? "\u25B6 " : " ", "Mode:")), /* @__PURE__ */ React17.createElement(Text14, { bold: true, color: focusedField === "mode" ? "yellow" : void 0 }, mode === "encode" ? "ENCODE" : "DECODE"), focusedField === "mode" && /* @__PURE__ */ React17.createElement(Text14, { dimColor: true }, " (Enter to toggle)")),
8748
+ /* @__PURE__ */ React17.createElement(Box13, { marginBottom: 1 }, /* @__PURE__ */ React17.createElement(Text14, { color: focusedField === "full" ? "green" : void 0 }, focusedField === "full" ? "\u25B6 " : " ", "[", fullUrl ? "\u2713" : " ", "] Full URL (encode/decode entire URL)")),
8749
+ /* @__PURE__ */ React17.createElement(Box13, { marginTop: 1 }, /* @__PURE__ */ React17.createElement(
8750
+ Text14,
9152
8751
  {
9153
8752
  bold: true,
9154
8753
  backgroundColor: focusedField === "convert" ? "green" : void 0,
@@ -9159,8 +8758,8 @@ var UrlView = () => {
9159
8758
  mode === "encode" ? "Encode" : "Decode",
9160
8759
  " ]"
9161
8760
  ))
9162
- ), result && /* @__PURE__ */ React23.createElement(
9163
- Box18,
8761
+ ), result && /* @__PURE__ */ React17.createElement(
8762
+ Box13,
9164
8763
  {
9165
8764
  flexDirection: "column",
9166
8765
  borderStyle: "single",
@@ -9168,26 +8767,26 @@ var UrlView = () => {
9168
8767
  paddingX: 2,
9169
8768
  paddingY: 1
9170
8769
  },
9171
- /* @__PURE__ */ React23.createElement(Box18, { marginBottom: 1 }, /* @__PURE__ */ React23.createElement(Text19, { bold: true, color: "green" }, "\u2713 Result:"), copied && /* @__PURE__ */ React23.createElement(Box18, { marginLeft: 2 }, /* @__PURE__ */ React23.createElement(Text19, { color: "green" }, "\u2713 Copied to clipboard!"))),
9172
- /* @__PURE__ */ React23.createElement(Box18, { flexDirection: "column" }, /* @__PURE__ */ React23.createElement(Text19, { dimColor: true }, "Mode: ", mode.toUpperCase(), " ", fullUrl ? "(Full URL)" : "(Component)"), /* @__PURE__ */ React23.createElement(Box18, { marginTop: 1 }, /* @__PURE__ */ React23.createElement(Text19, { wrap: "wrap" }, result)))
9173
- ), /* @__PURE__ */ React23.createElement(Box18, { marginTop: 1, borderStyle: "single", borderColor: "gray", paddingX: 2 }, /* @__PURE__ */ React23.createElement(Text19, { dimColor: true }, "Tab: Next | Enter: Toggle/Convert | C: Copy | Esc: Back")));
8770
+ /* @__PURE__ */ React17.createElement(Box13, { marginBottom: 1 }, /* @__PURE__ */ React17.createElement(Text14, { bold: true, color: "green" }, "\u2713 Result:"), copied && /* @__PURE__ */ React17.createElement(Box13, { marginLeft: 2 }, /* @__PURE__ */ React17.createElement(Text14, { color: "green" }, "\u2713 Copied to clipboard!"))),
8771
+ /* @__PURE__ */ React17.createElement(Box13, { flexDirection: "column" }, /* @__PURE__ */ React17.createElement(Text14, { dimColor: true }, "Mode: ", mode.toUpperCase(), " ", fullUrl ? "(Full URL)" : "(Component)"), /* @__PURE__ */ React17.createElement(Box13, { marginTop: 1 }, /* @__PURE__ */ React17.createElement(Text14, { wrap: "wrap" }, result)))
8772
+ ), /* @__PURE__ */ React17.createElement(Box13, { marginTop: 1, borderStyle: "single", borderColor: "gray", paddingX: 2 }, /* @__PURE__ */ React17.createElement(Text14, { dimColor: true }, "Tab: Next | Enter: Toggle/Convert | C: Copy | Esc: Back")));
9174
8773
  };
9175
8774
 
9176
8775
  // src/ui/utils/views/UnixTimeView.tsx
9177
- import React24, { useState as useState17 } from "react";
9178
- import { Box as Box19, Text as Text20, useInput as useInput15 } from "ink";
8776
+ import React18, { useState as useState12 } from "react";
8777
+ import { Box as Box14, Text as Text15, useInput as useInput10 } from "ink";
9179
8778
  import TextInput9 from "ink-text-input";
9180
8779
  var UnixTimeView = () => {
9181
- const [input5, setInput] = useState17("");
9182
- const [mode, setMode] = useState17("now");
9183
- const [format, setFormat] = useState17("iso");
9184
- const [useMs, setUseMs] = useState17(false);
9185
- const [result, setResult] = useState17("");
9186
- const [error, setError] = useState17("");
9187
- const [focusedField, setFocusedField] = useState17("mode");
9188
- const [copied, setCopied] = useState17(false);
8780
+ const [input5, setInput] = useState12("");
8781
+ const [mode, setMode] = useState12("now");
8782
+ const [format, setFormat] = useState12("iso");
8783
+ const [useMs, setUseMs] = useState12(false);
8784
+ const [result, setResult] = useState12("");
8785
+ const [error, setError] = useState12("");
8786
+ const [focusedField, setFocusedField] = useState12("mode");
8787
+ const [copied, setCopied] = useState12(false);
9189
8788
  const service = new UtilsService();
9190
- useInput15((input6, key) => {
8789
+ useInput10((input6, key) => {
9191
8790
  if (key.tab) {
9192
8791
  const fields = mode === "now" ? ["mode", "ms", "convert"] : mode === "to-human" ? ["mode", "input", "format", "convert"] : ["mode", "input", "convert"];
9193
8792
  const currentIndex = fields.indexOf(focusedField);
@@ -9248,8 +8847,8 @@ var UnixTimeView = () => {
9248
8847
  } catch (error2) {
9249
8848
  }
9250
8849
  };
9251
- return /* @__PURE__ */ React24.createElement(Box19, { flexDirection: "column" }, /* @__PURE__ */ React24.createElement(Box19, { marginBottom: 1 }, /* @__PURE__ */ React24.createElement(Text20, { bold: true, color: "cyan" }, "\u{1F552} Unix Time Converter")), /* @__PURE__ */ React24.createElement(
9252
- Box19,
8850
+ return /* @__PURE__ */ React18.createElement(Box14, { flexDirection: "column" }, /* @__PURE__ */ React18.createElement(Box14, { marginBottom: 1 }, /* @__PURE__ */ React18.createElement(Text15, { bold: true, color: "cyan" }, "\u{1F552} Unix Time Converter")), /* @__PURE__ */ React18.createElement(
8851
+ Box14,
9253
8852
  {
9254
8853
  flexDirection: "column",
9255
8854
  borderStyle: "single",
@@ -9258,20 +8857,20 @@ var UnixTimeView = () => {
9258
8857
  paddingY: 1,
9259
8858
  marginBottom: 1
9260
8859
  },
9261
- /* @__PURE__ */ React24.createElement(Text20, { bold: true, color: "yellow", marginBottom: 1 }, "Options:"),
9262
- /* @__PURE__ */ React24.createElement(Box19, { marginBottom: 1 }, /* @__PURE__ */ React24.createElement(Box19, { width: 20 }, /* @__PURE__ */ React24.createElement(Text20, { color: focusedField === "mode" ? "green" : void 0 }, focusedField === "mode" ? "\u25B6 " : " ", "Mode:")), /* @__PURE__ */ React24.createElement(Text20, { bold: true, color: focusedField === "mode" ? "yellow" : void 0 }, mode === "now" ? "CURRENT TIME" : mode === "to-human" ? "TIMESTAMP \u2192 HUMAN" : "HUMAN \u2192 TIMESTAMP"), focusedField === "mode" && /* @__PURE__ */ React24.createElement(Text20, { dimColor: true }, " (Enter to cycle)")),
9263
- mode !== "now" && /* @__PURE__ */ React24.createElement(Box19, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React24.createElement(Box19, { marginBottom: 0 }, /* @__PURE__ */ React24.createElement(Text20, { color: focusedField === "input" ? "green" : void 0 }, focusedField === "input" ? "\u25B6 " : " ", mode === "to-human" ? "Timestamp:" : "Date string:")), /* @__PURE__ */ React24.createElement(Box19, { marginLeft: 2, width: 50 }, focusedField === "input" ? /* @__PURE__ */ React24.createElement(
8860
+ /* @__PURE__ */ React18.createElement(Text15, { bold: true, color: "yellow", marginBottom: 1 }, "Options:"),
8861
+ /* @__PURE__ */ React18.createElement(Box14, { marginBottom: 1 }, /* @__PURE__ */ React18.createElement(Box14, { width: 20 }, /* @__PURE__ */ React18.createElement(Text15, { color: focusedField === "mode" ? "green" : void 0 }, focusedField === "mode" ? "\u25B6 " : " ", "Mode:")), /* @__PURE__ */ React18.createElement(Text15, { bold: true, color: focusedField === "mode" ? "yellow" : void 0 }, mode === "now" ? "CURRENT TIME" : mode === "to-human" ? "TIMESTAMP \u2192 HUMAN" : "HUMAN \u2192 TIMESTAMP"), focusedField === "mode" && /* @__PURE__ */ React18.createElement(Text15, { dimColor: true }, " (Enter to cycle)")),
8862
+ mode !== "now" && /* @__PURE__ */ React18.createElement(Box14, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React18.createElement(Box14, { marginBottom: 0 }, /* @__PURE__ */ React18.createElement(Text15, { color: focusedField === "input" ? "green" : void 0 }, focusedField === "input" ? "\u25B6 " : " ", mode === "to-human" ? "Timestamp:" : "Date string:")), /* @__PURE__ */ React18.createElement(Box14, { marginLeft: 2, width: 50 }, focusedField === "input" ? /* @__PURE__ */ React18.createElement(
9264
8863
  TextInput9,
9265
8864
  {
9266
8865
  value: input5,
9267
8866
  onChange: setInput,
9268
8867
  placeholder: mode === "to-human" ? "1702550400" : "2024-01-15 10:30:00"
9269
8868
  }
9270
- ) : /* @__PURE__ */ React24.createElement(Text20, { dimColor: !input5 }, input5 || "(empty)"))),
9271
- mode === "to-human" && /* @__PURE__ */ React24.createElement(Box19, { marginBottom: 1 }, /* @__PURE__ */ React24.createElement(Box19, { width: 20 }, /* @__PURE__ */ React24.createElement(Text20, { color: focusedField === "format" ? "green" : void 0 }, focusedField === "format" ? "\u25B6 " : " ", "Format:")), /* @__PURE__ */ React24.createElement(Text20, { bold: true, color: focusedField === "format" ? "yellow" : void 0 }, format.toUpperCase()), focusedField === "format" && /* @__PURE__ */ React24.createElement(Text20, { dimColor: true }, " (Enter to cycle)")),
9272
- mode === "now" && /* @__PURE__ */ React24.createElement(Box19, { marginBottom: 1 }, /* @__PURE__ */ React24.createElement(Text20, { color: focusedField === "ms" ? "green" : void 0 }, focusedField === "ms" ? "\u25B6 " : " ", "[", useMs ? "\u2713" : " ", "] Milliseconds")),
9273
- /* @__PURE__ */ React24.createElement(Box19, { marginTop: 1 }, /* @__PURE__ */ React24.createElement(
9274
- Text20,
8869
+ ) : /* @__PURE__ */ React18.createElement(Text15, { dimColor: !input5 }, input5 || "(empty)"))),
8870
+ mode === "to-human" && /* @__PURE__ */ React18.createElement(Box14, { marginBottom: 1 }, /* @__PURE__ */ React18.createElement(Box14, { width: 20 }, /* @__PURE__ */ React18.createElement(Text15, { color: focusedField === "format" ? "green" : void 0 }, focusedField === "format" ? "\u25B6 " : " ", "Format:")), /* @__PURE__ */ React18.createElement(Text15, { bold: true, color: focusedField === "format" ? "yellow" : void 0 }, format.toUpperCase()), focusedField === "format" && /* @__PURE__ */ React18.createElement(Text15, { dimColor: true }, " (Enter to cycle)")),
8871
+ mode === "now" && /* @__PURE__ */ React18.createElement(Box14, { marginBottom: 1 }, /* @__PURE__ */ React18.createElement(Text15, { color: focusedField === "ms" ? "green" : void 0 }, focusedField === "ms" ? "\u25B6 " : " ", "[", useMs ? "\u2713" : " ", "] Milliseconds")),
8872
+ /* @__PURE__ */ React18.createElement(Box14, { marginTop: 1 }, /* @__PURE__ */ React18.createElement(
8873
+ Text15,
9275
8874
  {
9276
8875
  bold: true,
9277
8876
  backgroundColor: focusedField === "convert" ? "green" : void 0,
@@ -9282,8 +8881,8 @@ var UnixTimeView = () => {
9282
8881
  mode === "now" ? "Get Current" : "Convert",
9283
8882
  " ]"
9284
8883
  ))
9285
- ), error && /* @__PURE__ */ React24.createElement(
9286
- Box19,
8884
+ ), error && /* @__PURE__ */ React18.createElement(
8885
+ Box14,
9287
8886
  {
9288
8887
  flexDirection: "column",
9289
8888
  borderStyle: "single",
@@ -9292,9 +8891,9 @@ var UnixTimeView = () => {
9292
8891
  paddingY: 1,
9293
8892
  marginBottom: 1
9294
8893
  },
9295
- /* @__PURE__ */ React24.createElement(Text20, { color: "red" }, "\u2717 Error: ", error)
9296
- ), result && /* @__PURE__ */ React24.createElement(
9297
- Box19,
8894
+ /* @__PURE__ */ React18.createElement(Text15, { color: "red" }, "\u2717 Error: ", error)
8895
+ ), result && /* @__PURE__ */ React18.createElement(
8896
+ Box14,
9298
8897
  {
9299
8898
  flexDirection: "column",
9300
8899
  borderStyle: "single",
@@ -9302,26 +8901,26 @@ var UnixTimeView = () => {
9302
8901
  paddingX: 2,
9303
8902
  paddingY: 1
9304
8903
  },
9305
- /* @__PURE__ */ React24.createElement(Box19, { marginBottom: 1 }, /* @__PURE__ */ React24.createElement(Text20, { bold: true, color: "green" }, "\u2713 Result:"), copied && /* @__PURE__ */ React24.createElement(Box19, { marginLeft: 2 }, /* @__PURE__ */ React24.createElement(Text20, { color: "green" }, "\u2713 Copied to clipboard!"))),
9306
- /* @__PURE__ */ React24.createElement(Box19, { flexDirection: "column" }, /* @__PURE__ */ React24.createElement(Box19, { marginTop: 1 }, /* @__PURE__ */ React24.createElement(Text20, { wrap: "wrap" }, result)))
9307
- ), /* @__PURE__ */ React24.createElement(Box19, { marginTop: 1, borderStyle: "single", borderColor: "gray", paddingX: 2 }, /* @__PURE__ */ React24.createElement(Text20, { dimColor: true }, "Tab: Next | Enter: Toggle/Convert | C: Copy | Esc: Back")));
8904
+ /* @__PURE__ */ React18.createElement(Box14, { marginBottom: 1 }, /* @__PURE__ */ React18.createElement(Text15, { bold: true, color: "green" }, "\u2713 Result:"), copied && /* @__PURE__ */ React18.createElement(Box14, { marginLeft: 2 }, /* @__PURE__ */ React18.createElement(Text15, { color: "green" }, "\u2713 Copied to clipboard!"))),
8905
+ /* @__PURE__ */ React18.createElement(Box14, { flexDirection: "column" }, /* @__PURE__ */ React18.createElement(Box14, { marginTop: 1 }, /* @__PURE__ */ React18.createElement(Text15, { wrap: "wrap" }, result)))
8906
+ ), /* @__PURE__ */ React18.createElement(Box14, { marginTop: 1, borderStyle: "single", borderColor: "gray", paddingX: 2 }, /* @__PURE__ */ React18.createElement(Text15, { dimColor: true }, "Tab: Next | Enter: Toggle/Convert | C: Copy | Esc: Back")));
9308
8907
  };
9309
8908
 
9310
8909
  // src/ui/utils/views/JwtView.tsx
9311
- import React25, { useState as useState18 } from "react";
9312
- import { Box as Box20, Text as Text21, useInput as useInput16 } from "ink";
8910
+ import React19, { useState as useState13 } from "react";
8911
+ import { Box as Box15, Text as Text16, useInput as useInput11 } from "ink";
9313
8912
  import TextInput10 from "ink-text-input";
9314
8913
  var JwtView = () => {
9315
- const [mode, setMode] = useState18("decode");
9316
- const [token, setToken] = useState18("");
9317
- const [payload, setPayload] = useState18("");
9318
- const [secret, setSecret] = useState18("");
9319
- const [result, setResult] = useState18({});
9320
- const [error, setError] = useState18("");
9321
- const [focusedField, setFocusedField] = useState18("mode");
9322
- const [copied, setCopied] = useState18(false);
8914
+ const [mode, setMode] = useState13("decode");
8915
+ const [token, setToken] = useState13("");
8916
+ const [payload, setPayload] = useState13("");
8917
+ const [secret, setSecret] = useState13("");
8918
+ const [result, setResult] = useState13({});
8919
+ const [error, setError] = useState13("");
8920
+ const [focusedField, setFocusedField] = useState13("mode");
8921
+ const [copied, setCopied] = useState13(false);
9323
8922
  const service = new UtilsService();
9324
- useInput16((input5, key) => {
8923
+ useInput11((input5, key) => {
9325
8924
  if (key.tab) {
9326
8925
  const fields = mode === "decode" ? ["mode", "token", "process"] : ["mode", "payload", "secret", "process"];
9327
8926
  const currentIndex = fields.indexOf(focusedField);
@@ -9376,8 +8975,8 @@ var JwtView = () => {
9376
8975
  } catch (error2) {
9377
8976
  }
9378
8977
  };
9379
- return /* @__PURE__ */ React25.createElement(Box20, { flexDirection: "column" }, /* @__PURE__ */ React25.createElement(Box20, { marginBottom: 1 }, /* @__PURE__ */ React25.createElement(Text21, { bold: true, color: "cyan" }, "\u{1F511} JWT Decoder/Encoder")), /* @__PURE__ */ React25.createElement(
9380
- Box20,
8978
+ return /* @__PURE__ */ React19.createElement(Box15, { flexDirection: "column" }, /* @__PURE__ */ React19.createElement(Box15, { marginBottom: 1 }, /* @__PURE__ */ React19.createElement(Text16, { bold: true, color: "cyan" }, "\u{1F511} JWT Decoder/Encoder")), /* @__PURE__ */ React19.createElement(
8979
+ Box15,
9381
8980
  {
9382
8981
  flexDirection: "column",
9383
8982
  borderStyle: "single",
@@ -9386,23 +8985,23 @@ var JwtView = () => {
9386
8985
  paddingY: 1,
9387
8986
  marginBottom: 1
9388
8987
  },
9389
- /* @__PURE__ */ React25.createElement(Text21, { bold: true, color: "yellow", marginBottom: 1 }, "Options:"),
9390
- /* @__PURE__ */ React25.createElement(Box20, { marginBottom: 1 }, /* @__PURE__ */ React25.createElement(Box20, { width: 20 }, /* @__PURE__ */ React25.createElement(Text21, { color: focusedField === "mode" ? "green" : void 0 }, focusedField === "mode" ? "\u25B6 " : " ", "Mode:")), /* @__PURE__ */ React25.createElement(Text21, { bold: true, color: focusedField === "mode" ? "yellow" : void 0 }, mode === "decode" ? "DECODE" : "ENCODE"), focusedField === "mode" && /* @__PURE__ */ React25.createElement(Text21, { dimColor: true }, " (Enter to toggle)")),
9391
- mode === "decode" ? /* @__PURE__ */ React25.createElement(Box20, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React25.createElement(Box20, { marginBottom: 0 }, /* @__PURE__ */ React25.createElement(Text21, { color: focusedField === "token" ? "green" : void 0 }, focusedField === "token" ? "\u25B6 " : " ", "JWT Token:")), /* @__PURE__ */ React25.createElement(Box20, { marginLeft: 2, width: 60 }, focusedField === "token" ? /* @__PURE__ */ React25.createElement(
8988
+ /* @__PURE__ */ React19.createElement(Text16, { bold: true, color: "yellow", marginBottom: 1 }, "Options:"),
8989
+ /* @__PURE__ */ React19.createElement(Box15, { marginBottom: 1 }, /* @__PURE__ */ React19.createElement(Box15, { width: 20 }, /* @__PURE__ */ React19.createElement(Text16, { color: focusedField === "mode" ? "green" : void 0 }, focusedField === "mode" ? "\u25B6 " : " ", "Mode:")), /* @__PURE__ */ React19.createElement(Text16, { bold: true, color: focusedField === "mode" ? "yellow" : void 0 }, mode === "decode" ? "DECODE" : "ENCODE"), focusedField === "mode" && /* @__PURE__ */ React19.createElement(Text16, { dimColor: true }, " (Enter to toggle)")),
8990
+ mode === "decode" ? /* @__PURE__ */ React19.createElement(Box15, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React19.createElement(Box15, { marginBottom: 0 }, /* @__PURE__ */ React19.createElement(Text16, { color: focusedField === "token" ? "green" : void 0 }, focusedField === "token" ? "\u25B6 " : " ", "JWT Token:")), /* @__PURE__ */ React19.createElement(Box15, { marginLeft: 2, width: 60 }, focusedField === "token" ? /* @__PURE__ */ React19.createElement(
9392
8991
  TextInput10,
9393
8992
  {
9394
8993
  value: token,
9395
8994
  onChange: setToken,
9396
8995
  placeholder: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
9397
8996
  }
9398
- ) : /* @__PURE__ */ React25.createElement(Text21, { dimColor: !token }, token || "(empty)"))) : /* @__PURE__ */ React25.createElement(React25.Fragment, null, /* @__PURE__ */ React25.createElement(Box20, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React25.createElement(Box20, { marginBottom: 0 }, /* @__PURE__ */ React25.createElement(Text21, { color: focusedField === "payload" ? "green" : void 0 }, focusedField === "payload" ? "\u25B6 " : " ", "Payload (JSON):")), /* @__PURE__ */ React25.createElement(Box20, { marginLeft: 2, width: 60 }, focusedField === "payload" ? /* @__PURE__ */ React25.createElement(
8997
+ ) : /* @__PURE__ */ React19.createElement(Text16, { dimColor: !token }, token || "(empty)"))) : /* @__PURE__ */ React19.createElement(React19.Fragment, null, /* @__PURE__ */ React19.createElement(Box15, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React19.createElement(Box15, { marginBottom: 0 }, /* @__PURE__ */ React19.createElement(Text16, { color: focusedField === "payload" ? "green" : void 0 }, focusedField === "payload" ? "\u25B6 " : " ", "Payload (JSON):")), /* @__PURE__ */ React19.createElement(Box15, { marginLeft: 2, width: 60 }, focusedField === "payload" ? /* @__PURE__ */ React19.createElement(
9399
8998
  TextInput10,
9400
8999
  {
9401
9000
  value: payload,
9402
9001
  onChange: setPayload,
9403
9002
  placeholder: '{"sub":"123","name":"John"}'
9404
9003
  }
9405
- ) : /* @__PURE__ */ React25.createElement(Text21, { dimColor: !payload }, payload || "(empty)"))), /* @__PURE__ */ React25.createElement(Box20, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React25.createElement(Box20, { marginBottom: 0 }, /* @__PURE__ */ React25.createElement(Text21, { color: focusedField === "secret" ? "green" : void 0 }, focusedField === "secret" ? "\u25B6 " : " ", "Secret Key:")), /* @__PURE__ */ React25.createElement(Box20, { marginLeft: 2, width: 60 }, focusedField === "secret" ? /* @__PURE__ */ React25.createElement(
9004
+ ) : /* @__PURE__ */ React19.createElement(Text16, { dimColor: !payload }, payload || "(empty)"))), /* @__PURE__ */ React19.createElement(Box15, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React19.createElement(Box15, { marginBottom: 0 }, /* @__PURE__ */ React19.createElement(Text16, { color: focusedField === "secret" ? "green" : void 0 }, focusedField === "secret" ? "\u25B6 " : " ", "Secret Key:")), /* @__PURE__ */ React19.createElement(Box15, { marginLeft: 2, width: 60 }, focusedField === "secret" ? /* @__PURE__ */ React19.createElement(
9406
9005
  TextInput10,
9407
9006
  {
9408
9007
  value: secret,
@@ -9410,9 +9009,9 @@ var JwtView = () => {
9410
9009
  placeholder: "your-secret-key",
9411
9010
  mask: "*"
9412
9011
  }
9413
- ) : /* @__PURE__ */ React25.createElement(Text21, { dimColor: !secret }, secret ? "*".repeat(secret.length) : "(empty)")))),
9414
- /* @__PURE__ */ React25.createElement(Box20, { marginTop: 1 }, /* @__PURE__ */ React25.createElement(
9415
- Text21,
9012
+ ) : /* @__PURE__ */ React19.createElement(Text16, { dimColor: !secret }, secret ? "*".repeat(secret.length) : "(empty)")))),
9013
+ /* @__PURE__ */ React19.createElement(Box15, { marginTop: 1 }, /* @__PURE__ */ React19.createElement(
9014
+ Text16,
9416
9015
  {
9417
9016
  bold: true,
9418
9017
  backgroundColor: focusedField === "process" ? "green" : void 0,
@@ -9423,8 +9022,8 @@ var JwtView = () => {
9423
9022
  mode === "decode" ? "Decode" : "Encode",
9424
9023
  " ]"
9425
9024
  ))
9426
- ), error && /* @__PURE__ */ React25.createElement(
9427
- Box20,
9025
+ ), error && /* @__PURE__ */ React19.createElement(
9026
+ Box15,
9428
9027
  {
9429
9028
  flexDirection: "column",
9430
9029
  borderStyle: "single",
@@ -9433,9 +9032,9 @@ var JwtView = () => {
9433
9032
  paddingY: 1,
9434
9033
  marginBottom: 1
9435
9034
  },
9436
- /* @__PURE__ */ React25.createElement(Text21, { color: "red" }, "\u2717 Error: ", error)
9437
- ), (result.header || result.token) && /* @__PURE__ */ React25.createElement(
9438
- Box20,
9035
+ /* @__PURE__ */ React19.createElement(Text16, { color: "red" }, "\u2717 Error: ", error)
9036
+ ), (result.header || result.token) && /* @__PURE__ */ React19.createElement(
9037
+ Box15,
9439
9038
  {
9440
9039
  flexDirection: "column",
9441
9040
  borderStyle: "single",
@@ -9443,23 +9042,23 @@ var JwtView = () => {
9443
9042
  paddingX: 2,
9444
9043
  paddingY: 1
9445
9044
  },
9446
- /* @__PURE__ */ React25.createElement(Box20, { marginBottom: 1 }, /* @__PURE__ */ React25.createElement(Text21, { bold: true, color: "green" }, "\u2713 Result:"), copied && result.token && /* @__PURE__ */ React25.createElement(Box20, { marginLeft: 2 }, /* @__PURE__ */ React25.createElement(Text21, { color: "green" }, "\u2713 Copied to clipboard!"))),
9447
- /* @__PURE__ */ React25.createElement(Box20, { flexDirection: "column" }, result.header && /* @__PURE__ */ React25.createElement(React25.Fragment, null, /* @__PURE__ */ React25.createElement(Text21, { bold: true, color: "yellow" }, "Header:"), /* @__PURE__ */ React25.createElement(Text21, null, JSON.stringify(result.header, null, 2)), /* @__PURE__ */ React25.createElement(Text21, null, " "), /* @__PURE__ */ React25.createElement(Text21, { bold: true, color: "yellow" }, "Payload:"), /* @__PURE__ */ React25.createElement(Text21, null, JSON.stringify(result.payload, null, 2)), /* @__PURE__ */ React25.createElement(Text21, null, " "), /* @__PURE__ */ React25.createElement(Text21, { bold: true, color: "yellow" }, "Signature:"), /* @__PURE__ */ React25.createElement(Text21, { dimColor: true }, result.signature)), result.token && /* @__PURE__ */ React25.createElement(React25.Fragment, null, /* @__PURE__ */ React25.createElement(Text21, { bold: true, color: "yellow" }, "Token:"), /* @__PURE__ */ React25.createElement(Text21, { wrap: "wrap" }, result.token)))
9448
- ), /* @__PURE__ */ React25.createElement(Box20, { marginTop: 1, borderStyle: "single", borderColor: "gray", paddingX: 2 }, /* @__PURE__ */ React25.createElement(Text21, { dimColor: true }, "Tab: Next | Enter: Toggle/", mode === "decode" ? "Decode" : "Encode", " | C: Copy | Esc: Back")));
9045
+ /* @__PURE__ */ React19.createElement(Box15, { marginBottom: 1 }, /* @__PURE__ */ React19.createElement(Text16, { bold: true, color: "green" }, "\u2713 Result:"), copied && result.token && /* @__PURE__ */ React19.createElement(Box15, { marginLeft: 2 }, /* @__PURE__ */ React19.createElement(Text16, { color: "green" }, "\u2713 Copied to clipboard!"))),
9046
+ /* @__PURE__ */ React19.createElement(Box15, { flexDirection: "column" }, result.header && /* @__PURE__ */ React19.createElement(React19.Fragment, null, /* @__PURE__ */ React19.createElement(Text16, { bold: true, color: "yellow" }, "Header:"), /* @__PURE__ */ React19.createElement(Text16, null, JSON.stringify(result.header, null, 2)), /* @__PURE__ */ React19.createElement(Text16, null, " "), /* @__PURE__ */ React19.createElement(Text16, { bold: true, color: "yellow" }, "Payload:"), /* @__PURE__ */ React19.createElement(Text16, null, JSON.stringify(result.payload, null, 2)), /* @__PURE__ */ React19.createElement(Text16, null, " "), /* @__PURE__ */ React19.createElement(Text16, { bold: true, color: "yellow" }, "Signature:"), /* @__PURE__ */ React19.createElement(Text16, { dimColor: true }, result.signature)), result.token && /* @__PURE__ */ React19.createElement(React19.Fragment, null, /* @__PURE__ */ React19.createElement(Text16, { bold: true, color: "yellow" }, "Token:"), /* @__PURE__ */ React19.createElement(Text16, { wrap: "wrap" }, result.token)))
9047
+ ), /* @__PURE__ */ React19.createElement(Box15, { marginTop: 1, borderStyle: "single", borderColor: "gray", paddingX: 2 }, /* @__PURE__ */ React19.createElement(Text16, { dimColor: true }, "Tab: Next | Enter: Toggle/", mode === "decode" ? "Decode" : "Encode", " | C: Copy | Esc: Back")));
9449
9048
  };
9450
9049
 
9451
9050
  // src/ui/utils/views/CronView.tsx
9452
- import React26, { useState as useState19 } from "react";
9453
- import { Box as Box21, Text as Text22, useInput as useInput17 } from "ink";
9051
+ import React20, { useState as useState14 } from "react";
9052
+ import { Box as Box16, Text as Text17, useInput as useInput12 } from "ink";
9454
9053
  import TextInput11 from "ink-text-input";
9455
9054
  var CronView = () => {
9456
- const [expression, setExpression] = useState19("");
9457
- const [result, setResult] = useState19(null);
9458
- const [error, setError] = useState19("");
9459
- const [focusedField, setFocusedField] = useState19("expression");
9460
- const [copied, setCopied] = useState19(false);
9055
+ const [expression, setExpression] = useState14("");
9056
+ const [result, setResult] = useState14(null);
9057
+ const [error, setError] = useState14("");
9058
+ const [focusedField, setFocusedField] = useState14("expression");
9059
+ const [copied, setCopied] = useState14(false);
9461
9060
  const service = new UtilsService();
9462
- useInput17((input5, key) => {
9061
+ useInput12((input5, key) => {
9463
9062
  if (key.tab) {
9464
9063
  setFocusedField(focusedField === "expression" ? "parse" : "expression");
9465
9064
  } else if (key.return) {
@@ -9497,8 +9096,8 @@ ${result.nextRuns.join("\n")}`;
9497
9096
  } catch (error2) {
9498
9097
  }
9499
9098
  };
9500
- return /* @__PURE__ */ React26.createElement(Box21, { flexDirection: "column" }, /* @__PURE__ */ React26.createElement(Box21, { marginBottom: 1 }, /* @__PURE__ */ React26.createElement(Text22, { bold: true, color: "cyan" }, "\u23F0 Cron Expression Parser")), /* @__PURE__ */ React26.createElement(
9501
- Box21,
9099
+ return /* @__PURE__ */ React20.createElement(Box16, { flexDirection: "column" }, /* @__PURE__ */ React20.createElement(Box16, { marginBottom: 1 }, /* @__PURE__ */ React20.createElement(Text17, { bold: true, color: "cyan" }, "\u23F0 Cron Expression Parser")), /* @__PURE__ */ React20.createElement(
9100
+ Box16,
9502
9101
  {
9503
9102
  flexDirection: "column",
9504
9103
  borderStyle: "single",
@@ -9507,18 +9106,18 @@ ${result.nextRuns.join("\n")}`;
9507
9106
  paddingY: 1,
9508
9107
  marginBottom: 1
9509
9108
  },
9510
- /* @__PURE__ */ React26.createElement(Text22, { bold: true, color: "yellow", marginBottom: 1 }, "Options:"),
9511
- /* @__PURE__ */ React26.createElement(Box21, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React26.createElement(Box21, { marginBottom: 0 }, /* @__PURE__ */ React26.createElement(Text22, { color: focusedField === "expression" ? "green" : void 0 }, focusedField === "expression" ? "\u25B6 " : " ", "Cron Expression:")), /* @__PURE__ */ React26.createElement(Box21, { marginLeft: 2, width: 50 }, focusedField === "expression" ? /* @__PURE__ */ React26.createElement(
9109
+ /* @__PURE__ */ React20.createElement(Text17, { bold: true, color: "yellow", marginBottom: 1 }, "Options:"),
9110
+ /* @__PURE__ */ React20.createElement(Box16, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React20.createElement(Box16, { marginBottom: 0 }, /* @__PURE__ */ React20.createElement(Text17, { color: focusedField === "expression" ? "green" : void 0 }, focusedField === "expression" ? "\u25B6 " : " ", "Cron Expression:")), /* @__PURE__ */ React20.createElement(Box16, { marginLeft: 2, width: 50 }, focusedField === "expression" ? /* @__PURE__ */ React20.createElement(
9512
9111
  TextInput11,
9513
9112
  {
9514
9113
  value: expression,
9515
9114
  onChange: setExpression,
9516
9115
  placeholder: "0 5 * * * (5-field or 6-field)"
9517
9116
  }
9518
- ) : /* @__PURE__ */ React26.createElement(Text22, { dimColor: !expression }, expression || "(empty)"))),
9519
- /* @__PURE__ */ React26.createElement(Box21, { marginTop: 1, marginBottom: 1 }, /* @__PURE__ */ React26.createElement(Text22, { dimColor: true }, 'Examples: "0 5 * * *" (daily at 5am), "*/15 * * * *" (every 15 min)')),
9520
- /* @__PURE__ */ React26.createElement(Box21, { marginTop: 1 }, /* @__PURE__ */ React26.createElement(
9521
- Text22,
9117
+ ) : /* @__PURE__ */ React20.createElement(Text17, { dimColor: !expression }, expression || "(empty)"))),
9118
+ /* @__PURE__ */ React20.createElement(Box16, { marginTop: 1, marginBottom: 1 }, /* @__PURE__ */ React20.createElement(Text17, { dimColor: true }, 'Examples: "0 5 * * *" (daily at 5am), "*/15 * * * *" (every 15 min)')),
9119
+ /* @__PURE__ */ React20.createElement(Box16, { marginTop: 1 }, /* @__PURE__ */ React20.createElement(
9120
+ Text17,
9522
9121
  {
9523
9122
  bold: true,
9524
9123
  backgroundColor: focusedField === "parse" ? "green" : void 0,
@@ -9527,8 +9126,8 @@ ${result.nextRuns.join("\n")}`;
9527
9126
  focusedField === "parse" ? "\u25B6 " : " ",
9528
9127
  "[ Parse Expression ]"
9529
9128
  ))
9530
- ), error && /* @__PURE__ */ React26.createElement(
9531
- Box21,
9129
+ ), error && /* @__PURE__ */ React20.createElement(
9130
+ Box16,
9532
9131
  {
9533
9132
  flexDirection: "column",
9534
9133
  borderStyle: "single",
@@ -9537,9 +9136,9 @@ ${result.nextRuns.join("\n")}`;
9537
9136
  paddingY: 1,
9538
9137
  marginBottom: 1
9539
9138
  },
9540
- /* @__PURE__ */ React26.createElement(Text22, { color: "red" }, "\u2717 Error: ", error)
9541
- ), result && /* @__PURE__ */ React26.createElement(
9542
- Box21,
9139
+ /* @__PURE__ */ React20.createElement(Text17, { color: "red" }, "\u2717 Error: ", error)
9140
+ ), result && /* @__PURE__ */ React20.createElement(
9141
+ Box16,
9543
9142
  {
9544
9143
  flexDirection: "column",
9545
9144
  borderStyle: "single",
@@ -9547,25 +9146,25 @@ ${result.nextRuns.join("\n")}`;
9547
9146
  paddingX: 2,
9548
9147
  paddingY: 1
9549
9148
  },
9550
- /* @__PURE__ */ React26.createElement(Box21, { marginBottom: 1 }, /* @__PURE__ */ React26.createElement(Text22, { bold: true, color: "green" }, "\u2713 Result:"), copied && /* @__PURE__ */ React26.createElement(Box21, { marginLeft: 2 }, /* @__PURE__ */ React26.createElement(Text22, { color: "green" }, "\u2713 Copied to clipboard!"))),
9551
- /* @__PURE__ */ React26.createElement(Box21, { flexDirection: "column" }, /* @__PURE__ */ React26.createElement(Text22, { bold: true, color: "yellow" }, "Expression:"), /* @__PURE__ */ React26.createElement(Text22, null, expression), /* @__PURE__ */ React26.createElement(Text22, null, " "), /* @__PURE__ */ React26.createElement(Text22, { bold: true, color: "yellow" }, "Meaning:"), /* @__PURE__ */ React26.createElement(Text22, null, result.description), /* @__PURE__ */ React26.createElement(Text22, null, " "), /* @__PURE__ */ React26.createElement(Text22, { bold: true, color: "yellow" }, "Next 5 executions:"), result.nextRuns.map((run, index) => /* @__PURE__ */ React26.createElement(Text22, { key: index }, " ", index + 1, ". ", run)))
9552
- ), /* @__PURE__ */ React26.createElement(Box21, { marginTop: 1, borderStyle: "single", borderColor: "gray", paddingX: 2 }, /* @__PURE__ */ React26.createElement(Text22, { dimColor: true }, "Tab: Next | Enter: Parse | C: Copy | Esc: Back")));
9149
+ /* @__PURE__ */ React20.createElement(Box16, { marginBottom: 1 }, /* @__PURE__ */ React20.createElement(Text17, { bold: true, color: "green" }, "\u2713 Result:"), copied && /* @__PURE__ */ React20.createElement(Box16, { marginLeft: 2 }, /* @__PURE__ */ React20.createElement(Text17, { color: "green" }, "\u2713 Copied to clipboard!"))),
9150
+ /* @__PURE__ */ React20.createElement(Box16, { flexDirection: "column" }, /* @__PURE__ */ React20.createElement(Text17, { bold: true, color: "yellow" }, "Expression:"), /* @__PURE__ */ React20.createElement(Text17, null, expression), /* @__PURE__ */ React20.createElement(Text17, null, " "), /* @__PURE__ */ React20.createElement(Text17, { bold: true, color: "yellow" }, "Meaning:"), /* @__PURE__ */ React20.createElement(Text17, null, result.description), /* @__PURE__ */ React20.createElement(Text17, null, " "), /* @__PURE__ */ React20.createElement(Text17, { bold: true, color: "yellow" }, "Next 5 executions:"), result.nextRuns.map((run, index) => /* @__PURE__ */ React20.createElement(Text17, { key: index }, " ", index + 1, ". ", run)))
9151
+ ), /* @__PURE__ */ React20.createElement(Box16, { marginTop: 1, borderStyle: "single", borderColor: "gray", paddingX: 2 }, /* @__PURE__ */ React20.createElement(Text17, { dimColor: true }, "Tab: Next | Enter: Parse | C: Copy | Esc: Back")));
9553
9152
  };
9554
9153
 
9555
9154
  // src/ui/utils/views/TimezoneView.tsx
9556
- import React27, { useState as useState20 } from "react";
9557
- import { Box as Box22, Text as Text23, useInput as useInput18 } from "ink";
9155
+ import React21, { useState as useState15 } from "react";
9156
+ import { Box as Box17, Text as Text18, useInput as useInput13 } from "ink";
9558
9157
  import TextInput12 from "ink-text-input";
9559
9158
  var TimezoneView = () => {
9560
- const [time, setTime] = useState20("");
9561
- const [fromTz, setFromTz] = useState20("UTC");
9562
- const [toTz, setToTz] = useState20("America/New_York");
9563
- const [result, setResult] = useState20("");
9564
- const [error, setError] = useState20("");
9565
- const [focusedField, setFocusedField] = useState20("time");
9566
- const [copied, setCopied] = useState20(false);
9159
+ const [time, setTime] = useState15("");
9160
+ const [fromTz, setFromTz] = useState15("UTC");
9161
+ const [toTz, setToTz] = useState15("America/New_York");
9162
+ const [result, setResult] = useState15("");
9163
+ const [error, setError] = useState15("");
9164
+ const [focusedField, setFocusedField] = useState15("time");
9165
+ const [copied, setCopied] = useState15(false);
9567
9166
  const service = new UtilsService();
9568
- useInput18((input5, key) => {
9167
+ useInput13((input5, key) => {
9569
9168
  if (key.tab) {
9570
9169
  const fields = ["time", "from", "to", "convert"];
9571
9170
  const currentIndex = fields.indexOf(focusedField);
@@ -9604,8 +9203,8 @@ var TimezoneView = () => {
9604
9203
  } catch (error2) {
9605
9204
  }
9606
9205
  };
9607
- return /* @__PURE__ */ React27.createElement(Box22, { flexDirection: "column" }, /* @__PURE__ */ React27.createElement(Box22, { marginBottom: 1 }, /* @__PURE__ */ React27.createElement(Text23, { bold: true, color: "cyan" }, "\u{1F30D} Timezone Converter")), /* @__PURE__ */ React27.createElement(
9608
- Box22,
9206
+ return /* @__PURE__ */ React21.createElement(Box17, { flexDirection: "column" }, /* @__PURE__ */ React21.createElement(Box17, { marginBottom: 1 }, /* @__PURE__ */ React21.createElement(Text18, { bold: true, color: "cyan" }, "\u{1F30D} Timezone Converter")), /* @__PURE__ */ React21.createElement(
9207
+ Box17,
9609
9208
  {
9610
9209
  flexDirection: "column",
9611
9210
  borderStyle: "single",
@@ -9614,34 +9213,34 @@ var TimezoneView = () => {
9614
9213
  paddingY: 1,
9615
9214
  marginBottom: 1
9616
9215
  },
9617
- /* @__PURE__ */ React27.createElement(Text23, { bold: true, color: "yellow", marginBottom: 1 }, "Options:"),
9618
- /* @__PURE__ */ React27.createElement(Box22, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React27.createElement(Box22, { marginBottom: 0 }, /* @__PURE__ */ React27.createElement(Text23, { color: focusedField === "time" ? "green" : void 0 }, focusedField === "time" ? "\u25B6 " : " ", "Time:")), /* @__PURE__ */ React27.createElement(Box22, { marginLeft: 2, width: 50 }, focusedField === "time" ? /* @__PURE__ */ React27.createElement(
9216
+ /* @__PURE__ */ React21.createElement(Text18, { bold: true, color: "yellow", marginBottom: 1 }, "Options:"),
9217
+ /* @__PURE__ */ React21.createElement(Box17, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React21.createElement(Box17, { marginBottom: 0 }, /* @__PURE__ */ React21.createElement(Text18, { color: focusedField === "time" ? "green" : void 0 }, focusedField === "time" ? "\u25B6 " : " ", "Time:")), /* @__PURE__ */ React21.createElement(Box17, { marginLeft: 2, width: 50 }, focusedField === "time" ? /* @__PURE__ */ React21.createElement(
9619
9218
  TextInput12,
9620
9219
  {
9621
9220
  value: time,
9622
9221
  onChange: setTime,
9623
9222
  placeholder: "2024-01-15 10:00:00"
9624
9223
  }
9625
- ) : /* @__PURE__ */ React27.createElement(Text23, { dimColor: !time }, time || "(empty)"))),
9626
- /* @__PURE__ */ React27.createElement(Box22, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React27.createElement(Box22, { marginBottom: 0 }, /* @__PURE__ */ React27.createElement(Text23, { color: focusedField === "from" ? "green" : void 0 }, focusedField === "from" ? "\u25B6 " : " ", "From Timezone:")), /* @__PURE__ */ React27.createElement(Box22, { marginLeft: 2, width: 50 }, focusedField === "from" ? /* @__PURE__ */ React27.createElement(
9224
+ ) : /* @__PURE__ */ React21.createElement(Text18, { dimColor: !time }, time || "(empty)"))),
9225
+ /* @__PURE__ */ React21.createElement(Box17, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React21.createElement(Box17, { marginBottom: 0 }, /* @__PURE__ */ React21.createElement(Text18, { color: focusedField === "from" ? "green" : void 0 }, focusedField === "from" ? "\u25B6 " : " ", "From Timezone:")), /* @__PURE__ */ React21.createElement(Box17, { marginLeft: 2, width: 50 }, focusedField === "from" ? /* @__PURE__ */ React21.createElement(
9627
9226
  TextInput12,
9628
9227
  {
9629
9228
  value: fromTz,
9630
9229
  onChange: setFromTz,
9631
9230
  placeholder: "UTC or America/New_York"
9632
9231
  }
9633
- ) : /* @__PURE__ */ React27.createElement(Text23, { dimColor: !fromTz }, fromTz || "(empty)"))),
9634
- /* @__PURE__ */ React27.createElement(Box22, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React27.createElement(Box22, { marginBottom: 0 }, /* @__PURE__ */ React27.createElement(Text23, { color: focusedField === "to" ? "green" : void 0 }, focusedField === "to" ? "\u25B6 " : " ", "To Timezone:")), /* @__PURE__ */ React27.createElement(Box22, { marginLeft: 2, width: 50 }, focusedField === "to" ? /* @__PURE__ */ React27.createElement(
9232
+ ) : /* @__PURE__ */ React21.createElement(Text18, { dimColor: !fromTz }, fromTz || "(empty)"))),
9233
+ /* @__PURE__ */ React21.createElement(Box17, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React21.createElement(Box17, { marginBottom: 0 }, /* @__PURE__ */ React21.createElement(Text18, { color: focusedField === "to" ? "green" : void 0 }, focusedField === "to" ? "\u25B6 " : " ", "To Timezone:")), /* @__PURE__ */ React21.createElement(Box17, { marginLeft: 2, width: 50 }, focusedField === "to" ? /* @__PURE__ */ React21.createElement(
9635
9234
  TextInput12,
9636
9235
  {
9637
9236
  value: toTz,
9638
9237
  onChange: setToTz,
9639
9238
  placeholder: "Asia/Tokyo or Europe/London"
9640
9239
  }
9641
- ) : /* @__PURE__ */ React27.createElement(Text23, { dimColor: !toTz }, toTz || "(empty)"))),
9642
- /* @__PURE__ */ React27.createElement(Box22, { marginBottom: 1 }, /* @__PURE__ */ React27.createElement(Text23, { dimColor: true }, "Common: UTC, America/New_York, Europe/London, Asia/Tokyo")),
9643
- /* @__PURE__ */ React27.createElement(Box22, { marginTop: 1 }, /* @__PURE__ */ React27.createElement(
9644
- Text23,
9240
+ ) : /* @__PURE__ */ React21.createElement(Text18, { dimColor: !toTz }, toTz || "(empty)"))),
9241
+ /* @__PURE__ */ React21.createElement(Box17, { marginBottom: 1 }, /* @__PURE__ */ React21.createElement(Text18, { dimColor: true }, "Common: UTC, America/New_York, Europe/London, Asia/Tokyo")),
9242
+ /* @__PURE__ */ React21.createElement(Box17, { marginTop: 1 }, /* @__PURE__ */ React21.createElement(
9243
+ Text18,
9645
9244
  {
9646
9245
  bold: true,
9647
9246
  backgroundColor: focusedField === "convert" ? "green" : void 0,
@@ -9650,8 +9249,8 @@ var TimezoneView = () => {
9650
9249
  focusedField === "convert" ? "\u25B6 " : " ",
9651
9250
  "[ Convert ]"
9652
9251
  ))
9653
- ), error && /* @__PURE__ */ React27.createElement(
9654
- Box22,
9252
+ ), error && /* @__PURE__ */ React21.createElement(
9253
+ Box17,
9655
9254
  {
9656
9255
  flexDirection: "column",
9657
9256
  borderStyle: "single",
@@ -9660,9 +9259,9 @@ var TimezoneView = () => {
9660
9259
  paddingY: 1,
9661
9260
  marginBottom: 1
9662
9261
  },
9663
- /* @__PURE__ */ React27.createElement(Text23, { color: "red" }, "\u2717 Error: ", error)
9664
- ), result && /* @__PURE__ */ React27.createElement(
9665
- Box22,
9262
+ /* @__PURE__ */ React21.createElement(Text18, { color: "red" }, "\u2717 Error: ", error)
9263
+ ), result && /* @__PURE__ */ React21.createElement(
9264
+ Box17,
9666
9265
  {
9667
9266
  flexDirection: "column",
9668
9267
  borderStyle: "single",
@@ -9670,28 +9269,28 @@ var TimezoneView = () => {
9670
9269
  paddingX: 2,
9671
9270
  paddingY: 1
9672
9271
  },
9673
- /* @__PURE__ */ React27.createElement(Box22, { marginBottom: 1 }, /* @__PURE__ */ React27.createElement(Text23, { bold: true, color: "green" }, "\u2713 Result:"), copied && /* @__PURE__ */ React27.createElement(Box22, { marginLeft: 2 }, /* @__PURE__ */ React27.createElement(Text23, { color: "green" }, "\u2713 Copied to clipboard!"))),
9674
- /* @__PURE__ */ React27.createElement(Box22, { flexDirection: "column" }, /* @__PURE__ */ React27.createElement(Text23, { dimColor: true }, "From: ", fromTz), /* @__PURE__ */ React27.createElement(Text23, { dimColor: true }, "To: ", toTz), /* @__PURE__ */ React27.createElement(Box22, { marginTop: 1 }, /* @__PURE__ */ React27.createElement(Text23, { wrap: "wrap" }, result)))
9675
- ), /* @__PURE__ */ React27.createElement(Box22, { marginTop: 1, borderStyle: "single", borderColor: "gray", paddingX: 2 }, /* @__PURE__ */ React27.createElement(Text23, { dimColor: true }, "Tab: Next | Enter: Convert | C: Copy | Esc: Back")));
9272
+ /* @__PURE__ */ React21.createElement(Box17, { marginBottom: 1 }, /* @__PURE__ */ React21.createElement(Text18, { bold: true, color: "green" }, "\u2713 Result:"), copied && /* @__PURE__ */ React21.createElement(Box17, { marginLeft: 2 }, /* @__PURE__ */ React21.createElement(Text18, { color: "green" }, "\u2713 Copied to clipboard!"))),
9273
+ /* @__PURE__ */ React21.createElement(Box17, { flexDirection: "column" }, /* @__PURE__ */ React21.createElement(Text18, { dimColor: true }, "From: ", fromTz), /* @__PURE__ */ React21.createElement(Text18, { dimColor: true }, "To: ", toTz), /* @__PURE__ */ React21.createElement(Box17, { marginTop: 1 }, /* @__PURE__ */ React21.createElement(Text18, { wrap: "wrap" }, result)))
9274
+ ), /* @__PURE__ */ React21.createElement(Box17, { marginTop: 1, borderStyle: "single", borderColor: "gray", paddingX: 2 }, /* @__PURE__ */ React21.createElement(Text18, { dimColor: true }, "Tab: Next | Enter: Convert | C: Copy | Esc: Back")));
9676
9275
  };
9677
9276
 
9678
9277
  // src/ui/utils/views/HttpView.tsx
9679
- import React28, { useState as useState21 } from "react";
9680
- import { Box as Box23, Text as Text24, useInput as useInput19 } from "ink";
9278
+ import React22, { useState as useState16 } from "react";
9279
+ import { Box as Box18, Text as Text19, useInput as useInput14 } from "ink";
9681
9280
  import TextInput13 from "ink-text-input";
9682
9281
  var METHODS = ["GET", "POST", "PUT", "PATCH", "DELETE"];
9683
9282
  var HttpView = () => {
9684
- const [url, setUrl] = useState21("");
9685
- const [method, setMethod] = useState21("GET");
9686
- const [headers, setHeaders] = useState21("");
9687
- const [body, setBody] = useState21("");
9688
- const [response, setResponse] = useState21(null);
9689
- const [error, setError] = useState21("");
9690
- const [loading, setLoading] = useState21(false);
9691
- const [focusedField, setFocusedField] = useState21("url");
9692
- const [copied, setCopied] = useState21(false);
9283
+ const [url, setUrl] = useState16("");
9284
+ const [method, setMethod] = useState16("GET");
9285
+ const [headers, setHeaders] = useState16("");
9286
+ const [body, setBody] = useState16("");
9287
+ const [response, setResponse] = useState16(null);
9288
+ const [error, setError] = useState16("");
9289
+ const [loading, setLoading] = useState16(false);
9290
+ const [focusedField, setFocusedField] = useState16("url");
9291
+ const [copied, setCopied] = useState16(false);
9693
9292
  const service = new UtilsService();
9694
- useInput19((input5, key) => {
9293
+ useInput14((input5, key) => {
9695
9294
  if (loading) return;
9696
9295
  if (key.tab) {
9697
9296
  const fields = ["url", "method", "headers", "body", "send"];
@@ -9752,8 +9351,8 @@ var HttpView = () => {
9752
9351
  } catch (error2) {
9753
9352
  }
9754
9353
  };
9755
- return /* @__PURE__ */ React28.createElement(Box23, { flexDirection: "column" }, /* @__PURE__ */ React28.createElement(Box23, { marginBottom: 1 }, /* @__PURE__ */ React28.createElement(Text24, { bold: true, color: "cyan" }, "\u{1F310} HTTP Request")), /* @__PURE__ */ React28.createElement(
9756
- Box23,
9354
+ return /* @__PURE__ */ React22.createElement(Box18, { flexDirection: "column" }, /* @__PURE__ */ React22.createElement(Box18, { marginBottom: 1 }, /* @__PURE__ */ React22.createElement(Text19, { bold: true, color: "cyan" }, "\u{1F310} HTTP Request")), /* @__PURE__ */ React22.createElement(
9355
+ Box18,
9757
9356
  {
9758
9357
  flexDirection: "column",
9759
9358
  borderStyle: "single",
@@ -9762,34 +9361,34 @@ var HttpView = () => {
9762
9361
  paddingY: 1,
9763
9362
  marginBottom: 1
9764
9363
  },
9765
- /* @__PURE__ */ React28.createElement(Text24, { bold: true, color: "yellow", marginBottom: 1 }, "Request:"),
9766
- /* @__PURE__ */ React28.createElement(Box23, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React28.createElement(Box23, { marginBottom: 0 }, /* @__PURE__ */ React28.createElement(Text24, { color: focusedField === "url" ? "green" : void 0 }, focusedField === "url" ? "\u25B6 " : " ", "URL:")), /* @__PURE__ */ React28.createElement(Box23, { marginLeft: 2, width: 60 }, focusedField === "url" ? /* @__PURE__ */ React28.createElement(
9364
+ /* @__PURE__ */ React22.createElement(Text19, { bold: true, color: "yellow", marginBottom: 1 }, "Request:"),
9365
+ /* @__PURE__ */ React22.createElement(Box18, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React22.createElement(Box18, { marginBottom: 0 }, /* @__PURE__ */ React22.createElement(Text19, { color: focusedField === "url" ? "green" : void 0 }, focusedField === "url" ? "\u25B6 " : " ", "URL:")), /* @__PURE__ */ React22.createElement(Box18, { marginLeft: 2, width: 60 }, focusedField === "url" ? /* @__PURE__ */ React22.createElement(
9767
9366
  TextInput13,
9768
9367
  {
9769
9368
  value: url,
9770
9369
  onChange: setUrl,
9771
9370
  placeholder: "https://api.example.com/endpoint"
9772
9371
  }
9773
- ) : /* @__PURE__ */ React28.createElement(Text24, { dimColor: !url }, url || "(empty)"))),
9774
- /* @__PURE__ */ React28.createElement(Box23, { marginBottom: 1 }, /* @__PURE__ */ React28.createElement(Box23, { width: 20 }, /* @__PURE__ */ React28.createElement(Text24, { color: focusedField === "method" ? "green" : void 0 }, focusedField === "method" ? "\u25B6 " : " ", "Method:")), /* @__PURE__ */ React28.createElement(Text24, { bold: true, color: focusedField === "method" ? "yellow" : void 0 }, method), focusedField === "method" && /* @__PURE__ */ React28.createElement(Text24, { dimColor: true }, " (\u2190 \u2192 to change)")),
9775
- /* @__PURE__ */ React28.createElement(Box23, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React28.createElement(Box23, { marginBottom: 0 }, /* @__PURE__ */ React28.createElement(Text24, { color: focusedField === "headers" ? "green" : void 0 }, focusedField === "headers" ? "\u25B6 " : " ", "Headers (one per line, Key: Value):")), /* @__PURE__ */ React28.createElement(Box23, { marginLeft: 2, width: 60 }, focusedField === "headers" ? /* @__PURE__ */ React28.createElement(
9372
+ ) : /* @__PURE__ */ React22.createElement(Text19, { dimColor: !url }, url || "(empty)"))),
9373
+ /* @__PURE__ */ React22.createElement(Box18, { marginBottom: 1 }, /* @__PURE__ */ React22.createElement(Box18, { width: 20 }, /* @__PURE__ */ React22.createElement(Text19, { color: focusedField === "method" ? "green" : void 0 }, focusedField === "method" ? "\u25B6 " : " ", "Method:")), /* @__PURE__ */ React22.createElement(Text19, { bold: true, color: focusedField === "method" ? "yellow" : void 0 }, method), focusedField === "method" && /* @__PURE__ */ React22.createElement(Text19, { dimColor: true }, " (\u2190 \u2192 to change)")),
9374
+ /* @__PURE__ */ React22.createElement(Box18, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React22.createElement(Box18, { marginBottom: 0 }, /* @__PURE__ */ React22.createElement(Text19, { color: focusedField === "headers" ? "green" : void 0 }, focusedField === "headers" ? "\u25B6 " : " ", "Headers (one per line, Key: Value):")), /* @__PURE__ */ React22.createElement(Box18, { marginLeft: 2, width: 60 }, focusedField === "headers" ? /* @__PURE__ */ React22.createElement(
9776
9375
  TextInput13,
9777
9376
  {
9778
9377
  value: headers,
9779
9378
  onChange: setHeaders,
9780
9379
  placeholder: "Authorization: Bearer token"
9781
9380
  }
9782
- ) : /* @__PURE__ */ React28.createElement(Text24, { dimColor: !headers }, headers || "(none)"))),
9783
- (method === "POST" || method === "PUT" || method === "PATCH") && /* @__PURE__ */ React28.createElement(Box23, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React28.createElement(Box23, { marginBottom: 0 }, /* @__PURE__ */ React28.createElement(Text24, { color: focusedField === "body" ? "green" : void 0 }, focusedField === "body" ? "\u25B6 " : " ", "Body (JSON):")), /* @__PURE__ */ React28.createElement(Box23, { marginLeft: 2, width: 60 }, focusedField === "body" ? /* @__PURE__ */ React28.createElement(
9381
+ ) : /* @__PURE__ */ React22.createElement(Text19, { dimColor: !headers }, headers || "(none)"))),
9382
+ (method === "POST" || method === "PUT" || method === "PATCH") && /* @__PURE__ */ React22.createElement(Box18, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React22.createElement(Box18, { marginBottom: 0 }, /* @__PURE__ */ React22.createElement(Text19, { color: focusedField === "body" ? "green" : void 0 }, focusedField === "body" ? "\u25B6 " : " ", "Body (JSON):")), /* @__PURE__ */ React22.createElement(Box18, { marginLeft: 2, width: 60 }, focusedField === "body" ? /* @__PURE__ */ React22.createElement(
9784
9383
  TextInput13,
9785
9384
  {
9786
9385
  value: body,
9787
9386
  onChange: setBody,
9788
9387
  placeholder: '{"key":"value"}'
9789
9388
  }
9790
- ) : /* @__PURE__ */ React28.createElement(Text24, { dimColor: !body }, body || "(empty)"))),
9791
- /* @__PURE__ */ React28.createElement(Box23, { marginTop: 1 }, /* @__PURE__ */ React28.createElement(
9792
- Text24,
9389
+ ) : /* @__PURE__ */ React22.createElement(Text19, { dimColor: !body }, body || "(empty)"))),
9390
+ /* @__PURE__ */ React22.createElement(Box18, { marginTop: 1 }, /* @__PURE__ */ React22.createElement(
9391
+ Text19,
9793
9392
  {
9794
9393
  bold: true,
9795
9394
  backgroundColor: focusedField === "send" ? "green" : void 0,
@@ -9800,8 +9399,8 @@ var HttpView = () => {
9800
9399
  loading ? "Sending..." : "Send Request",
9801
9400
  " ]"
9802
9401
  ))
9803
- ), error && /* @__PURE__ */ React28.createElement(
9804
- Box23,
9402
+ ), error && /* @__PURE__ */ React22.createElement(
9403
+ Box18,
9805
9404
  {
9806
9405
  flexDirection: "column",
9807
9406
  borderStyle: "single",
@@ -9810,9 +9409,9 @@ var HttpView = () => {
9810
9409
  paddingY: 1,
9811
9410
  marginBottom: 1
9812
9411
  },
9813
- /* @__PURE__ */ React28.createElement(Text24, { color: "red" }, "\u2717 Error: ", error)
9814
- ), response && /* @__PURE__ */ React28.createElement(
9815
- Box23,
9412
+ /* @__PURE__ */ React22.createElement(Text19, { color: "red" }, "\u2717 Error: ", error)
9413
+ ), response && /* @__PURE__ */ React22.createElement(
9414
+ Box18,
9816
9415
  {
9817
9416
  flexDirection: "column",
9818
9417
  borderStyle: "single",
@@ -9820,23 +9419,23 @@ var HttpView = () => {
9820
9419
  paddingX: 2,
9821
9420
  paddingY: 1
9822
9421
  },
9823
- /* @__PURE__ */ React28.createElement(Box23, { marginBottom: 1 }, /* @__PURE__ */ React28.createElement(Text24, { bold: true, color: "green" }, "\u2713 Response:"), copied && /* @__PURE__ */ React28.createElement(Box23, { marginLeft: 2 }, /* @__PURE__ */ React28.createElement(Text24, { color: "green" }, "\u2713 Copied body to clipboard!"))),
9824
- /* @__PURE__ */ React28.createElement(Box23, { flexDirection: "column" }, /* @__PURE__ */ React28.createElement(Text24, null, "Status: ", /* @__PURE__ */ React28.createElement(Text24, { color: response.status < 400 ? "green" : "red" }, response.status)), /* @__PURE__ */ React28.createElement(Text24, null, "Time: ", response.time, "ms"), /* @__PURE__ */ React28.createElement(Text24, null, "Size: ", response.size), /* @__PURE__ */ React28.createElement(Text24, null, " "), /* @__PURE__ */ React28.createElement(Text24, { bold: true, color: "yellow" }, "Headers:"), Object.entries(response.headers).slice(0, 5).map(([key, value]) => /* @__PURE__ */ React28.createElement(Text24, { key, dimColor: true }, " ", key, ": ", value)), /* @__PURE__ */ React28.createElement(Text24, null, " "), /* @__PURE__ */ React28.createElement(Text24, { bold: true, color: "yellow" }, "Body:"), /* @__PURE__ */ React28.createElement(Text24, null, typeof response.body === "string" ? response.body.slice(0, 500) : JSON.stringify(response.body, null, 2).slice(0, 500)))
9825
- ), /* @__PURE__ */ React28.createElement(Box23, { marginTop: 1, borderStyle: "single", borderColor: "gray", paddingX: 2 }, /* @__PURE__ */ React28.createElement(Text24, { dimColor: true }, "Tab: Next | \u2190/\u2192: Change method | Enter: Send | C: Copy body | Esc: Back")));
9422
+ /* @__PURE__ */ React22.createElement(Box18, { marginBottom: 1 }, /* @__PURE__ */ React22.createElement(Text19, { bold: true, color: "green" }, "\u2713 Response:"), copied && /* @__PURE__ */ React22.createElement(Box18, { marginLeft: 2 }, /* @__PURE__ */ React22.createElement(Text19, { color: "green" }, "\u2713 Copied body to clipboard!"))),
9423
+ /* @__PURE__ */ React22.createElement(Box18, { flexDirection: "column" }, /* @__PURE__ */ React22.createElement(Text19, null, "Status: ", /* @__PURE__ */ React22.createElement(Text19, { color: response.status < 400 ? "green" : "red" }, response.status)), /* @__PURE__ */ React22.createElement(Text19, null, "Time: ", response.time, "ms"), /* @__PURE__ */ React22.createElement(Text19, null, "Size: ", response.size), /* @__PURE__ */ React22.createElement(Text19, null, " "), /* @__PURE__ */ React22.createElement(Text19, { bold: true, color: "yellow" }, "Headers:"), Object.entries(response.headers).slice(0, 5).map(([key, value]) => /* @__PURE__ */ React22.createElement(Text19, { key, dimColor: true }, " ", key, ": ", value)), /* @__PURE__ */ React22.createElement(Text19, null, " "), /* @__PURE__ */ React22.createElement(Text19, { bold: true, color: "yellow" }, "Body:"), /* @__PURE__ */ React22.createElement(Text19, null, typeof response.body === "string" ? response.body.slice(0, 500) : JSON.stringify(response.body, null, 2).slice(0, 500)))
9424
+ ), /* @__PURE__ */ React22.createElement(Box18, { marginTop: 1, borderStyle: "single", borderColor: "gray", paddingX: 2 }, /* @__PURE__ */ React22.createElement(Text19, { dimColor: true }, "Tab: Next | \u2190/\u2192: Change method | Enter: Send | C: Copy body | Esc: Back")));
9826
9425
  };
9827
9426
 
9828
9427
  // src/ui/utils/views/MarkdownView.tsx
9829
- import React29, { useState as useState22 } from "react";
9830
- import { Box as Box24, Text as Text25, useInput as useInput20 } from "ink";
9428
+ import React23, { useState as useState17 } from "react";
9429
+ import { Box as Box19, Text as Text20, useInput as useInput15 } from "ink";
9831
9430
  import TextInput14 from "ink-text-input";
9832
9431
  import * as fs15 from "fs";
9833
9432
  import * as path7 from "path";
9834
9433
  var MarkdownView = () => {
9835
- const [filePath, setFilePath] = useState22("");
9836
- const [content, setContent] = useState22("");
9837
- const [error, setError] = useState22("");
9838
- const [focusedField, setFocusedField] = useState22("file");
9839
- useInput20((input5, key) => {
9434
+ const [filePath, setFilePath] = useState17("");
9435
+ const [content, setContent] = useState17("");
9436
+ const [error, setError] = useState17("");
9437
+ const [focusedField, setFocusedField] = useState17("file");
9438
+ useInput15((input5, key) => {
9840
9439
  if (key.tab) {
9841
9440
  setFocusedField(focusedField === "file" ? "preview" : "file");
9842
9441
  } else if (key.return) {
@@ -9877,8 +9476,8 @@ ${code.trim()}
9877
9476
  setContent("");
9878
9477
  }
9879
9478
  };
9880
- return /* @__PURE__ */ React29.createElement(Box24, { flexDirection: "column" }, /* @__PURE__ */ React29.createElement(Box24, { marginBottom: 1 }, /* @__PURE__ */ React29.createElement(Text25, { bold: true, color: "cyan" }, "\u{1F4C4} Markdown Preview")), /* @__PURE__ */ React29.createElement(
9881
- Box24,
9479
+ return /* @__PURE__ */ React23.createElement(Box19, { flexDirection: "column" }, /* @__PURE__ */ React23.createElement(Box19, { marginBottom: 1 }, /* @__PURE__ */ React23.createElement(Text20, { bold: true, color: "cyan" }, "\u{1F4C4} Markdown Preview")), /* @__PURE__ */ React23.createElement(
9480
+ Box19,
9882
9481
  {
9883
9482
  flexDirection: "column",
9884
9483
  borderStyle: "single",
@@ -9887,17 +9486,17 @@ ${code.trim()}
9887
9486
  paddingY: 1,
9888
9487
  marginBottom: 1
9889
9488
  },
9890
- /* @__PURE__ */ React29.createElement(Text25, { bold: true, color: "yellow", marginBottom: 1 }, "Options:"),
9891
- /* @__PURE__ */ React29.createElement(Box24, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React29.createElement(Box24, { marginBottom: 0 }, /* @__PURE__ */ React29.createElement(Text25, { color: focusedField === "file" ? "green" : void 0 }, focusedField === "file" ? "\u25B6 " : " ", "File path:")), /* @__PURE__ */ React29.createElement(Box24, { marginLeft: 2, width: 60 }, focusedField === "file" ? /* @__PURE__ */ React29.createElement(
9489
+ /* @__PURE__ */ React23.createElement(Text20, { bold: true, color: "yellow", marginBottom: 1 }, "Options:"),
9490
+ /* @__PURE__ */ React23.createElement(Box19, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React23.createElement(Box19, { marginBottom: 0 }, /* @__PURE__ */ React23.createElement(Text20, { color: focusedField === "file" ? "green" : void 0 }, focusedField === "file" ? "\u25B6 " : " ", "File path:")), /* @__PURE__ */ React23.createElement(Box19, { marginLeft: 2, width: 60 }, focusedField === "file" ? /* @__PURE__ */ React23.createElement(
9892
9491
  TextInput14,
9893
9492
  {
9894
9493
  value: filePath,
9895
9494
  onChange: setFilePath,
9896
9495
  placeholder: "./README.md or /path/to/file.md"
9897
9496
  }
9898
- ) : /* @__PURE__ */ React29.createElement(Text25, { dimColor: !filePath }, filePath || "(empty)"))),
9899
- /* @__PURE__ */ React29.createElement(Box24, { marginTop: 1 }, /* @__PURE__ */ React29.createElement(
9900
- Text25,
9497
+ ) : /* @__PURE__ */ React23.createElement(Text20, { dimColor: !filePath }, filePath || "(empty)"))),
9498
+ /* @__PURE__ */ React23.createElement(Box19, { marginTop: 1 }, /* @__PURE__ */ React23.createElement(
9499
+ Text20,
9901
9500
  {
9902
9501
  bold: true,
9903
9502
  backgroundColor: focusedField === "preview" ? "green" : void 0,
@@ -9906,8 +9505,8 @@ ${code.trim()}
9906
9505
  focusedField === "preview" ? "\u25B6 " : " ",
9907
9506
  "[ Preview File ]"
9908
9507
  ))
9909
- ), error && /* @__PURE__ */ React29.createElement(
9910
- Box24,
9508
+ ), error && /* @__PURE__ */ React23.createElement(
9509
+ Box19,
9911
9510
  {
9912
9511
  flexDirection: "column",
9913
9512
  borderStyle: "single",
@@ -9916,9 +9515,9 @@ ${code.trim()}
9916
9515
  paddingY: 1,
9917
9516
  marginBottom: 1
9918
9517
  },
9919
- /* @__PURE__ */ React29.createElement(Text25, { color: "red" }, "\u2717 Error: ", error)
9920
- ), content && /* @__PURE__ */ React29.createElement(
9921
- Box24,
9518
+ /* @__PURE__ */ React23.createElement(Text20, { color: "red" }, "\u2717 Error: ", error)
9519
+ ), content && /* @__PURE__ */ React23.createElement(
9520
+ Box19,
9922
9521
  {
9923
9522
  flexDirection: "column",
9924
9523
  borderStyle: "single",
@@ -9926,9 +9525,9 @@ ${code.trim()}
9926
9525
  paddingX: 2,
9927
9526
  paddingY: 1
9928
9527
  },
9929
- /* @__PURE__ */ React29.createElement(Box24, { marginBottom: 1 }, /* @__PURE__ */ React29.createElement(Text25, { bold: true, color: "green" }, "\u2713 Preview:")),
9930
- /* @__PURE__ */ React29.createElement(Box24, { flexDirection: "column" }, /* @__PURE__ */ React29.createElement(Text25, null, content))
9931
- ), /* @__PURE__ */ React29.createElement(Box24, { marginTop: 1, borderStyle: "single", borderColor: "gray", paddingX: 2 }, /* @__PURE__ */ React29.createElement(Text25, { dimColor: true }, "Tab: Next | Enter: Preview | Esc: Back")));
9528
+ /* @__PURE__ */ React23.createElement(Box19, { marginBottom: 1 }, /* @__PURE__ */ React23.createElement(Text20, { bold: true, color: "green" }, "\u2713 Preview:")),
9529
+ /* @__PURE__ */ React23.createElement(Box19, { flexDirection: "column" }, /* @__PURE__ */ React23.createElement(Text20, null, content))
9530
+ ), /* @__PURE__ */ React23.createElement(Box19, { marginTop: 1, borderStyle: "single", borderColor: "gray", paddingX: 2 }, /* @__PURE__ */ React23.createElement(Text20, { dimColor: true }, "Tab: Next | Enter: Preview | Esc: Back")));
9932
9531
  };
9933
9532
 
9934
9533
  // src/ui/utils/UtilsApp.tsx
@@ -9948,10 +9547,10 @@ var MENU_ITEMS = [
9948
9547
  { id: "markdown", icon: "\u{1F4C4}", label: "Markdown", description: "Preview markdown" }
9949
9548
  ];
9950
9549
  var UtilsApp = ({ onExit }) => {
9951
- const [selectedIndex, setSelectedIndex] = useState23(0);
9952
- const [activeView, setActiveView] = useState23(null);
9953
- const { exit } = useApp5();
9954
- useInput21((input5, key) => {
9550
+ const [selectedIndex, setSelectedIndex] = useState18(0);
9551
+ const [activeView, setActiveView] = useState18(null);
9552
+ const { exit } = useApp4();
9553
+ useInput16((input5, key) => {
9955
9554
  if (activeView) {
9956
9555
  if (key.escape) {
9957
9556
  setActiveView(null);
@@ -9969,8 +9568,8 @@ var UtilsApp = ({ onExit }) => {
9969
9568
  exit();
9970
9569
  }
9971
9570
  });
9972
- return /* @__PURE__ */ React30.createElement(Box25, { flexDirection: "column", width: "100%", height: "100%" }, /* @__PURE__ */ React30.createElement(
9973
- Box25,
9571
+ return /* @__PURE__ */ React24.createElement(Box20, { flexDirection: "column", width: "100%", height: "100%" }, /* @__PURE__ */ React24.createElement(
9572
+ Box20,
9974
9573
  {
9975
9574
  borderStyle: "single",
9976
9575
  borderColor: "cyan",
@@ -9978,10 +9577,10 @@ var UtilsApp = ({ onExit }) => {
9978
9577
  paddingY: 0,
9979
9578
  marginBottom: 1
9980
9579
  },
9981
- /* @__PURE__ */ React30.createElement(Text26, { bold: true, color: "cyan" }, "\u{1F6E0}\uFE0F Developer Utilities - Interactive Mode"),
9982
- /* @__PURE__ */ React30.createElement(Box25, { marginLeft: "auto" }, /* @__PURE__ */ React30.createElement(Text26, { dimColor: true }, "Press Ctrl+Q to quit"))
9983
- ), /* @__PURE__ */ React30.createElement(Box25, { flexGrow: 1 }, /* @__PURE__ */ React30.createElement(
9984
- Box25,
9580
+ /* @__PURE__ */ React24.createElement(Text21, { bold: true, color: "cyan" }, "\u{1F6E0}\uFE0F Developer Utilities - Interactive Mode"),
9581
+ /* @__PURE__ */ React24.createElement(Box20, { marginLeft: "auto" }, /* @__PURE__ */ React24.createElement(Text21, { dimColor: true }, "Press Ctrl+Q to quit"))
9582
+ ), /* @__PURE__ */ React24.createElement(Box20, { flexGrow: 1 }, /* @__PURE__ */ React24.createElement(
9583
+ Box20,
9985
9584
  {
9986
9585
  flexDirection: "column",
9987
9586
  width: 30,
@@ -9991,9 +9590,9 @@ var UtilsApp = ({ onExit }) => {
9991
9590
  paddingY: 1,
9992
9591
  marginRight: 1
9993
9592
  },
9994
- /* @__PURE__ */ React30.createElement(Box25, { marginBottom: 1 }, /* @__PURE__ */ React30.createElement(Text26, { bold: true, color: "yellow" }, "Select Utility:")),
9995
- MENU_ITEMS.map((item, index) => /* @__PURE__ */ React30.createElement(Box25, { key: item.id, marginBottom: 0 }, /* @__PURE__ */ React30.createElement(
9996
- Text26,
9593
+ /* @__PURE__ */ React24.createElement(Box20, { marginBottom: 1 }, /* @__PURE__ */ React24.createElement(Text21, { bold: true, color: "yellow" }, "Select Utility:")),
9594
+ MENU_ITEMS.map((item, index) => /* @__PURE__ */ React24.createElement(Box20, { key: item.id, marginBottom: 0 }, /* @__PURE__ */ React24.createElement(
9595
+ Text21,
9997
9596
  {
9998
9597
  color: selectedIndex === index && !activeView ? "green" : void 0,
9999
9598
  bold: selectedIndex === index && !activeView,
@@ -10004,9 +9603,9 @@ var UtilsApp = ({ onExit }) => {
10004
9603
  " ",
10005
9604
  item.label
10006
9605
  ))),
10007
- /* @__PURE__ */ React30.createElement(Box25, { marginTop: 1, borderStyle: "single", borderColor: "gray", paddingX: 1 }, /* @__PURE__ */ React30.createElement(Text26, { dimColor: true }, "\u2191/\u2193: Navigate", "\n", "Enter: Select", "\n", "Esc: Back/Quit"))
10008
- ), /* @__PURE__ */ React30.createElement(
10009
- Box25,
9606
+ /* @__PURE__ */ React24.createElement(Box20, { marginTop: 1, borderStyle: "single", borderColor: "gray", paddingX: 1 }, /* @__PURE__ */ React24.createElement(Text21, { dimColor: true }, "\u2191/\u2193: Navigate", "\n", "Enter: Select", "\n", "Esc: Back/Quit"))
9607
+ ), /* @__PURE__ */ React24.createElement(
9608
+ Box20,
10010
9609
  {
10011
9610
  flexDirection: "column",
10012
9611
  flexGrow: 1,
@@ -10015,21 +9614,21 @@ var UtilsApp = ({ onExit }) => {
10015
9614
  paddingX: 2,
10016
9615
  paddingY: 1
10017
9616
  },
10018
- activeView ? /* @__PURE__ */ React30.createElement(ActiveUtilityView, { utilityType: activeView }) : /* @__PURE__ */ React30.createElement(WelcomeView, { selectedItem: MENU_ITEMS[selectedIndex] })
10019
- )), /* @__PURE__ */ React30.createElement(
10020
- Box25,
9617
+ activeView ? /* @__PURE__ */ React24.createElement(ActiveUtilityView, { utilityType: activeView }) : /* @__PURE__ */ React24.createElement(WelcomeView, { selectedItem: MENU_ITEMS[selectedIndex] })
9618
+ )), /* @__PURE__ */ React24.createElement(
9619
+ Box20,
10021
9620
  {
10022
9621
  borderStyle: "single",
10023
9622
  borderColor: "gray",
10024
9623
  paddingX: 2,
10025
9624
  marginTop: 1
10026
9625
  },
10027
- /* @__PURE__ */ React30.createElement(Text26, { dimColor: true }, "jai1-cli | Use arrow keys or j/k to navigate")
9626
+ /* @__PURE__ */ React24.createElement(Text21, { dimColor: true }, "jai1-cli | Use arrow keys or j/k to navigate")
10028
9627
  ));
10029
9628
  };
10030
9629
  var WelcomeView = ({ selectedItem }) => {
10031
- return /* @__PURE__ */ React30.createElement(Box25, { flexDirection: "column" }, /* @__PURE__ */ React30.createElement(Box25, { marginBottom: 1 }, /* @__PURE__ */ React30.createElement(Text26, { bold: true, color: "cyan" }, "Welcome to Developer Utilities")), /* @__PURE__ */ React30.createElement(Box25, { marginBottom: 2 }, /* @__PURE__ */ React30.createElement(Text26, null, "Select a utility from the left menu to get started.")), /* @__PURE__ */ React30.createElement(
10032
- Box25,
9630
+ return /* @__PURE__ */ React24.createElement(Box20, { flexDirection: "column" }, /* @__PURE__ */ React24.createElement(Box20, { marginBottom: 1 }, /* @__PURE__ */ React24.createElement(Text21, { bold: true, color: "cyan" }, "Welcome to Developer Utilities")), /* @__PURE__ */ React24.createElement(Box20, { marginBottom: 2 }, /* @__PURE__ */ React24.createElement(Text21, null, "Select a utility from the left menu to get started.")), /* @__PURE__ */ React24.createElement(
9631
+ Box20,
10033
9632
  {
10034
9633
  borderStyle: "single",
10035
9634
  borderColor: "yellow",
@@ -10037,49 +9636,49 @@ var WelcomeView = ({ selectedItem }) => {
10037
9636
  paddingY: 1,
10038
9637
  marginBottom: 2
10039
9638
  },
10040
- /* @__PURE__ */ React30.createElement(Box25, { flexDirection: "column" }, /* @__PURE__ */ React30.createElement(Text26, { bold: true, color: "yellow" }, selectedItem.icon, " ", selectedItem.label), /* @__PURE__ */ React30.createElement(Text26, { dimColor: true }, selectedItem.description))
10041
- ), /* @__PURE__ */ React30.createElement(Box25, { marginBottom: 1 }, /* @__PURE__ */ React30.createElement(Text26, { bold: true }, "Quick Actions:")), /* @__PURE__ */ React30.createElement(Box25, { flexDirection: "column", marginLeft: 2 }, /* @__PURE__ */ React30.createElement(Text26, null, "\u2022 Press ", /* @__PURE__ */ React30.createElement(Text26, { color: "green" }, "Enter"), " to open selected utility"), /* @__PURE__ */ React30.createElement(Text26, null, "\u2022 Use ", /* @__PURE__ */ React30.createElement(Text26, { color: "green" }, "\u2191/\u2193"), " or ", /* @__PURE__ */ React30.createElement(Text26, { color: "green" }, "j/k"), " to navigate"), /* @__PURE__ */ React30.createElement(Text26, null, "\u2022 Press ", /* @__PURE__ */ React30.createElement(Text26, { color: "green" }, "Esc"), " to go back or quit"), /* @__PURE__ */ React30.createElement(Text26, null, "\u2022 Press ", /* @__PURE__ */ React30.createElement(Text26, { color: "green" }, "Ctrl+Q"), " to quit anytime")), /* @__PURE__ */ React30.createElement(Box25, { marginTop: 2 }, /* @__PURE__ */ React30.createElement(Text26, { dimColor: true }, "\u{1F4A1} Tip: Each utility provides an interactive interface for easy usage.")));
9639
+ /* @__PURE__ */ React24.createElement(Box20, { flexDirection: "column" }, /* @__PURE__ */ React24.createElement(Text21, { bold: true, color: "yellow" }, selectedItem.icon, " ", selectedItem.label), /* @__PURE__ */ React24.createElement(Text21, { dimColor: true }, selectedItem.description))
9640
+ ), /* @__PURE__ */ React24.createElement(Box20, { marginBottom: 1 }, /* @__PURE__ */ React24.createElement(Text21, { bold: true }, "Quick Actions:")), /* @__PURE__ */ React24.createElement(Box20, { flexDirection: "column", marginLeft: 2 }, /* @__PURE__ */ React24.createElement(Text21, null, "\u2022 Press ", /* @__PURE__ */ React24.createElement(Text21, { color: "green" }, "Enter"), " to open selected utility"), /* @__PURE__ */ React24.createElement(Text21, null, "\u2022 Use ", /* @__PURE__ */ React24.createElement(Text21, { color: "green" }, "\u2191/\u2193"), " or ", /* @__PURE__ */ React24.createElement(Text21, { color: "green" }, "j/k"), " to navigate"), /* @__PURE__ */ React24.createElement(Text21, null, "\u2022 Press ", /* @__PURE__ */ React24.createElement(Text21, { color: "green" }, "Esc"), " to go back or quit"), /* @__PURE__ */ React24.createElement(Text21, null, "\u2022 Press ", /* @__PURE__ */ React24.createElement(Text21, { color: "green" }, "Ctrl+Q"), " to quit anytime")), /* @__PURE__ */ React24.createElement(Box20, { marginTop: 2 }, /* @__PURE__ */ React24.createElement(Text21, { dimColor: true }, "\u{1F4A1} Tip: Each utility provides an interactive interface for easy usage.")));
10042
9641
  };
10043
9642
  var ActiveUtilityView = ({ utilityType }) => {
10044
9643
  switch (utilityType) {
10045
9644
  case "password":
10046
- return /* @__PURE__ */ React30.createElement(PasswordView, null);
9645
+ return /* @__PURE__ */ React24.createElement(PasswordView, null);
10047
9646
  case "uuid":
10048
- return /* @__PURE__ */ React30.createElement(UuidView, null);
9647
+ return /* @__PURE__ */ React24.createElement(UuidView, null);
10049
9648
  case "hash":
10050
- return /* @__PURE__ */ React30.createElement(HashView, null);
9649
+ return /* @__PURE__ */ React24.createElement(HashView, null);
10051
9650
  case "base64-encode":
10052
9651
  case "base64-decode":
10053
- return /* @__PURE__ */ React30.createElement(Base64View, null);
9652
+ return /* @__PURE__ */ React24.createElement(Base64View, null);
10054
9653
  case "url-encode":
10055
9654
  case "url-decode":
10056
- return /* @__PURE__ */ React30.createElement(UrlView, null);
9655
+ return /* @__PURE__ */ React24.createElement(UrlView, null);
10057
9656
  case "unix-time":
10058
- return /* @__PURE__ */ React30.createElement(UnixTimeView, null);
9657
+ return /* @__PURE__ */ React24.createElement(UnixTimeView, null);
10059
9658
  case "jwt":
10060
- return /* @__PURE__ */ React30.createElement(JwtView, null);
9659
+ return /* @__PURE__ */ React24.createElement(JwtView, null);
10061
9660
  case "cron":
10062
- return /* @__PURE__ */ React30.createElement(CronView, null);
9661
+ return /* @__PURE__ */ React24.createElement(CronView, null);
10063
9662
  case "timezone":
10064
- return /* @__PURE__ */ React30.createElement(TimezoneView, null);
9663
+ return /* @__PURE__ */ React24.createElement(TimezoneView, null);
10065
9664
  case "http":
10066
- return /* @__PURE__ */ React30.createElement(HttpView, null);
9665
+ return /* @__PURE__ */ React24.createElement(HttpView, null);
10067
9666
  case "markdown":
10068
- return /* @__PURE__ */ React30.createElement(MarkdownView, null);
9667
+ return /* @__PURE__ */ React24.createElement(MarkdownView, null);
10069
9668
  default:
10070
- return /* @__PURE__ */ React30.createElement(PlaceholderView, { utilityType });
9669
+ return /* @__PURE__ */ React24.createElement(PlaceholderView, { utilityType });
10071
9670
  }
10072
9671
  };
10073
9672
  var PlaceholderView = ({ utilityType }) => {
10074
9673
  const item = MENU_ITEMS.find((m) => m.id === utilityType);
10075
- return /* @__PURE__ */ React30.createElement(Box25, { flexDirection: "column" }, /* @__PURE__ */ React30.createElement(Box25, { marginBottom: 1 }, /* @__PURE__ */ React30.createElement(Text26, { bold: true, color: "cyan" }, item?.icon, " ", item?.label)), /* @__PURE__ */ React30.createElement(Box25, { borderStyle: "single", borderColor: "yellow", paddingX: 2, paddingY: 1 }, /* @__PURE__ */ React30.createElement(Text26, null, "\u{1F6A7} This utility view is under construction.", "\n", "\n", "For now, use the command-line version:", "\n", /* @__PURE__ */ React30.createElement(Text26, { color: "green" }, "$ jai1 utils ", utilityType, " --help"), "\n", "\n", "Press ", /* @__PURE__ */ React30.createElement(Text26, { color: "yellow" }, "Esc"), " to return to the menu.")));
9674
+ return /* @__PURE__ */ React24.createElement(Box20, { flexDirection: "column" }, /* @__PURE__ */ React24.createElement(Box20, { marginBottom: 1 }, /* @__PURE__ */ React24.createElement(Text21, { bold: true, color: "cyan" }, item?.icon, " ", item?.label)), /* @__PURE__ */ React24.createElement(Box20, { borderStyle: "single", borderColor: "yellow", paddingX: 2, paddingY: 1 }, /* @__PURE__ */ React24.createElement(Text21, null, "\u{1F6A7} This utility view is under construction.", "\n", "\n", "For now, use the command-line version:", "\n", /* @__PURE__ */ React24.createElement(Text21, { color: "green" }, "$ jai1 utils ", utilityType, " --help"), "\n", "\n", "Press ", /* @__PURE__ */ React24.createElement(Text21, { color: "yellow" }, "Esc"), " to return to the menu.")));
10076
9675
  };
10077
9676
 
10078
9677
  // src/commands/utils/interactive.ts
10079
9678
  async function runInteractiveMode() {
10080
9679
  return new Promise((resolve4) => {
10081
- const { unmount, waitUntilExit } = render5(
10082
- React31.createElement(UtilsApp, {
9680
+ const { unmount, waitUntilExit } = render4(
9681
+ React25.createElement(UtilsApp, {
10083
9682
  onExit: () => {
10084
9683
  unmount();
10085
9684
  resolve4();
@@ -10094,40 +9693,40 @@ async function runInteractiveMode() {
10094
9693
 
10095
9694
  // src/commands/utils/index.ts
10096
9695
  function showUtilsHelp() {
10097
- console.log(chalk14.bold.cyan("\u{1F6E0}\uFE0F jai1 utils") + chalk14.dim(" - Developer utilities"));
9696
+ console.log(chalk15.bold.cyan("\u{1F6E0}\uFE0F jai1 utils") + chalk15.dim(" - Developer utilities"));
10098
9697
  console.log();
10099
- console.log(chalk14.bold("M\xE3 h\xF3a & B\u1EA3o m\u1EADt:"));
10100
- console.log(` ${chalk14.cyan("password")} T\u1EA1o m\u1EADt kh\u1EA9u ng\u1EABu nhi\xEAn`);
10101
- console.log(` ${chalk14.cyan("uuid")} T\u1EA1o UUID v4`);
10102
- console.log(` ${chalk14.cyan("hash")} Hash text (MD5/SHA/bcrypt)`);
10103
- console.log(` ${chalk14.cyan("jwt")} Decode/encode JWT tokens`);
9698
+ console.log(chalk15.bold("M\xE3 h\xF3a & B\u1EA3o m\u1EADt:"));
9699
+ console.log(` ${chalk15.cyan("password")} T\u1EA1o m\u1EADt kh\u1EA9u ng\u1EABu nhi\xEAn`);
9700
+ console.log(` ${chalk15.cyan("uuid")} T\u1EA1o UUID v4`);
9701
+ console.log(` ${chalk15.cyan("hash")} Hash text (MD5/SHA/bcrypt)`);
9702
+ console.log(` ${chalk15.cyan("jwt")} Decode/encode JWT tokens`);
10104
9703
  console.log();
10105
- console.log(chalk14.bold("Encoding:"));
10106
- console.log(` ${chalk14.cyan("base64-encode")} Encode sang Base64`);
10107
- console.log(` ${chalk14.cyan("base64-decode")} Decode t\u1EEB Base64`);
10108
- console.log(` ${chalk14.cyan("url-encode")} Encode URL components`);
10109
- console.log(` ${chalk14.cyan("url-decode")} Decode URL components`);
9704
+ console.log(chalk15.bold("Encoding:"));
9705
+ console.log(` ${chalk15.cyan("base64-encode")} Encode sang Base64`);
9706
+ console.log(` ${chalk15.cyan("base64-decode")} Decode t\u1EEB Base64`);
9707
+ console.log(` ${chalk15.cyan("url-encode")} Encode URL components`);
9708
+ console.log(` ${chalk15.cyan("url-decode")} Decode URL components`);
10110
9709
  console.log();
10111
- console.log(chalk14.bold("Th\u1EDDi gian:"));
10112
- console.log(` ${chalk14.cyan("unix-time")} Chuy\u1EC3n \u0111\u1ED5i unix timestamp`);
10113
- console.log(` ${chalk14.cyan("timezone")} Chuy\u1EC3n \u0111\u1ED5i m\xFAi gi\u1EDD`);
10114
- console.log(` ${chalk14.cyan("cron")} Parse cron expressions`);
9710
+ console.log(chalk15.bold("Th\u1EDDi gian:"));
9711
+ console.log(` ${chalk15.cyan("unix-time")} Chuy\u1EC3n \u0111\u1ED5i unix timestamp`);
9712
+ console.log(` ${chalk15.cyan("timezone")} Chuy\u1EC3n \u0111\u1ED5i m\xFAi gi\u1EDD`);
9713
+ console.log(` ${chalk15.cyan("cron")} Parse cron expressions`);
10115
9714
  console.log();
10116
- console.log(chalk14.bold("Kh\xE1c:"));
10117
- console.log(` ${chalk14.cyan("http")} G\u1EEDi HTTP requests`);
10118
- console.log(` ${chalk14.cyan("markdown-preview")} Xem tr\u01B0\u1EDBc file markdown`);
9715
+ console.log(chalk15.bold("Kh\xE1c:"));
9716
+ console.log(` ${chalk15.cyan("http")} G\u1EEDi HTTP requests`);
9717
+ console.log(` ${chalk15.cyan("markdown-preview")} Xem tr\u01B0\u1EDBc file markdown`);
10119
9718
  console.log();
10120
- console.log(chalk14.bold("Ch\u1EBF \u0111\u1ED9 Interactive:"));
10121
- console.log(chalk14.dim(" $ jai1 utils -i"));
10122
- console.log(chalk14.dim(" $ jai1 utils --interactive"));
9719
+ console.log(chalk15.bold("Ch\u1EBF \u0111\u1ED9 Interactive:"));
9720
+ console.log(chalk15.dim(" $ jai1 utils -i"));
9721
+ console.log(chalk15.dim(" $ jai1 utils --interactive"));
10123
9722
  console.log();
10124
- console.log(chalk14.bold("V\xED d\u1EE5:"));
10125
- console.log(chalk14.dim(" $ jai1 utils password --length 24"));
10126
- console.log(chalk14.dim(" $ jai1 utils uuid --count 5"));
10127
- console.log(chalk14.dim(' $ jai1 utils hash "text" --algorithm sha256'));
10128
- console.log(chalk14.dim(" $ jai1 utils http https://api.example.com"));
9723
+ console.log(chalk15.bold("V\xED d\u1EE5:"));
9724
+ console.log(chalk15.dim(" $ jai1 utils password --length 24"));
9725
+ console.log(chalk15.dim(" $ jai1 utils uuid --count 5"));
9726
+ console.log(chalk15.dim(' $ jai1 utils hash "text" --algorithm sha256'));
9727
+ console.log(chalk15.dim(" $ jai1 utils http https://api.example.com"));
10129
9728
  console.log();
10130
- console.log(chalk14.dim('Ch\u1EA1y "jai1 utils <l\u1EC7nh> --help" \u0111\u1EC3 xem chi ti\u1EBFt'));
9729
+ console.log(chalk15.dim('Ch\u1EA1y "jai1 utils <l\u1EC7nh> --help" \u0111\u1EC3 xem chi ti\u1EBFt'));
10131
9730
  }
10132
9731
  function createUtilsCommand() {
10133
9732
  const utilsCommand = new Command42("utils").description("Developer utilities for common tasks").option("-i, --interactive", "Run in interactive mode");
@@ -10156,11 +9755,11 @@ function createUtilsCommand() {
10156
9755
 
10157
9756
  // src/commands/deps/index.ts
10158
9757
  import { Command as Command45 } from "commander";
10159
- import chalk17 from "chalk";
9758
+ import chalk18 from "chalk";
10160
9759
 
10161
9760
  // src/commands/deps/check.ts
10162
9761
  import { Command as Command43 } from "commander";
10163
- import chalk15 from "chalk";
9762
+ import chalk16 from "chalk";
10164
9763
  import Table4 from "cli-table3";
10165
9764
  import ora from "ora";
10166
9765
 
@@ -10763,7 +10362,7 @@ function createDepsCheckCommand() {
10763
10362
  if (projects.length === 0) {
10764
10363
  spinner.fail("Kh\xF4ng t\xECm th\u1EA5y project n\xE0o \u0111\u01B0\u1EE3c h\u1ED7 tr\u1EE3");
10765
10364
  console.log();
10766
- console.log(chalk15.dim("H\u1ED7 tr\u1EE3: Node.js (package.json), PHP (composer.json), Python (requirements.txt/Pipfile)"));
10365
+ console.log(chalk16.dim("H\u1ED7 tr\u1EE3: Node.js (package.json), PHP (composer.json), Python (requirements.txt/Pipfile)"));
10767
10366
  process.exit(1);
10768
10367
  }
10769
10368
  spinner.succeed(`Ph\xE1t hi\u1EC7n ${projects.length} project:`);
@@ -10777,7 +10376,7 @@ function createDepsCheckCommand() {
10777
10376
  await checkEcosystem(project.ecosystem, project.manager, cwd);
10778
10377
  }
10779
10378
  console.log();
10780
- console.log(chalk15.dim('\u{1F4A1} Ch\u1EA1y "jai1 deps upgrade" \u0111\u1EC3 n\xE2ng c\u1EA5p packages.'));
10379
+ console.log(chalk16.dim('\u{1F4A1} Ch\u1EA1y "jai1 deps upgrade" \u0111\u1EC3 n\xE2ng c\u1EA5p packages.'));
10781
10380
  });
10782
10381
  return checkCommand;
10783
10382
  }
@@ -10810,7 +10409,7 @@ async function checkEcosystem(ecosystem, manager, cwd) {
10810
10409
  });
10811
10410
  } catch (error) {
10812
10411
  spinner.fail(`L\u1ED7i ki\u1EC3m tra ${label}`);
10813
- console.log(chalk15.red(error.message));
10412
+ console.log(chalk16.red(error.message));
10814
10413
  console.log();
10815
10414
  return;
10816
10415
  }
@@ -10823,10 +10422,10 @@ async function checkEcosystem(ecosystem, manager, cwd) {
10823
10422
  console.log();
10824
10423
  const table = new Table4({
10825
10424
  head: [
10826
- chalk15.cyan("Package"),
10827
- chalk15.cyan("Hi\u1EC7n t\u1EA1i"),
10828
- chalk15.cyan("M\u1EDBi nh\u1EA5t"),
10829
- chalk15.cyan("Lo\u1EA1i")
10425
+ chalk16.cyan("Package"),
10426
+ chalk16.cyan("Hi\u1EC7n t\u1EA1i"),
10427
+ chalk16.cyan("M\u1EDBi nh\u1EA5t"),
10428
+ chalk16.cyan("Lo\u1EA1i")
10830
10429
  ],
10831
10430
  style: {
10832
10431
  head: [],
@@ -10837,9 +10436,9 @@ async function checkEcosystem(ecosystem, manager, cwd) {
10837
10436
  const upgradeIcon = pkg.upgradeType === "major" ? "\u{1F534}" : pkg.upgradeType === "minor" ? "\u{1F7E1}" : "\u{1F7E2}";
10838
10437
  table.push([
10839
10438
  `${upgradeIcon} ${pkg.name}`,
10840
- chalk15.dim(pkg.current),
10841
- chalk15.green(pkg.latest),
10842
- pkg.type === "dev" ? chalk15.dim("dev") : "dep"
10439
+ chalk16.dim(pkg.current),
10440
+ chalk16.green(pkg.latest),
10441
+ pkg.type === "dev" ? chalk16.dim("dev") : "dep"
10843
10442
  ]);
10844
10443
  }
10845
10444
  console.log(table.toString());
@@ -10847,13 +10446,13 @@ async function checkEcosystem(ecosystem, manager, cwd) {
10847
10446
  if (result.isLaravel) {
10848
10447
  const blockedPackages = result.packages.filter((p) => p.blockedReason);
10849
10448
  if (blockedPackages.length > 0) {
10850
- console.log(chalk15.yellow("\u26A0\uFE0F Laravel major version upgrades blocked (nguy hi\u1EC3m):"));
10449
+ console.log(chalk16.yellow("\u26A0\uFE0F Laravel major version upgrades blocked (nguy hi\u1EC3m):"));
10851
10450
  for (const pkg of blockedPackages) {
10852
- console.log(chalk15.dim(` - ${pkg.name}: ${pkg.current} \u2192 ${pkg.latest}`));
10451
+ console.log(chalk16.dim(` - ${pkg.name}: ${pkg.current} \u2192 ${pkg.latest}`));
10853
10452
  }
10854
10453
  console.log();
10855
- console.log(chalk15.dim("\u{1F4A1} \u0110\u1EC3 n\xE2ng c\u1EA5p Laravel major version, ch\u1EA1y th\u1EE7 c\xF4ng:"));
10856
- console.log(chalk15.dim(` composer require ${blockedPackages[0].name}:^${blockedPackages[0].latest}`));
10454
+ console.log(chalk16.dim("\u{1F4A1} \u0110\u1EC3 n\xE2ng c\u1EA5p Laravel major version, ch\u1EA1y th\u1EE7 c\xF4ng:"));
10455
+ console.log(chalk16.dim(` composer require ${blockedPackages[0].name}:^${blockedPackages[0].latest}`));
10857
10456
  console.log();
10858
10457
  }
10859
10458
  }
@@ -10862,7 +10461,7 @@ async function checkEcosystem(ecosystem, manager, cwd) {
10862
10461
  // src/commands/deps/upgrade.ts
10863
10462
  import { Command as Command44 } from "commander";
10864
10463
  import { checkbox as checkbox3, confirm as confirm8 } from "@inquirer/prompts";
10865
- import chalk16 from "chalk";
10464
+ import chalk17 from "chalk";
10866
10465
  import ora2 from "ora";
10867
10466
  import Table5 from "cli-table3";
10868
10467
  function createDepsUpgradeCommand() {
@@ -10879,7 +10478,7 @@ async function handleDepsUpgrade(options) {
10879
10478
  if (projects.length === 0) {
10880
10479
  spinner.fail("Kh\xF4ng t\xECm th\u1EA5y project n\xE0o \u0111\u01B0\u1EE3c h\u1ED7 tr\u1EE3");
10881
10480
  console.log();
10882
- console.log(chalk16.dim("H\u1ED7 tr\u1EE3: Node.js (package.json), PHP (composer.json), Python (requirements.txt/Pipfile)"));
10481
+ console.log(chalk17.dim("H\u1ED7 tr\u1EE3: Node.js (package.json), PHP (composer.json), Python (requirements.txt/Pipfile)"));
10883
10482
  process.exit(1);
10884
10483
  }
10885
10484
  spinner.succeed(`Ph\xE1t hi\u1EC7n ${projects.length} project:`);
@@ -10893,9 +10492,9 @@ async function handleDepsUpgrade(options) {
10893
10492
  await upgradeEcosystem(project, cwd, options);
10894
10493
  }
10895
10494
  console.log();
10896
- console.log(chalk16.green("\u2705 Ho\xE0n th\xE0nh!"));
10495
+ console.log(chalk17.green("\u2705 Ho\xE0n th\xE0nh!"));
10897
10496
  } catch (error) {
10898
- console.error(chalk16.red(`
10497
+ console.error(chalk17.red(`
10899
10498
  \u274C ${error.message}
10900
10499
  `));
10901
10500
  process.exit(1);
@@ -10904,10 +10503,10 @@ async function handleDepsUpgrade(options) {
10904
10503
  async function upgradeEcosystem(project, cwd, options) {
10905
10504
  const service = getService(project.ecosystem);
10906
10505
  const label = `${getEcosystemIcon(project.ecosystem)} ${getEcosystemLabel(project.ecosystem)}`;
10907
- console.log(chalk16.bold.cyan(`
10506
+ console.log(chalk17.bold.cyan(`
10908
10507
  ${"\u2501".repeat(80)}`));
10909
- console.log(chalk16.bold.cyan(`${label}`));
10910
- console.log(chalk16.bold.cyan("\u2501".repeat(80)));
10508
+ console.log(chalk17.bold.cyan(`${label}`));
10509
+ console.log(chalk17.bold.cyan("\u2501".repeat(80)));
10911
10510
  console.log();
10912
10511
  const spinner = ora2("\u0110ang ki\u1EC3m tra packages...").start();
10913
10512
  let packages;
@@ -10918,7 +10517,7 @@ ${"\u2501".repeat(80)}`));
10918
10517
  packages = result.packages;
10919
10518
  } catch (error) {
10920
10519
  spinner.fail("L\u1ED7i ki\u1EC3m tra packages");
10921
- console.log(chalk16.red(error.message));
10520
+ console.log(chalk17.red(error.message));
10922
10521
  return;
10923
10522
  }
10924
10523
  if (packages.length === 0) {
@@ -10931,7 +10530,7 @@ ${"\u2501".repeat(80)}`));
10931
10530
  let selectedPackages;
10932
10531
  if (options.all) {
10933
10532
  selectedPackages = packages;
10934
- console.log(chalk16.cyan(`\u{1F4CB} \u0110\xE3 ch\u1ECDn t\u1EA5t c\u1EA3 ${selectedPackages.length} packages
10533
+ console.log(chalk17.cyan(`\u{1F4CB} \u0110\xE3 ch\u1ECDn t\u1EA5t c\u1EA3 ${selectedPackages.length} packages
10935
10534
  `));
10936
10535
  } else {
10937
10536
  try {
@@ -10949,12 +10548,12 @@ ${"\u2501".repeat(80)}`));
10949
10548
  theme: checkboxTheme
10950
10549
  });
10951
10550
  if (selected.length === 0) {
10952
- console.log(chalk16.yellow("\u23F8\uFE0F Kh\xF4ng c\xF3 packages n\xE0o \u0111\u01B0\u1EE3c ch\u1ECDn\n"));
10551
+ console.log(chalk17.yellow("\u23F8\uFE0F Kh\xF4ng c\xF3 packages n\xE0o \u0111\u01B0\u1EE3c ch\u1ECDn\n"));
10953
10552
  return;
10954
10553
  }
10955
10554
  selectedPackages = packages.filter((p) => selected.includes(p.name));
10956
10555
  } catch {
10957
- console.log(chalk16.yellow("\n\u23F8\uFE0F \u0110\xE3 h\u1EE7y\n"));
10556
+ console.log(chalk17.yellow("\n\u23F8\uFE0F \u0110\xE3 h\u1EE7y\n"));
10958
10557
  return;
10959
10558
  }
10960
10559
  }
@@ -10965,35 +10564,35 @@ ${"\u2501".repeat(80)}`));
10965
10564
  default: true
10966
10565
  });
10967
10566
  } catch {
10968
- console.log(chalk16.yellow("\n\u23F8\uFE0F \u0110\xE3 h\u1EE7y\n"));
10567
+ console.log(chalk17.yellow("\n\u23F8\uFE0F \u0110\xE3 h\u1EE7y\n"));
10969
10568
  return;
10970
10569
  }
10971
10570
  if (!shouldProceed) {
10972
- console.log(chalk16.yellow("\u23F8\uFE0F Upgrade \u0111\xE3 h\u1EE7y\n"));
10571
+ console.log(chalk17.yellow("\u23F8\uFE0F Upgrade \u0111\xE3 h\u1EE7y\n"));
10973
10572
  return;
10974
10573
  }
10975
10574
  console.log();
10976
- console.log(chalk16.cyan(`\u{1F527} Package manager: ${project.manager}`));
10977
- console.log(chalk16.cyan("\u{1F4E5} \u0110ang upgrade...\n"));
10575
+ console.log(chalk17.cyan(`\u{1F527} Package manager: ${project.manager}`));
10576
+ console.log(chalk17.cyan("\u{1F4E5} \u0110ang upgrade...\n"));
10978
10577
  const commands = service.getUpgradeCommands(selectedPackages);
10979
10578
  try {
10980
10579
  if (commands.deps) {
10981
- console.log(chalk16.dim(`$ ${commands.deps}
10580
+ console.log(chalk17.dim(`$ ${commands.deps}
10982
10581
  `));
10983
10582
  }
10984
10583
  if (commands.devDeps) {
10985
- console.log(chalk16.dim(`$ ${commands.devDeps}
10584
+ console.log(chalk17.dim(`$ ${commands.devDeps}
10986
10585
  `));
10987
10586
  }
10988
10587
  await service.upgrade(cwd, { packages: selectedPackages });
10989
- console.log(chalk16.green(`
10588
+ console.log(chalk17.green(`
10990
10589
  \u2705 \u0110\xE3 upgrade ${selectedPackages.length} packages th\xE0nh c\xF4ng!`));
10991
10590
  } catch (error) {
10992
- console.error(chalk16.red("\n\u274C L\u1ED7i khi upgrade:"));
10993
- console.error(chalk16.red(error.message));
10994
- console.log(chalk16.yellow("\n\u{1F4A1} B\u1EA1n c\xF3 th\u1EC3 th\u1EED upgrade th\u1EE7 c\xF4ng:"));
10995
- if (commands.deps) console.log(chalk16.cyan(` ${commands.deps}`));
10996
- if (commands.devDeps) console.log(chalk16.cyan(` ${commands.devDeps}`));
10591
+ console.error(chalk17.red("\n\u274C L\u1ED7i khi upgrade:"));
10592
+ console.error(chalk17.red(error.message));
10593
+ console.log(chalk17.yellow("\n\u{1F4A1} B\u1EA1n c\xF3 th\u1EC3 th\u1EED upgrade th\u1EE7 c\xF4ng:"));
10594
+ if (commands.deps) console.log(chalk17.cyan(` ${commands.deps}`));
10595
+ if (commands.devDeps) console.log(chalk17.cyan(` ${commands.devDeps}`));
10997
10596
  console.log();
10998
10597
  throw error;
10999
10598
  }
@@ -11001,10 +10600,10 @@ ${"\u2501".repeat(80)}`));
11001
10600
  function displayUpgradeTable(packages) {
11002
10601
  const table = new Table5({
11003
10602
  head: [
11004
- chalk16.cyan("Package"),
11005
- chalk16.cyan("Hi\u1EC7n t\u1EA1i"),
11006
- chalk16.cyan("M\u1EDBi nh\u1EA5t"),
11007
- chalk16.cyan("Lo\u1EA1i")
10603
+ chalk17.cyan("Package"),
10604
+ chalk17.cyan("Hi\u1EC7n t\u1EA1i"),
10605
+ chalk17.cyan("M\u1EDBi nh\u1EA5t"),
10606
+ chalk17.cyan("Lo\u1EA1i")
11008
10607
  ],
11009
10608
  style: {
11010
10609
  head: [],
@@ -11015,9 +10614,9 @@ function displayUpgradeTable(packages) {
11015
10614
  const upgradeIcon = pkg.upgradeType === "major" ? "\u{1F534}" : pkg.upgradeType === "minor" ? "\u{1F7E1}" : "\u{1F7E2}";
11016
10615
  table.push([
11017
10616
  `${upgradeIcon} ${pkg.name}`,
11018
- chalk16.dim(pkg.current),
11019
- chalk16.green(pkg.latest),
11020
- pkg.type === "dev" ? chalk16.dim("dev") : "dep"
10617
+ chalk17.dim(pkg.current),
10618
+ chalk17.green(pkg.latest),
10619
+ pkg.type === "dev" ? chalk17.dim("dev") : "dep"
11021
10620
  ]);
11022
10621
  }
11023
10622
  console.log(table.toString());
@@ -11060,23 +10659,23 @@ function getEcosystemLabel(ecosystem) {
11060
10659
 
11061
10660
  // src/commands/deps/index.ts
11062
10661
  function showDepsHelp() {
11063
- console.log(chalk17.bold.cyan("\u{1F4E6} jai1 deps") + chalk17.dim(" - Qu\u1EA3n l\xFD dependencies trong project"));
10662
+ console.log(chalk18.bold.cyan("\u{1F4E6} jai1 deps") + chalk18.dim(" - Qu\u1EA3n l\xFD dependencies trong project"));
11064
10663
  console.log();
11065
- console.log(chalk17.bold("C\xE1c l\u1EC7nh:"));
11066
- console.log(` ${chalk17.cyan("check")} Ki\u1EC3m tra c\xE1c packages c\u1EA7n upgrade`);
11067
- console.log(` ${chalk17.cyan("upgrade")} N\xE2ng c\u1EA5p dependencies l\xEAn phi\xEAn b\u1EA3n m\u1EDBi nh\u1EA5t`);
10664
+ console.log(chalk18.bold("C\xE1c l\u1EC7nh:"));
10665
+ console.log(` ${chalk18.cyan("check")} Ki\u1EC3m tra c\xE1c packages c\u1EA7n upgrade`);
10666
+ console.log(` ${chalk18.cyan("upgrade")} N\xE2ng c\u1EA5p dependencies l\xEAn phi\xEAn b\u1EA3n m\u1EDBi nh\u1EA5t`);
11068
10667
  console.log();
11069
- console.log(chalk17.bold("H\u1ED7 tr\u1EE3:"));
11070
- console.log(chalk17.dim(" \u2022 Node.js (npm, pnpm, yarn, bun)"));
11071
- console.log(chalk17.dim(" \u2022 PHP/Composer (v\u1EDBi b\u1EA3o v\u1EC7 Laravel major version)"));
11072
- console.log(chalk17.dim(" \u2022 Python (pip, pipenv)"));
10668
+ console.log(chalk18.bold("H\u1ED7 tr\u1EE3:"));
10669
+ console.log(chalk18.dim(" \u2022 Node.js (npm, pnpm, yarn, bun)"));
10670
+ console.log(chalk18.dim(" \u2022 PHP/Composer (v\u1EDBi b\u1EA3o v\u1EC7 Laravel major version)"));
10671
+ console.log(chalk18.dim(" \u2022 Python (pip, pipenv)"));
11073
10672
  console.log();
11074
- console.log(chalk17.bold("V\xED d\u1EE5:"));
11075
- console.log(chalk17.dim(" $ jai1 deps check"));
11076
- console.log(chalk17.dim(" $ jai1 deps upgrade"));
11077
- console.log(chalk17.dim(" $ jai1 deps upgrade --all"));
10673
+ console.log(chalk18.bold("V\xED d\u1EE5:"));
10674
+ console.log(chalk18.dim(" $ jai1 deps check"));
10675
+ console.log(chalk18.dim(" $ jai1 deps upgrade"));
10676
+ console.log(chalk18.dim(" $ jai1 deps upgrade --all"));
11078
10677
  console.log();
11079
- console.log(chalk17.dim('Ch\u1EA1y "jai1 deps <l\u1EC7nh> --help" \u0111\u1EC3 xem chi ti\u1EBFt'));
10678
+ console.log(chalk18.dim('Ch\u1EA1y "jai1 deps <l\u1EC7nh> --help" \u0111\u1EC3 xem chi ti\u1EBFt'));
11080
10679
  }
11081
10680
  function createDepsCommand() {
11082
10681
  const depsCommand = new Command45("deps").description("Qu\u1EA3n l\xFD dependencies trong project").action(() => {
@@ -11092,13 +10691,13 @@ import { Command as Command56 } from "commander";
11092
10691
 
11093
10692
  // src/commands/tasks/add.ts
11094
10693
  import { Command as Command46 } from "commander";
11095
- import chalk18 from "chalk";
10694
+ import chalk19 from "chalk";
11096
10695
  function createTaskAddCommand() {
11097
10696
  return new Command46("add").description("Add a new task").argument("<title>", "Task title").option("-p, --priority <n>", "Priority: 0=critical, 1=high, 2=medium, 3=low", "2").option("-P, --parent <parent>", "Parent: feature/xxx, plan/xxx, bug/xxx").option("-t, --tags <tags>", "Comma-separated tags").option("-j, --json", "Output JSON").action(async (title, options) => {
11098
10697
  const service = new TaskService();
11099
10698
  const priority = Number(options.priority ?? 2);
11100
10699
  if (priority < 0 || priority > 3) {
11101
- console.error(chalk18.red("\u274C Priority must be 0-3"));
10700
+ console.error(chalk19.red("\u274C Priority must be 0-3"));
11102
10701
  process.exit(1);
11103
10702
  }
11104
10703
  const tags = options.tags ? options.tags.split(",").map((t) => t.trim()) : [];
@@ -11114,21 +10713,21 @@ function createTaskAddCommand() {
11114
10713
  }
11115
10714
  const icon = PRIORITY_ICONS[task.priority] || "\u{1F7E1}";
11116
10715
  const label = PRIORITY_LABELS[task.priority] || "Medium";
11117
- console.log(chalk18.green(`\u2705 Task added: ${chalk18.bold(task.id)}`));
11118
- console.log(` ${chalk18.dim("Title:")} ${task.title}`);
11119
- console.log(` ${chalk18.dim("Priority:")} ${icon} ${label}`);
10716
+ console.log(chalk19.green(`\u2705 Task added: ${chalk19.bold(task.id)}`));
10717
+ console.log(` ${chalk19.dim("Title:")} ${task.title}`);
10718
+ console.log(` ${chalk19.dim("Priority:")} ${icon} ${label}`);
11120
10719
  if (task.parent) {
11121
- console.log(` ${chalk18.dim("Parent:")} ${task.parent}`);
10720
+ console.log(` ${chalk19.dim("Parent:")} ${task.parent}`);
11122
10721
  }
11123
10722
  if (task.tags.length > 0) {
11124
- console.log(` ${chalk18.dim("Tags:")} ${task.tags.join(", ")}`);
10723
+ console.log(` ${chalk19.dim("Tags:")} ${task.tags.join(", ")}`);
11125
10724
  }
11126
10725
  });
11127
10726
  }
11128
10727
 
11129
10728
  // src/commands/tasks/list.ts
11130
10729
  import { Command as Command47 } from "commander";
11131
- import chalk19 from "chalk";
10730
+ import chalk20 from "chalk";
11132
10731
  function createTaskListCommand() {
11133
10732
  return new Command47("list").alias("ls").description("List tasks").option("-s, --status <status>", "Filter by status: todo, in_progress, done, cancelled").option("-P, --parent <parent>", "Filter by parent: feature/xxx, plan/xxx").option("-j, --json", "Output JSON").action(async (options) => {
11134
10733
  await handleTaskList(options);
@@ -11149,12 +10748,12 @@ async function handleTaskList(options) {
11149
10748
  return;
11150
10749
  }
11151
10750
  if (tasks.length === 0) {
11152
- console.log(chalk19.dim("No tasks found."));
10751
+ console.log(chalk20.dim("No tasks found."));
11153
10752
  return;
11154
10753
  }
11155
10754
  const doneIds = new Set(allTasks.filter((t) => t.status === "done").map((t) => t.id));
11156
10755
  const header = options.parent ? `\u{1F4CB} ${options.parent} (${tasks.length} tasks)` : `\u{1F4CB} All tasks (${tasks.length})`;
11157
- console.log(chalk19.bold(header));
10756
+ console.log(chalk20.bold(header));
11158
10757
  console.log();
11159
10758
  for (const task of tasks) {
11160
10759
  printTaskLine(task, doneIds);
@@ -11164,23 +10763,23 @@ function printTaskLine(task, doneIds) {
11164
10763
  const isBlocked = task.status === "todo" && task.depends_on.length > 0 && !task.depends_on.every((id) => doneIds.has(id));
11165
10764
  const statusIcon = isBlocked ? BLOCKED_ICON : STATUS_ICONS[task.status] || "\u{1F4CB}";
11166
10765
  const priorityIcon = PRIORITY_ICONS[task.priority] || "\u{1F7E1}";
11167
- let line = ` ${statusIcon} ${chalk19.dim(task.id)} P${task.priority}${priorityIcon} ${task.title}`;
10766
+ let line = ` ${statusIcon} ${chalk20.dim(task.id)} P${task.priority}${priorityIcon} ${task.title}`;
11168
10767
  if (task.status === "in_progress" && task.assigned_to) {
11169
- line += chalk19.cyan(` @${task.assigned_to}`);
10768
+ line += chalk20.cyan(` @${task.assigned_to}`);
11170
10769
  }
11171
10770
  if (isBlocked) {
11172
10771
  const blockedBy = task.depends_on.filter((id) => !doneIds.has(id));
11173
- line += chalk19.red(` (blocked: ${blockedBy.join(", ")})`);
10772
+ line += chalk20.red(` (blocked: ${blockedBy.join(", ")})`);
11174
10773
  }
11175
10774
  if (task.parent) {
11176
- line += chalk19.dim(` [${task.parent}]`);
10775
+ line += chalk20.dim(` [${task.parent}]`);
11177
10776
  }
11178
10777
  console.log(line);
11179
10778
  }
11180
10779
 
11181
10780
  // src/commands/tasks/ready.ts
11182
10781
  import { Command as Command48 } from "commander";
11183
- import chalk20 from "chalk";
10782
+ import chalk21 from "chalk";
11184
10783
  function createTaskReadyCommand() {
11185
10784
  return new Command48("ready").description("Show tasks ready to pick (not blocked, not assigned)").option("-P, --parent <parent>", "Filter by parent").option("-j, --json", "Output JSON").action(async (options) => {
11186
10785
  const service = new TaskService();
@@ -11190,33 +10789,33 @@ function createTaskReadyCommand() {
11190
10789
  return;
11191
10790
  }
11192
10791
  if (tasks.length === 0) {
11193
- console.log(chalk20.dim("No tasks ready to pick."));
11194
- console.log(chalk20.dim("\u{1F4A1} Check blocked tasks: jai1 t list -s todo"));
10792
+ console.log(chalk21.dim("No tasks ready to pick."));
10793
+ console.log(chalk21.dim("\u{1F4A1} Check blocked tasks: jai1 t list -s todo"));
11195
10794
  return;
11196
10795
  }
11197
- console.log(chalk20.bold(`\u{1F4CB} Ready to pick (${tasks.length} tasks):`));
10796
+ console.log(chalk21.bold(`\u{1F4CB} Ready to pick (${tasks.length} tasks):`));
11198
10797
  console.log();
11199
10798
  for (const task of tasks) {
11200
10799
  const icon = PRIORITY_ICONS[task.priority] || "\u{1F7E1}";
11201
- let line = ` P${task.priority}${icon} ${chalk20.dim(task.id)} ${task.title}`;
10800
+ let line = ` P${task.priority}${icon} ${chalk21.dim(task.id)} ${task.title}`;
11202
10801
  if (task.parent) {
11203
- line += chalk20.dim(` [${task.parent}]`);
10802
+ line += chalk21.dim(` [${task.parent}]`);
11204
10803
  }
11205
10804
  console.log(line);
11206
10805
  }
11207
10806
  console.log();
11208
- console.log(chalk20.dim("\u{1F4A1} Run: jai1 t pick"));
10807
+ console.log(chalk21.dim("\u{1F4A1} Run: jai1 t pick"));
11209
10808
  });
11210
10809
  }
11211
10810
 
11212
10811
  // src/commands/tasks/update.ts
11213
10812
  import { Command as Command49 } from "commander";
11214
- import chalk21 from "chalk";
10813
+ import chalk22 from "chalk";
11215
10814
  var VALID_STATUSES = ["todo", "in_progress", "done", "cancelled"];
11216
10815
  function createTaskUpdateCommand() {
11217
10816
  return new Command49("update").description("Update task status").argument("<id>", "Task ID (e.g. T-001)").requiredOption("-s, --status <status>", "New status: todo, in_progress, done, cancelled").option("-j, --json", "Output JSON").action(async (id, options) => {
11218
10817
  if (!VALID_STATUSES.includes(options.status)) {
11219
- console.error(chalk21.red(`\u274C Invalid status. Must be: ${VALID_STATUSES.join(", ")}`));
10818
+ console.error(chalk22.red(`\u274C Invalid status. Must be: ${VALID_STATUSES.join(", ")}`));
11220
10819
  process.exit(1);
11221
10820
  }
11222
10821
  const service = new TaskService();
@@ -11227,9 +10826,9 @@ function createTaskUpdateCommand() {
11227
10826
  return;
11228
10827
  }
11229
10828
  const icon = STATUS_ICONS[task.status] || "\u{1F4CB}";
11230
- console.log(chalk21.green(`\u2705 ${task.id} \u2192 ${icon} ${task.status}`));
10829
+ console.log(chalk22.green(`\u2705 ${task.id} \u2192 ${icon} ${task.status}`));
11231
10830
  } catch (error) {
11232
- console.error(chalk21.red(`\u274C ${error instanceof Error ? error.message : String(error)}`));
10831
+ console.error(chalk22.red(`\u274C ${error instanceof Error ? error.message : String(error)}`));
11233
10832
  process.exit(1);
11234
10833
  }
11235
10834
  });
@@ -11237,14 +10836,14 @@ function createTaskUpdateCommand() {
11237
10836
 
11238
10837
  // src/commands/tasks/show.ts
11239
10838
  import { Command as Command50 } from "commander";
11240
- import chalk22 from "chalk";
10839
+ import chalk23 from "chalk";
11241
10840
  function createTaskShowCommand() {
11242
10841
  return new Command50("show").description("Show task detail or all tasks under a parent").argument("<query>", "Task ID (T-001) or parent (feature/xxx)").option("-j, --json", "Output JSON").action(async (query, options) => {
11243
10842
  const service = new TaskService();
11244
10843
  if (query.startsWith("T-")) {
11245
10844
  const task = await service.findById(query);
11246
10845
  if (!task) {
11247
- console.error(chalk22.red(`\u274C Task ${query} not found`));
10846
+ console.error(chalk23.red(`\u274C Task ${query} not found`));
11248
10847
  process.exit(1);
11249
10848
  }
11250
10849
  if (options.json) {
@@ -11255,34 +10854,34 @@ function createTaskShowCommand() {
11255
10854
  const statusIcon = blocked ? BLOCKED_ICON : STATUS_ICONS[task.status] || "\u{1F4CB}";
11256
10855
  const priIcon = PRIORITY_ICONS[task.priority] || "\u{1F7E1}";
11257
10856
  const priLabel = PRIORITY_LABELS[task.priority] || "Medium";
11258
- console.log(chalk22.bold(`
10857
+ console.log(chalk23.bold(`
11259
10858
  \u{1F4CC} ${task.id}: ${task.title}
11260
10859
  `));
11261
- console.log(` ${chalk22.dim("Status:")} ${statusIcon} ${task.status}${blocked ? chalk22.red(" (BLOCKED)") : ""}`);
11262
- console.log(` ${chalk22.dim("Priority:")} ${priIcon} P${task.priority} ${priLabel}`);
10860
+ console.log(` ${chalk23.dim("Status:")} ${statusIcon} ${task.status}${blocked ? chalk23.red(" (BLOCKED)") : ""}`);
10861
+ console.log(` ${chalk23.dim("Priority:")} ${priIcon} P${task.priority} ${priLabel}`);
11263
10862
  if (task.parent) {
11264
- console.log(` ${chalk22.dim("Parent:")} ${task.parent}`);
10863
+ console.log(` ${chalk23.dim("Parent:")} ${task.parent}`);
11265
10864
  }
11266
10865
  if (task.assigned_to) {
11267
- console.log(` ${chalk22.dim("Assigned:")} @${task.assigned_to} (${task.claimed_at})`);
10866
+ console.log(` ${chalk23.dim("Assigned:")} @${task.assigned_to} (${task.claimed_at})`);
11268
10867
  }
11269
10868
  if (task.depends_on.length > 0) {
11270
- console.log(` ${chalk22.dim("Depends on:")} ${task.depends_on.join(", ")}`);
10869
+ console.log(` ${chalk23.dim("Depends on:")} ${task.depends_on.join(", ")}`);
11271
10870
  if (blocked) {
11272
- console.log(` ${chalk22.dim("Blocked by:")} ${chalk22.red(blockedBy.join(", "))}`);
10871
+ console.log(` ${chalk23.dim("Blocked by:")} ${chalk23.red(blockedBy.join(", "))}`);
11273
10872
  }
11274
10873
  }
11275
10874
  if (task.tags.length > 0) {
11276
- console.log(` ${chalk22.dim("Tags:")} ${task.tags.join(", ")}`);
10875
+ console.log(` ${chalk23.dim("Tags:")} ${task.tags.join(", ")}`);
11277
10876
  }
11278
10877
  if (task.branch) {
11279
- console.log(` ${chalk22.dim("Branch:")} ${task.branch}`);
10878
+ console.log(` ${chalk23.dim("Branch:")} ${task.branch}`);
11280
10879
  }
11281
10880
  if (task.notes) {
11282
- console.log(` ${chalk22.dim("Notes:")} ${task.notes}`);
10881
+ console.log(` ${chalk23.dim("Notes:")} ${task.notes}`);
11283
10882
  }
11284
- console.log(` ${chalk22.dim("Created:")} ${task.created}`);
11285
- console.log(` ${chalk22.dim("Updated:")} ${task.updated}`);
10883
+ console.log(` ${chalk23.dim("Created:")} ${task.created}`);
10884
+ console.log(` ${chalk23.dim("Updated:")} ${task.updated}`);
11286
10885
  console.log();
11287
10886
  } else {
11288
10887
  const tasks = await service.filter({ parent: query });
@@ -11291,10 +10890,10 @@ function createTaskShowCommand() {
11291
10890
  return;
11292
10891
  }
11293
10892
  if (tasks.length === 0) {
11294
- console.log(chalk22.dim(`No tasks for parent: ${query}`));
10893
+ console.log(chalk23.dim(`No tasks for parent: ${query}`));
11295
10894
  return;
11296
10895
  }
11297
- console.log(chalk22.bold(`
10896
+ console.log(chalk23.bold(`
11298
10897
  \u{1F4CB} ${query} (${tasks.length} tasks)
11299
10898
  `));
11300
10899
  const allTasks = await service.readAll();
@@ -11302,11 +10901,11 @@ function createTaskShowCommand() {
11302
10901
  for (const task of tasks) {
11303
10902
  const isBlocked = task.status === "todo" && task.depends_on.length > 0 && !task.depends_on.every((id) => doneIds.has(id));
11304
10903
  const icon = isBlocked ? BLOCKED_ICON : STATUS_ICONS[task.status] || "\u{1F4CB}";
11305
- let line = ` ${icon} ${chalk22.dim(task.id)} P${task.priority} ${task.title}`;
11306
- if (task.assigned_to) line += chalk22.cyan(` @${task.assigned_to}`);
10904
+ let line = ` ${icon} ${chalk23.dim(task.id)} P${task.priority} ${task.title}`;
10905
+ if (task.assigned_to) line += chalk23.cyan(` @${task.assigned_to}`);
11307
10906
  if (isBlocked) {
11308
10907
  const bb = task.depends_on.filter((id) => !doneIds.has(id));
11309
- line += chalk22.red(` (blocked: ${bb.join(", ")})`);
10908
+ line += chalk23.red(` (blocked: ${bb.join(", ")})`);
11310
10909
  }
11311
10910
  console.log(line);
11312
10911
  }
@@ -11317,7 +10916,7 @@ function createTaskShowCommand() {
11317
10916
 
11318
10917
  // src/commands/tasks/pick.ts
11319
10918
  import { Command as Command51 } from "commander";
11320
- import chalk23 from "chalk";
10919
+ import chalk24 from "chalk";
11321
10920
  import { confirm as confirm9 } from "@inquirer/prompts";
11322
10921
  function createTaskPickCommand() {
11323
10922
  return new Command51("pick").description("Claim the next available task").option("-j, --json", "Output JSON").action(async (options) => {
@@ -11328,8 +10927,8 @@ function createTaskPickCommand() {
11328
10927
  console.log(JSON.stringify({ picked: null, message: "No tasks ready" }));
11329
10928
  return;
11330
10929
  }
11331
- console.log(chalk23.dim("No tasks ready to pick."));
11332
- console.log(chalk23.dim('\u{1F4A1} Add tasks first: jai1 t add "..."'));
10930
+ console.log(chalk24.dim("No tasks ready to pick."));
10931
+ console.log(chalk24.dim('\u{1F4A1} Add tasks first: jai1 t add "..."'));
11333
10932
  return;
11334
10933
  }
11335
10934
  const top = ready[0];
@@ -11339,13 +10938,13 @@ function createTaskPickCommand() {
11339
10938
  console.log(JSON.stringify(picked2, null, 2));
11340
10939
  return;
11341
10940
  }
11342
- console.log(chalk23.bold("\n\u{1F4CC} Next available task:"));
11343
- console.log(` ${chalk23.bold(top.id)} P${top.priority}${icon} ${top.title}`);
10941
+ console.log(chalk24.bold("\n\u{1F4CC} Next available task:"));
10942
+ console.log(` ${chalk24.bold(top.id)} P${top.priority}${icon} ${top.title}`);
11344
10943
  if (top.parent) {
11345
- console.log(` ${chalk23.dim("Parent:")} ${top.parent}`);
10944
+ console.log(` ${chalk24.dim("Parent:")} ${top.parent}`);
11346
10945
  }
11347
10946
  if (ready.length > 1) {
11348
- console.log(chalk23.dim(`
10947
+ console.log(chalk24.dim(`
11349
10948
  +${ready.length - 1} more tasks ready`));
11350
10949
  }
11351
10950
  const proceed = await confirm9({
@@ -11353,18 +10952,18 @@ function createTaskPickCommand() {
11353
10952
  default: true
11354
10953
  });
11355
10954
  if (!proceed) {
11356
- console.log(chalk23.dim("\nCancelled."));
10955
+ console.log(chalk24.dim("\nCancelled."));
11357
10956
  return;
11358
10957
  }
11359
10958
  const picked = await service.pick(top.id);
11360
- console.log(chalk23.green(`
10959
+ console.log(chalk24.green(`
11361
10960
  \u2705 ${picked.id} assigned to @${picked.assigned_to}, status \u2192 in_progress`));
11362
10961
  });
11363
10962
  }
11364
10963
 
11365
10964
  // src/commands/tasks/done.ts
11366
10965
  import { Command as Command52 } from "commander";
11367
- import chalk24 from "chalk";
10966
+ import chalk25 from "chalk";
11368
10967
  function createTaskDoneCommand() {
11369
10968
  return new Command52("done").description("Mark task as done").argument("<id>", "Task ID (e.g. T-001)").option("-j, --json", "Output JSON").action(async (id, options) => {
11370
10969
  const service = new TaskService();
@@ -11374,9 +10973,9 @@ function createTaskDoneCommand() {
11374
10973
  console.log(JSON.stringify(task, null, 2));
11375
10974
  return;
11376
10975
  }
11377
- console.log(chalk24.green(`\u2705 ${task.id}: ${task.title} \u2192 done`));
10976
+ console.log(chalk25.green(`\u2705 ${task.id}: ${task.title} \u2192 done`));
11378
10977
  } catch (error) {
11379
- console.error(chalk24.red(`\u274C ${error instanceof Error ? error.message : String(error)}`));
10978
+ console.error(chalk25.red(`\u274C ${error instanceof Error ? error.message : String(error)}`));
11380
10979
  process.exit(1);
11381
10980
  }
11382
10981
  });
@@ -11384,7 +10983,7 @@ function createTaskDoneCommand() {
11384
10983
 
11385
10984
  // src/commands/tasks/dep.ts
11386
10985
  import { Command as Command53 } from "commander";
11387
- import chalk25 from "chalk";
10986
+ import chalk26 from "chalk";
11388
10987
  function createTaskDepCommand() {
11389
10988
  return new Command53("dep").description("Add dependency: child depends on parent").argument("<childId>", "Child task ID (the one that waits)").argument("<parentId>", "Parent task ID (must be done first)").option("-j, --json", "Output JSON").action(async (childId, parentId, options) => {
11390
10989
  const service = new TaskService();
@@ -11394,10 +10993,10 @@ function createTaskDepCommand() {
11394
10993
  console.log(JSON.stringify(task, null, 2));
11395
10994
  return;
11396
10995
  }
11397
- console.log(chalk25.green(`\u2705 ${childId} now depends on ${parentId}`));
11398
- console.log(chalk25.dim(` ${task.title} \u2192 waits for ${parentId}`));
10996
+ console.log(chalk26.green(`\u2705 ${childId} now depends on ${parentId}`));
10997
+ console.log(chalk26.dim(` ${task.title} \u2192 waits for ${parentId}`));
11399
10998
  } catch (error) {
11400
- console.error(chalk25.red(`\u274C ${error instanceof Error ? error.message : String(error)}`));
10999
+ console.error(chalk26.red(`\u274C ${error instanceof Error ? error.message : String(error)}`));
11401
11000
  process.exit(1);
11402
11001
  }
11403
11002
  });
@@ -11405,27 +11004,27 @@ function createTaskDepCommand() {
11405
11004
 
11406
11005
  // src/commands/tasks/sync.ts
11407
11006
  import { Command as Command54 } from "commander";
11408
- import chalk26 from "chalk";
11007
+ import chalk27 from "chalk";
11409
11008
  function createTaskSyncCommand() {
11410
11009
  return new Command54("sync").description("Sync tasks with git (commit & push only tasks file)").option("--pull", "Pull and merge tasks from origin/main").option("--push", "Commit and push tasks file").action(async (options) => {
11411
11010
  const service = new TaskService();
11412
11011
  if (options.pull) {
11413
- console.log(chalk26.dim("\u23F3 Pulling tasks from origin/main..."));
11012
+ console.log(chalk27.dim("\u23F3 Pulling tasks from origin/main..."));
11414
11013
  try {
11415
11014
  const result = await service.syncPull();
11416
- console.log(chalk26.green(`\u2705 Sync pull complete: ${result.merged} tasks merged`));
11015
+ console.log(chalk27.green(`\u2705 Sync pull complete: ${result.merged} tasks merged`));
11417
11016
  } catch (error) {
11418
- console.error(chalk26.red(`\u274C ${error instanceof Error ? error.message : String(error)}`));
11017
+ console.error(chalk27.red(`\u274C ${error instanceof Error ? error.message : String(error)}`));
11419
11018
  process.exit(1);
11420
11019
  }
11421
11020
  return;
11422
11021
  }
11423
- console.log(chalk26.dim("\u23F3 Syncing tasks to git..."));
11022
+ console.log(chalk27.dim("\u23F3 Syncing tasks to git..."));
11424
11023
  try {
11425
11024
  await service.syncPush();
11426
- console.log(chalk26.green("\u2705 Tasks synced to git"));
11025
+ console.log(chalk27.green("\u2705 Tasks synced to git"));
11427
11026
  } catch (error) {
11428
- console.error(chalk26.red(`\u274C ${error instanceof Error ? error.message : String(error)}`));
11027
+ console.error(chalk27.red(`\u274C ${error instanceof Error ? error.message : String(error)}`));
11429
11028
  process.exit(1);
11430
11029
  }
11431
11030
  });
@@ -11433,107 +11032,107 @@ function createTaskSyncCommand() {
11433
11032
 
11434
11033
  // src/commands/tasks/guide.ts
11435
11034
  import { Command as Command55 } from "commander";
11436
- import chalk27 from "chalk";
11035
+ import chalk28 from "chalk";
11437
11036
  var GUIDE_TEXT = `
11438
- ${chalk27.cyan.bold("\u{1F4D6} Jai1 Task Management Guide")}
11439
-
11440
- ${chalk27.bold("\u2501\u2501\u2501 STATUSES \u2501\u2501\u2501")}
11441
- ${chalk27.dim("todo")} \u{1F4CB} Ch\u01B0a b\u1EAFt \u0111\u1EA7u
11442
- ${chalk27.dim("in_progress")} \u{1F535} \u0110ang l\xE0m (bao g\u1ED3m review)
11443
- ${chalk27.dim("done")} \u2705 Ho\xE0n th\xE0nh
11444
- ${chalk27.dim("cancelled")} \u26AB Hu\u1EF7
11445
- ${chalk27.dim("(blocked)")} \u{1F534} Computed: depends_on ch\u01B0a done
11446
-
11447
- ${chalk27.bold("\u2501\u2501\u2501 PRIORITY \u2501\u2501\u2501")}
11448
- ${chalk27.dim("0")} = \u{1F525} Critical \u2014 Prod down, security, block c\u1EA3 team
11449
- ${chalk27.dim("1")} = \u{1F534} High \u2014 Feature ch\xEDnh, deadline g\u1EA7n
11450
- ${chalk27.dim("2")} = \u{1F7E1} Medium \u2014 B\xECnh th\u01B0\u1EDDng (default)
11451
- ${chalk27.dim("3")} = \u{1F7E2} Low \u2014 Nice-to-have, docs, refactor
11452
-
11453
- ${chalk27.bold("\u2501\u2501\u2501 QUICK START \u2501\u2501\u2501")}
11454
- ${chalk27.cyan("jai1 t add")} "Fix login bug" -p 1 -P bug/login
11455
- ${chalk27.cyan("jai1 t ready")} Show tasks s\u1EB5n s\xE0ng
11456
- ${chalk27.cyan("jai1 t pick")} Claim & start working
11457
- ${chalk27.cyan("jai1 t done")} T-003 Mark complete
11458
-
11459
- ${chalk27.bold("\u2501\u2501\u2501 DAILY WORKFLOW \u2501\u2501\u2501")}
11460
- ${chalk27.cyan("jai1 t sync --pull")} Pull latest tasks
11461
- ${chalk27.cyan("jai1 t summary")} Dashboard t\u1ED5ng quan
11462
- ${chalk27.cyan("jai1 t ready")} Xem tasks s\u1EB5n s\xE0ng
11463
- ${chalk27.cyan("jai1 t pick")} Claim task m\u1EDBi
11464
- ${chalk27.cyan("jai1 t done")} T-xxx Ho\xE0n th\xE0nh task
11465
- ${chalk27.cyan("jai1 t sync --push")} Push l\xEAn git
11466
-
11467
- ${chalk27.bold("\u2501\u2501\u2501 ADDING TASKS \u2501\u2501\u2501")}
11468
- ${chalk27.yellow("\u26A0 Lu\xF4n ki\u1EC3m tra duplicate tr\u01B0\u1EDBc khi add:")}
11469
- ${chalk27.cyan("jai1 t list -P")} feature/xxx
11470
-
11471
- ${chalk27.dim("Add cho feature:")}
11472
- ${chalk27.cyan("jai1 t add")} "Setup DB schema" -p 1 -P feature/xxx
11473
- ${chalk27.cyan("jai1 t add")} "Create API" -p 1 -P feature/xxx
11474
- ${chalk27.cyan("jai1 t add")} "Build UI" -p 2 -P feature/xxx
11475
-
11476
- ${chalk27.dim("Add cho plan:")}
11477
- ${chalk27.cyan("jai1 t add")} "Refactor middleware" -p 2 -P plan/xxx
11478
-
11479
- ${chalk27.dim("Add standalone:")}
11480
- ${chalk27.cyan("jai1 t add")} "Fix README typo" -p 3
11481
-
11482
- ${chalk27.dim("Add bug fix:")}
11483
- ${chalk27.cyan("jai1 t add")} "Fix login redirect" -p 1 -P bug/xxx
11484
-
11485
- ${chalk27.bold("\u2501\u2501\u2501 DEPENDENCY \u2501\u2501\u2501")}
11486
- ${chalk27.dim("Task dependency:")}
11487
- ${chalk27.cyan("jai1 t dep")} T-002 T-001 T-002 ch\u1EDD T-001 done
11488
- ${chalk27.cyan("jai1 t dep")} T-003 T-002 T-003 ch\u1EDD T-002 done
11489
-
11490
- ${chalk27.dim("Feature-level dependency:")}
11491
- ${chalk27.dim("# N\u1EBFu feature/auth ph\u1EE5 thu\u1ED9c feature/user-model:")}
11492
- ${chalk27.cyan("jai1 t add")} "[DEP] Wait for feature/user-model" -p 1 -P feature/auth
11493
- ${chalk27.dim("# R\u1ED3i dep n\xF3 v\u1EDBi tasks cu\u1ED1i c\u1EE7a user-model")}
11494
-
11495
- ${chalk27.dim("View deps:")}
11496
- ${chalk27.cyan("jai1 t show")} T-002 Hi\u1EC7n depends_on
11497
-
11498
- ${chalk27.bold("\u2501\u2501\u2501 TEAM COLLABORATION \u2501\u2501\u2501")}
11499
- ${chalk27.yellow("\u26A0 Assignment ch\u1EC9 qua pick \u2014 kh\xF4ng set th\u1EE7 c\xF4ng.")}
11500
- ${chalk27.dim("Khi b\u1EA1n pick \u2192 team th\u1EA5y task \u0111\xE3 c\xF3 ng\u01B0\u1EDDi nh\u1EADn.")}
11501
-
11502
- ${chalk27.dim("Sync morning:")} ${chalk27.cyan("jai1 t sync --pull")}
11503
- ${chalk27.dim("Sync evening:")} ${chalk27.cyan("jai1 t sync --push")}
11504
-
11505
- ${chalk27.bold("\u2501\u2501\u2501 FOR AI AGENTS (Workflow Integration) \u2501\u2501\u2501")}
11506
- ${chalk27.dim("Khi t\u1EA1o tasks t\u1EEB feature/plan:")}
11507
- 1. ${chalk27.cyan("jai1 t list -P")} <parent> Check existing (tr\xE1nh duplicate)
11508
- 2. ${chalk27.cyan("jai1 t add")} "..." -p <0-3> -P <parent> Add t\u1EEBng task
11509
- 3. ${chalk27.cyan("jai1 t dep")} <child> <parent> Set dependencies
11510
- 4. ${chalk27.cyan("jai1 t done")} <id> Mark complete
11511
-
11512
- ${chalk27.dim("Khi implement task ti\u1EBFp theo:")}
11513
- 1. ${chalk27.cyan("jai1 t pick")} (ho\u1EB7c ${chalk27.cyan("jai1 t ready -P")} <parent>)
11037
+ ${chalk28.cyan.bold("\u{1F4D6} Jai1 Task Management Guide")}
11038
+
11039
+ ${chalk28.bold("\u2501\u2501\u2501 STATUSES \u2501\u2501\u2501")}
11040
+ ${chalk28.dim("todo")} \u{1F4CB} Ch\u01B0a b\u1EAFt \u0111\u1EA7u
11041
+ ${chalk28.dim("in_progress")} \u{1F535} \u0110ang l\xE0m (bao g\u1ED3m review)
11042
+ ${chalk28.dim("done")} \u2705 Ho\xE0n th\xE0nh
11043
+ ${chalk28.dim("cancelled")} \u26AB Hu\u1EF7
11044
+ ${chalk28.dim("(blocked)")} \u{1F534} Computed: depends_on ch\u01B0a done
11045
+
11046
+ ${chalk28.bold("\u2501\u2501\u2501 PRIORITY \u2501\u2501\u2501")}
11047
+ ${chalk28.dim("0")} = \u{1F525} Critical \u2014 Prod down, security, block c\u1EA3 team
11048
+ ${chalk28.dim("1")} = \u{1F534} High \u2014 Feature ch\xEDnh, deadline g\u1EA7n
11049
+ ${chalk28.dim("2")} = \u{1F7E1} Medium \u2014 B\xECnh th\u01B0\u1EDDng (default)
11050
+ ${chalk28.dim("3")} = \u{1F7E2} Low \u2014 Nice-to-have, docs, refactor
11051
+
11052
+ ${chalk28.bold("\u2501\u2501\u2501 QUICK START \u2501\u2501\u2501")}
11053
+ ${chalk28.cyan("jai1 t add")} "Fix login bug" -p 1 -P bug/login
11054
+ ${chalk28.cyan("jai1 t ready")} Show tasks s\u1EB5n s\xE0ng
11055
+ ${chalk28.cyan("jai1 t pick")} Claim & start working
11056
+ ${chalk28.cyan("jai1 t done")} T-003 Mark complete
11057
+
11058
+ ${chalk28.bold("\u2501\u2501\u2501 DAILY WORKFLOW \u2501\u2501\u2501")}
11059
+ ${chalk28.cyan("jai1 t sync --pull")} Pull latest tasks
11060
+ ${chalk28.cyan("jai1 t summary")} Dashboard t\u1ED5ng quan
11061
+ ${chalk28.cyan("jai1 t ready")} Xem tasks s\u1EB5n s\xE0ng
11062
+ ${chalk28.cyan("jai1 t pick")} Claim task m\u1EDBi
11063
+ ${chalk28.cyan("jai1 t done")} T-xxx Ho\xE0n th\xE0nh task
11064
+ ${chalk28.cyan("jai1 t sync --push")} Push l\xEAn git
11065
+
11066
+ ${chalk28.bold("\u2501\u2501\u2501 ADDING TASKS \u2501\u2501\u2501")}
11067
+ ${chalk28.yellow("\u26A0 Lu\xF4n ki\u1EC3m tra duplicate tr\u01B0\u1EDBc khi add:")}
11068
+ ${chalk28.cyan("jai1 t list -P")} feature/xxx
11069
+
11070
+ ${chalk28.dim("Add cho feature:")}
11071
+ ${chalk28.cyan("jai1 t add")} "Setup DB schema" -p 1 -P feature/xxx
11072
+ ${chalk28.cyan("jai1 t add")} "Create API" -p 1 -P feature/xxx
11073
+ ${chalk28.cyan("jai1 t add")} "Build UI" -p 2 -P feature/xxx
11074
+
11075
+ ${chalk28.dim("Add cho plan:")}
11076
+ ${chalk28.cyan("jai1 t add")} "Refactor middleware" -p 2 -P plan/xxx
11077
+
11078
+ ${chalk28.dim("Add standalone:")}
11079
+ ${chalk28.cyan("jai1 t add")} "Fix README typo" -p 3
11080
+
11081
+ ${chalk28.dim("Add bug fix:")}
11082
+ ${chalk28.cyan("jai1 t add")} "Fix login redirect" -p 1 -P bug/xxx
11083
+
11084
+ ${chalk28.bold("\u2501\u2501\u2501 DEPENDENCY \u2501\u2501\u2501")}
11085
+ ${chalk28.dim("Task dependency:")}
11086
+ ${chalk28.cyan("jai1 t dep")} T-002 T-001 T-002 ch\u1EDD T-001 done
11087
+ ${chalk28.cyan("jai1 t dep")} T-003 T-002 T-003 ch\u1EDD T-002 done
11088
+
11089
+ ${chalk28.dim("Feature-level dependency:")}
11090
+ ${chalk28.dim("# N\u1EBFu feature/auth ph\u1EE5 thu\u1ED9c feature/user-model:")}
11091
+ ${chalk28.cyan("jai1 t add")} "[DEP] Wait for feature/user-model" -p 1 -P feature/auth
11092
+ ${chalk28.dim("# R\u1ED3i dep n\xF3 v\u1EDBi tasks cu\u1ED1i c\u1EE7a user-model")}
11093
+
11094
+ ${chalk28.dim("View deps:")}
11095
+ ${chalk28.cyan("jai1 t show")} T-002 Hi\u1EC7n depends_on
11096
+
11097
+ ${chalk28.bold("\u2501\u2501\u2501 TEAM COLLABORATION \u2501\u2501\u2501")}
11098
+ ${chalk28.yellow("\u26A0 Assignment ch\u1EC9 qua pick \u2014 kh\xF4ng set th\u1EE7 c\xF4ng.")}
11099
+ ${chalk28.dim("Khi b\u1EA1n pick \u2192 team th\u1EA5y task \u0111\xE3 c\xF3 ng\u01B0\u1EDDi nh\u1EADn.")}
11100
+
11101
+ ${chalk28.dim("Sync morning:")} ${chalk28.cyan("jai1 t sync --pull")}
11102
+ ${chalk28.dim("Sync evening:")} ${chalk28.cyan("jai1 t sync --push")}
11103
+
11104
+ ${chalk28.bold("\u2501\u2501\u2501 FOR AI AGENTS (Workflow Integration) \u2501\u2501\u2501")}
11105
+ ${chalk28.dim("Khi t\u1EA1o tasks t\u1EEB feature/plan:")}
11106
+ 1. ${chalk28.cyan("jai1 t list -P")} <parent> Check existing (tr\xE1nh duplicate)
11107
+ 2. ${chalk28.cyan("jai1 t add")} "..." -p <0-3> -P <parent> Add t\u1EEBng task
11108
+ 3. ${chalk28.cyan("jai1 t dep")} <child> <parent> Set dependencies
11109
+ 4. ${chalk28.cyan("jai1 t done")} <id> Mark complete
11110
+
11111
+ ${chalk28.dim("Khi implement task ti\u1EBFp theo:")}
11112
+ 1. ${chalk28.cyan("jai1 t pick")} (ho\u1EB7c ${chalk28.cyan("jai1 t ready -P")} <parent>)
11514
11113
  2. Implement task
11515
- 3. ${chalk27.cyan("jai1 t done")} <id>
11114
+ 3. ${chalk28.cyan("jai1 t done")} <id>
11516
11115
 
11517
- ${chalk27.dim("Status transitions:")}
11116
+ ${chalk28.dim("Status transitions:")}
11518
11117
  add \u2192 todo (default)
11519
11118
  pick \u2192 in_progress (auto assign)
11520
11119
  done \u2192 done
11521
11120
  update -s \u2192 any valid status
11522
11121
 
11523
- ${chalk27.bold("\u2501\u2501\u2501 ALL COMMANDS \u2501\u2501\u2501")}
11524
- ${chalk27.cyan("jai1 t list")} [-s status] [-P parent] [-j]
11525
- ${chalk27.cyan("jai1 t ready")} [-P parent] [-j]
11526
- ${chalk27.cyan("jai1 t add")} <title> [-p 0-3] [-P parent] [-t tags] [-j]
11527
- ${chalk27.cyan("jai1 t update")} <id> -s <status> [-j]
11528
- ${chalk27.cyan("jai1 t show")} <id|parent> [-j]
11529
- ${chalk27.cyan("jai1 t pick")} [-j]
11530
- ${chalk27.cyan("jai1 t done")} <id> [-j]
11531
- ${chalk27.cyan("jai1 t dep")} <childId> <parentId> [-j]
11532
- ${chalk27.cyan("jai1 t sync")} [--pull] [--push]
11533
- ${chalk27.cyan("jai1 t summary")} [-j]
11534
- ${chalk27.cyan("jai1 t guide")}
11535
-
11536
- ${chalk27.dim("-j / --json available on all commands (except guide, sync)")}
11122
+ ${chalk28.bold("\u2501\u2501\u2501 ALL COMMANDS \u2501\u2501\u2501")}
11123
+ ${chalk28.cyan("jai1 t list")} [-s status] [-P parent] [-j]
11124
+ ${chalk28.cyan("jai1 t ready")} [-P parent] [-j]
11125
+ ${chalk28.cyan("jai1 t add")} <title> [-p 0-3] [-P parent] [-t tags] [-j]
11126
+ ${chalk28.cyan("jai1 t update")} <id> -s <status> [-j]
11127
+ ${chalk28.cyan("jai1 t show")} <id|parent> [-j]
11128
+ ${chalk28.cyan("jai1 t pick")} [-j]
11129
+ ${chalk28.cyan("jai1 t done")} <id> [-j]
11130
+ ${chalk28.cyan("jai1 t dep")} <childId> <parentId> [-j]
11131
+ ${chalk28.cyan("jai1 t sync")} [--pull] [--push]
11132
+ ${chalk28.cyan("jai1 t summary")} [-j]
11133
+ ${chalk28.cyan("jai1 t guide")}
11134
+
11135
+ ${chalk28.dim("-j / --json available on all commands (except guide, sync)")}
11537
11136
  `;
11538
11137
  function createTaskGuideCommand() {
11539
11138
  return new Command55("guide").description("Show full task management guide").action(() => {
@@ -11568,11 +11167,11 @@ function createTasksCommand() {
11568
11167
 
11569
11168
  // src/commands/kit/index.ts
11570
11169
  import { Command as Command60 } from "commander";
11571
- import chalk29 from "chalk";
11170
+ import chalk30 from "chalk";
11572
11171
 
11573
11172
  // src/commands/kit/list.ts
11574
11173
  import { Command as Command57 } from "commander";
11575
- import chalk28 from "chalk";
11174
+ import chalk29 from "chalk";
11576
11175
  import Table6 from "cli-table3";
11577
11176
 
11578
11177
  // src/services/starter-kit.service.ts
@@ -11646,7 +11245,7 @@ function createKitListCommand() {
11646
11245
  if (!config) {
11647
11246
  throw new ValidationError('Not initialized. Run "jai1 auth" first.');
11648
11247
  }
11649
- console.log(chalk28.cyan("\u{1F4E6} \u0110ang t\u1EA3i danh s\xE1ch starter kits..."));
11248
+ console.log(chalk29.cyan("\u{1F4E6} \u0110ang t\u1EA3i danh s\xE1ch starter kits..."));
11650
11249
  console.log();
11651
11250
  const kitService = new StarterKitService();
11652
11251
  const kits = await kitService.list(config, {
@@ -11654,9 +11253,9 @@ function createKitListCommand() {
11654
11253
  search: options.search
11655
11254
  });
11656
11255
  if (kits.length === 0) {
11657
- console.log(chalk28.yellow("Kh\xF4ng t\xECm th\u1EA5y starter kits n\xE0o."));
11256
+ console.log(chalk29.yellow("Kh\xF4ng t\xECm th\u1EA5y starter kits n\xE0o."));
11658
11257
  if (options.category || options.search) {
11659
- console.log(chalk28.dim("Th\u1EED b\u1ECF filter \u0111\u1EC3 xem t\u1EA5t c\u1EA3."));
11258
+ console.log(chalk29.dim("Th\u1EED b\u1ECF filter \u0111\u1EC3 xem t\u1EA5t c\u1EA3."));
11660
11259
  }
11661
11260
  return;
11662
11261
  }
@@ -11680,28 +11279,28 @@ function createKitListCommand() {
11680
11279
  const categoryKits = byCategory[category];
11681
11280
  const categoryIcon = category === "frontend" ? "\u{1F3A8}" : category === "backend" ? "\u2699\uFE0F" : category === "fullstack" ? "\u{1F680}" : "\u{1F4E6}";
11682
11281
  console.log(
11683
- chalk28.bold(`${categoryIcon} ${category.charAt(0).toUpperCase() + category.slice(1)}`)
11282
+ chalk29.bold(`${categoryIcon} ${category.charAt(0).toUpperCase() + category.slice(1)}`)
11684
11283
  );
11685
11284
  const table = new Table6({
11686
11285
  head: [
11687
- chalk28.cyan("Slug"),
11688
- chalk28.cyan("M\xF4 t\u1EA3"),
11689
- chalk28.cyan("Version")
11286
+ chalk29.cyan("Slug"),
11287
+ chalk29.cyan("M\xF4 t\u1EA3"),
11288
+ chalk29.cyan("Version")
11690
11289
  ],
11691
11290
  style: { head: [], border: ["gray"] }
11692
11291
  });
11693
11292
  for (const kit of categoryKits) {
11694
11293
  table.push([
11695
- chalk28.white(kit.slug),
11696
- chalk28.dim(kit.description.slice(0, 50)),
11697
- chalk28.green(`v${kit.version}`)
11294
+ chalk29.white(kit.slug),
11295
+ chalk29.dim(kit.description.slice(0, 50)),
11296
+ chalk29.green(`v${kit.version}`)
11698
11297
  ]);
11699
11298
  }
11700
11299
  console.log(table.toString());
11701
11300
  console.log();
11702
11301
  }
11703
- console.log(chalk28.dim(`T\u1ED5ng c\u1ED9ng: ${kits.length} starter kit(s)`));
11704
- console.log(chalk28.dim('\n\u{1F4A1} Ch\u1EA1y "jai1 kit create <slug>" \u0111\u1EC3 t\u1EA1o project m\u1EDBi'));
11302
+ console.log(chalk29.dim(`T\u1ED5ng c\u1ED9ng: ${kits.length} starter kit(s)`));
11303
+ console.log(chalk29.dim('\n\u{1F4A1} Ch\u1EA1y "jai1 kit create <slug>" \u0111\u1EC3 t\u1EA1o project m\u1EDBi'));
11705
11304
  });
11706
11305
  }
11707
11306
 
@@ -11981,20 +11580,20 @@ async function getAllFiles(dir) {
11981
11580
 
11982
11581
  // src/commands/kit/index.ts
11983
11582
  function showKitHelp() {
11984
- console.log(chalk29.bold.cyan("\u{1F4E6} jai1 kit") + chalk29.dim(" - Qu\u1EA3n l\xFD starter kits"));
11583
+ console.log(chalk30.bold.cyan("\u{1F4E6} jai1 kit") + chalk30.dim(" - Qu\u1EA3n l\xFD starter kits"));
11985
11584
  console.log();
11986
- console.log(chalk29.bold("C\xE1c l\u1EC7nh:"));
11987
- console.log(` ${chalk29.cyan("list")} Li\u1EC7t k\xEA c\xE1c starter kits c\xF3 s\u1EB5n`);
11988
- console.log(` ${chalk29.cyan("info")} Xem chi ti\u1EBFt m\u1ED9t starter kit`);
11989
- console.log(` ${chalk29.cyan("create")} T\u1EA1o project m\u1EDBi t\u1EEB starter kit`);
11585
+ console.log(chalk30.bold("C\xE1c l\u1EC7nh:"));
11586
+ console.log(` ${chalk30.cyan("list")} Li\u1EC7t k\xEA c\xE1c starter kits c\xF3 s\u1EB5n`);
11587
+ console.log(` ${chalk30.cyan("info")} Xem chi ti\u1EBFt m\u1ED9t starter kit`);
11588
+ console.log(` ${chalk30.cyan("create")} T\u1EA1o project m\u1EDBi t\u1EEB starter kit`);
11990
11589
  console.log();
11991
- console.log(chalk29.bold("V\xED d\u1EE5:"));
11992
- console.log(chalk29.dim(" $ jai1 kit list"));
11993
- console.log(chalk29.dim(" $ jai1 kit list --category frontend"));
11994
- console.log(chalk29.dim(" $ jai1 kit info next-tw4-shadcn"));
11995
- console.log(chalk29.dim(" $ jai1 kit create next-tw4-shadcn my-project"));
11590
+ console.log(chalk30.bold("V\xED d\u1EE5:"));
11591
+ console.log(chalk30.dim(" $ jai1 kit list"));
11592
+ console.log(chalk30.dim(" $ jai1 kit list --category frontend"));
11593
+ console.log(chalk30.dim(" $ jai1 kit info next-tw4-shadcn"));
11594
+ console.log(chalk30.dim(" $ jai1 kit create next-tw4-shadcn my-project"));
11996
11595
  console.log();
11997
- console.log(chalk29.dim('Ch\u1EA1y "jai1 kit <l\u1EC7nh> --help" \u0111\u1EC3 xem chi ti\u1EBFt'));
11596
+ console.log(chalk30.dim('Ch\u1EA1y "jai1 kit <l\u1EC7nh> --help" \u0111\u1EC3 xem chi ti\u1EBFt'));
11998
11597
  }
11999
11598
  function createKitCommand() {
12000
11599
  const cmd = new Command60("kit").description("Manage starter kits for new projects").action(() => {
@@ -12008,11 +11607,11 @@ function createKitCommand() {
12008
11607
 
12009
11608
  // src/commands/rules/index.ts
12010
11609
  import { Command as Command67 } from "commander";
12011
- import chalk31 from "chalk";
11610
+ import chalk32 from "chalk";
12012
11611
 
12013
11612
  // src/commands/rules/list.ts
12014
11613
  import { Command as Command61 } from "commander";
12015
- import chalk30 from "chalk";
11614
+ import chalk31 from "chalk";
12016
11615
  import Table7 from "cli-table3";
12017
11616
  function createRulesListCommand() {
12018
11617
  return new Command61("list").description("List available rule presets").option("--json", "Output as JSON").action(async (options) => {
@@ -12021,7 +11620,7 @@ function createRulesListCommand() {
12021
11620
  if (!config) {
12022
11621
  throw new ValidationError('Not initialized. Run "jai1 auth" first.');
12023
11622
  }
12024
- console.log(chalk30.cyan("\u{1F4CB} \u0110ang t\u1EA3i danh s\xE1ch rule presets..."));
11623
+ console.log(chalk31.cyan("\u{1F4CB} \u0110ang t\u1EA3i danh s\xE1ch rule presets..."));
12025
11624
  console.log();
12026
11625
  try {
12027
11626
  const response = await fetch(`${config.apiUrl}/api/rules/presets`, {
@@ -12038,23 +11637,23 @@ function createRulesListCommand() {
12038
11637
  return;
12039
11638
  }
12040
11639
  if (data.total === 0) {
12041
- console.log(chalk30.yellow("Kh\xF4ng c\xF3 presets n\xE0o."));
11640
+ console.log(chalk31.yellow("Kh\xF4ng c\xF3 presets n\xE0o."));
12042
11641
  return;
12043
11642
  }
12044
11643
  console.log(
12045
- chalk30.green(`\u2713 T\xECm th\u1EA5y ${chalk30.bold(data.total)} preset${data.total > 1 ? "s" : ""}`)
11644
+ chalk31.green(`\u2713 T\xECm th\u1EA5y ${chalk31.bold(data.total)} preset${data.total > 1 ? "s" : ""}`)
12046
11645
  );
12047
11646
  console.log();
12048
11647
  for (const preset of data.presets) {
12049
- console.log(chalk30.bold.cyan(`\u{1F4E6} ${preset.slug}`));
11648
+ console.log(chalk31.bold.cyan(`\u{1F4E6} ${preset.slug}`));
12050
11649
  const table = new Table7({
12051
11650
  style: { head: [], border: ["gray"], compact: true },
12052
11651
  colWidths: [15, 55]
12053
11652
  });
12054
11653
  table.push(
12055
- [chalk30.dim("T\xEAn"), chalk30.white(preset.name)],
12056
- [chalk30.dim("M\xF4 t\u1EA3"), chalk30.white(preset.description)],
12057
- [chalk30.dim("Version"), chalk30.green(`v${preset.version}`)]
11654
+ [chalk31.dim("T\xEAn"), chalk31.white(preset.name)],
11655
+ [chalk31.dim("M\xF4 t\u1EA3"), chalk31.white(preset.description)],
11656
+ [chalk31.dim("Version"), chalk31.green(`v${preset.version}`)]
12058
11657
  );
12059
11658
  const stackParts = [];
12060
11659
  if (preset.stack.frontend) stackParts.push(preset.stack.frontend);
@@ -12062,16 +11661,16 @@ function createRulesListCommand() {
12062
11661
  if (preset.stack.css) stackParts.push(preset.stack.css);
12063
11662
  if (preset.stack.database) stackParts.push(preset.stack.database);
12064
11663
  if (stackParts.length > 0) {
12065
- table.push([chalk30.dim("Stack"), chalk30.yellow(stackParts.join(" + "))]);
11664
+ table.push([chalk31.dim("Stack"), chalk31.yellow(stackParts.join(" + "))]);
12066
11665
  }
12067
11666
  table.push(
12068
- [chalk30.dim("Tags"), chalk30.dim(preset.tags.join(", ") || "-")],
12069
- [chalk30.dim("Downloads"), chalk30.white(preset.downloads.toString())]
11667
+ [chalk31.dim("Tags"), chalk31.dim(preset.tags.join(", ") || "-")],
11668
+ [chalk31.dim("Downloads"), chalk31.white(preset.downloads.toString())]
12070
11669
  );
12071
11670
  console.log(table.toString());
12072
11671
  console.log();
12073
11672
  }
12074
- console.log(chalk30.dim('\u{1F4A1} Ch\u1EA1y "jai1 rules apply <name>" \u0111\u1EC3 \xE1p d\u1EE5ng preset'));
11673
+ console.log(chalk31.dim('\u{1F4A1} Ch\u1EA1y "jai1 rules apply <name>" \u0111\u1EC3 \xE1p d\u1EE5ng preset'));
12075
11674
  } catch (error) {
12076
11675
  throw new Error(
12077
11676
  `L\u1ED7i khi t\u1EA3i presets: ${error instanceof Error ? error.message : String(error)}`
@@ -13499,23 +13098,23 @@ async function checkIdeFilesExist(ideId, format) {
13499
13098
 
13500
13099
  // src/commands/rules/index.ts
13501
13100
  function showRulesHelp() {
13502
- console.log(chalk31.bold.cyan("\u{1F4CB} jai1 rules") + chalk31.dim(" - Qu\u1EA3n l\xFD rule presets cho AI agents"));
13101
+ console.log(chalk32.bold.cyan("\u{1F4CB} jai1 rules") + chalk32.dim(" - Qu\u1EA3n l\xFD rule presets cho AI agents"));
13503
13102
  console.log();
13504
- console.log(chalk31.bold("C\xE1c l\u1EC7nh:"));
13505
- console.log(` ${chalk31.cyan("list")} Li\u1EC7t k\xEA c\xE1c presets c\xF3 s\u1EB5n`);
13506
- console.log(` ${chalk31.cyan("info")} Xem chi ti\u1EBFt m\u1ED9t preset`);
13507
- console.log(` ${chalk31.cyan("init")} Kh\u1EDFi t\u1EA1o rules t\u1EEB preset`);
13508
- console.log(` ${chalk31.cyan("apply")} \xC1p d\u1EE5ng preset v\xE0o project`);
13509
- console.log(` ${chalk31.cyan("sync")} \u0110\u1ED3ng b\u1ED9 rules sang c\xE1c \u0111\u1ECBnh d\u1EA1ng IDE`);
13510
- console.log(` ${chalk31.cyan("restore")} Kh\xF4i ph\u1EE5c rules t\u1EEB backup`);
13103
+ console.log(chalk32.bold("C\xE1c l\u1EC7nh:"));
13104
+ console.log(` ${chalk32.cyan("list")} Li\u1EC7t k\xEA c\xE1c presets c\xF3 s\u1EB5n`);
13105
+ console.log(` ${chalk32.cyan("info")} Xem chi ti\u1EBFt m\u1ED9t preset`);
13106
+ console.log(` ${chalk32.cyan("init")} Kh\u1EDFi t\u1EA1o rules t\u1EEB preset`);
13107
+ console.log(` ${chalk32.cyan("apply")} \xC1p d\u1EE5ng preset v\xE0o project`);
13108
+ console.log(` ${chalk32.cyan("sync")} \u0110\u1ED3ng b\u1ED9 rules sang c\xE1c \u0111\u1ECBnh d\u1EA1ng IDE`);
13109
+ console.log(` ${chalk32.cyan("restore")} Kh\xF4i ph\u1EE5c rules t\u1EEB backup`);
13511
13110
  console.log();
13512
- console.log(chalk31.bold("V\xED d\u1EE5:"));
13513
- console.log(chalk31.dim(" $ jai1 rules list"));
13514
- console.log(chalk31.dim(" $ jai1 rules info react-typescript"));
13515
- console.log(chalk31.dim(" $ jai1 rules init --preset=react-typescript"));
13516
- console.log(chalk31.dim(" $ jai1 rules apply react-typescript"));
13111
+ console.log(chalk32.bold("V\xED d\u1EE5:"));
13112
+ console.log(chalk32.dim(" $ jai1 rules list"));
13113
+ console.log(chalk32.dim(" $ jai1 rules info react-typescript"));
13114
+ console.log(chalk32.dim(" $ jai1 rules init --preset=react-typescript"));
13115
+ console.log(chalk32.dim(" $ jai1 rules apply react-typescript"));
13517
13116
  console.log();
13518
- console.log(chalk31.dim('Ch\u1EA1y "jai1 rules <l\u1EC7nh> --help" \u0111\u1EC3 xem chi ti\u1EBFt'));
13117
+ console.log(chalk32.dim('Ch\u1EA1y "jai1 rules <l\u1EC7nh> --help" \u0111\u1EC3 xem chi ti\u1EBFt'));
13519
13118
  }
13520
13119
  function createRulesCommand() {
13521
13120
  const rulesCommand = new Command67("rules").description("Manage rule presets for AI agents").action(() => {
@@ -15248,92 +14847,11 @@ async function resetSettings2(groupKeys) {
15248
14847
  console.log("\u{1F4A1} M\u1EB9o: Kh\u1EDFi \u0111\u1ED9ng l\u1EA1i VSCode \u0111\u1EC3 \xE1p d\u1EE5ng c\xE1c thay \u0111\u1ED5i.");
15249
14848
  }
15250
14849
 
15251
- // src/commands/context.ts
15252
- import React32 from "react";
15253
- import { render as render6 } from "ink";
15254
- import { Command as Command77 } from "commander";
15255
- function createContextCommand() {
15256
- const cmd = new Command77("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) => {
15257
- let initialIDE;
15258
- if (options.ide) {
15259
- const validIDEs = ["cursor", "windsurf", "antigravity", "jai1"];
15260
- if (!validIDEs.includes(options.ide)) {
15261
- console.error(`\u274C IDE kh\xF4ng h\u1EE3p l\u1EC7: ${options.ide}`);
15262
- console.error(` IDE h\u1EE3p l\u1EC7: ${validIDEs.join(", ")}`);
15263
- process.exit(1);
15264
- }
15265
- initialIDE = options.ide;
15266
- }
15267
- let initialType;
15268
- if (options.type) {
15269
- const validTypes = ["rules", "workflows", "skills", "agents", "prompts", "context"];
15270
- if (!validTypes.includes(options.type)) {
15271
- console.error(`\u274C Lo\u1EA1i context kh\xF4ng h\u1EE3p l\u1EC7: ${options.type}`);
15272
- console.error(` Lo\u1EA1i h\u1EE3p l\u1EC7: ${validTypes.join(", ")}`);
15273
- process.exit(1);
15274
- }
15275
- initialType = options.type;
15276
- }
15277
- if (options.stats) {
15278
- await printStats2();
15279
- return;
15280
- }
15281
- const { waitUntilExit } = render6(
15282
- React32.createElement(ContextApp, {
15283
- initialIDE,
15284
- initialType,
15285
- onExit: () => {
15286
- process.exit(0);
15287
- }
15288
- })
15289
- );
15290
- await waitUntilExit();
15291
- });
15292
- return cmd;
15293
- }
15294
- async function printStats2() {
15295
- const scanner = new ContextScannerService();
15296
- console.log("\u{1F50D} \u0110ang qu\xE9t context...\n");
15297
- try {
15298
- const context = await scanner.scanAll();
15299
- if (context.ides.length === 0) {
15300
- console.log("\u26A0\uFE0F Kh\xF4ng t\xECm th\u1EA5y context n\xE0o");
15301
- console.log(" H\xE3y ch\u1EA1y `jai1 apply` \u0111\u1EC3 c\xE0i \u0111\u1EB7t context cho IDE c\u1EE7a b\u1EA1n.\n");
15302
- return;
15303
- }
15304
- console.log("\u{1F4CA} Th\u1ED1ng k\xEA Context\n");
15305
- console.log(`\u{1F4C1} Project: ${context.projectPath}`);
15306
- console.log(`\u{1F550} Scan time: ${context.scanTime.toLocaleString("vi-VN")}
15307
- `);
15308
- for (const ideContext of context.ides) {
15309
- console.log(`${ideContext.config.icon} ${ideContext.config.name}`);
15310
- console.log(` Path: ${ideContext.config.basePath}`);
15311
- console.log(` Items: ${ideContext.stats.totalItems}`);
15312
- const types = [];
15313
- if (ideContext.stats.byType.rules) types.push(`${ideContext.stats.byType.rules} rules`);
15314
- if (ideContext.stats.byType.workflows) types.push(`${ideContext.stats.byType.workflows} workflows`);
15315
- if (ideContext.stats.byType.skills) types.push(`${ideContext.stats.byType.skills} skills`);
15316
- if (ideContext.stats.byType.agents) types.push(`${ideContext.stats.byType.agents} agents`);
15317
- if (ideContext.stats.byType.prompts) types.push(`${ideContext.stats.byType.prompts} prompts`);
15318
- if (ideContext.stats.byType.context) types.push(`${ideContext.stats.byType.context} context`);
15319
- if (types.length > 0) {
15320
- console.log(` Breakdown: ${types.join(", ")}`);
15321
- }
15322
- console.log("");
15323
- }
15324
- console.log(`\u2705 T\u1ED5ng: ${context.totalItems} items
15325
- `);
15326
- } catch (error) {
15327
- console.error("\u274C L\u1ED7i khi qu\xE9t context:", error);
15328
- process.exit(1);
15329
- }
15330
- }
15331
-
15332
14850
  // src/commands/migrate-ide.ts
15333
- import { Command as Command78 } from "commander";
14851
+ import { Command as Command77 } from "commander";
15334
14852
  import { checkbox as checkbox8, confirm as confirm19 } from "@inquirer/prompts";
15335
14853
  function createMigrateIdeCommand() {
15336
- const cmd = new Command78("migrate-ide").description("Migrate .jai1 rules v\xE0 workflows sang IDEs (Cursor, Windsurf, Claude Code, etc.)").option("--ide <ides...>", "Target IDEs (cursor, windsurf, antigravity, claudecode, opencode)").option("--type <types...>", "Content types (rules, workflows, commands)").option("--dry-run", "Preview changes without writing files").action(async (options) => {
14854
+ const cmd = new Command77("migrate-ide").description("Migrate .jai1 rules v\xE0 workflows sang IDEs (Cursor, Windsurf, Claude Code, etc.)").option("--ide <ides...>", "Target IDEs (cursor, windsurf, antigravity, claudecode, opencode)").option("--type <types...>", "Content types (rules, workflows, commands)").option("--dry-run", "Preview changes without writing files").action(async (options) => {
15337
14855
  await runMigrateIde(options);
15338
14856
  });
15339
14857
  return cmd;
@@ -15442,62 +14960,62 @@ async function runMigrateIde(options) {
15442
14960
 
15443
14961
  // src/utils/help-formatter.ts
15444
14962
  import boxen4 from "boxen";
15445
- import chalk32 from "chalk";
14963
+ import chalk33 from "chalk";
15446
14964
  import gradient from "gradient-string";
15447
14965
  import figlet from "figlet";
15448
14966
  function showCustomHelp(version) {
15449
14967
  const title = figlet.textSync("JAI1", { font: "Small" });
15450
14968
  console.log(gradient.pastel(title));
15451
14969
  console.log(
15452
- boxen4(chalk32.cyan(`Agentic Coding CLI v${version}`), {
14970
+ boxen4(chalk33.cyan(`Agentic Coding CLI v${version}`), {
15453
14971
  padding: { left: 1, right: 1, top: 0, bottom: 0 },
15454
14972
  borderStyle: "round",
15455
14973
  borderColor: "cyan"
15456
14974
  })
15457
14975
  );
15458
- console.log(chalk32.bold("\n\u{1F527} Thi\u1EBFt l\u1EADp & Th\xF4ng tin"));
14976
+ console.log(chalk33.bold("\n\u{1F527} Thi\u1EBFt l\u1EADp & Th\xF4ng tin"));
15459
14977
  console.log(" auth X\xE1c th\u1EF1c v\xE0 c\u1EA5u h\xECnh client");
15460
14978
  console.log(" status Hi\u1EC3n th\u1ECB tr\u1EA1ng th\xE1i c\u1EA5u h\xECnh");
15461
14979
  console.log(" client-info T\u1EA1o th\xF4ng tin client \u0111\u1EC3 g\u1EEDi \u0111\u1ED9i ph\xE1t tri\u1EC3n");
15462
14980
  console.log(" errors Qu\u1EA3n l\xFD error logs c\u1EE5c b\u1ED9");
15463
14981
  console.log(" guide H\u01B0\u1EDBng d\u1EABn s\u1EED d\u1EE5ng nhanh");
15464
14982
  console.log(" doctor Chu\u1EA9n \u0111o\xE1n project hi\u1EC7n t\u1EA1i");
15465
- console.log(chalk32.bold("\n\u{1F4E6} Qu\u1EA3n l\xFD Components"));
14983
+ console.log(chalk33.bold("\n\u{1F4E6} Qu\u1EA3n l\xFD Components"));
15466
14984
  console.log(" apply C\xE0i \u0111\u1EB7t components (interactive)");
15467
14985
  console.log(" update C\u1EADp nh\u1EADt components \u0111\xE3 c\xE0i");
15468
14986
  console.log(" check Ki\u1EC3m tra c\u1EADp nh\u1EADt t\u1EEB server");
15469
- console.log(chalk32.bold("\n\u{1F5A5}\uFE0F IDE & T\xEDch h\u1EE3p"));
14987
+ console.log(chalk33.bold("\n\u{1F5A5}\uFE0F IDE & T\xEDch h\u1EE3p"));
15470
14988
  console.log(" ide L\u1EC7nh c\u1EA5u h\xECnh IDE");
15471
14989
  console.log(" chat Chat AI v\u1EDBi Jai1 LLM Proxy");
15472
14990
  console.log(" openai-keys Th\xF4ng tin API credentials");
15473
- console.log(chalk32.bold("\n\u{1F916} AI Tools"));
14991
+ console.log(chalk33.bold("\n\u{1F916} AI Tools"));
15474
14992
  console.log(" translate D\u1ECBch v\u0103n b\u1EA3n/file b\u1EB1ng AI");
15475
14993
  console.log(" image T\u1EA1o \u1EA3nh (Coming Soon)");
15476
14994
  console.log(" stats Th\u1ED1ng k\xEA s\u1EED d\u1EE5ng LLM");
15477
14995
  console.log(" feedback G\u1EEDi b\xE1o c\xE1o/\u0111\u1EC1 xu\u1EA5t");
15478
- console.log(chalk32.bold("\n\u{1F4C1} Project"));
14996
+ console.log(chalk33.bold("\n\u{1F4C1} Project"));
15479
14997
  console.log(" kit Qu\u1EA3n l\xFD starter kits");
15480
14998
  console.log(" rules Qu\u1EA3n l\xFD rule presets");
15481
14999
  console.log(" deps Qu\u1EA3n l\xFD dependencies");
15482
15000
  console.log(" redmine Redmine context sync");
15483
- console.log(chalk32.bold("\n\u2699\uFE0F B\u1EA3o tr\xEC"));
15001
+ console.log(chalk33.bold("\n\u2699\uFE0F B\u1EA3o tr\xEC"));
15484
15002
  console.log(" upgrade C\u1EADp nh\u1EADt CLI client");
15485
15003
  console.log(" clean D\u1ECDn d\u1EB9p cache/backup");
15486
15004
  console.log(" utils Developer utilities");
15487
15005
  const name = getCliName();
15488
- console.log(chalk32.dim(`
15006
+ console.log(chalk33.dim(`
15489
15007
  S\u1EED d\u1EE5ng: ${name} [l\u1EC7nh] --help \u0111\u1EC3 xem chi ti\u1EBFt`));
15490
15008
  }
15491
15009
  function showUnknownCommand(commandName) {
15492
- console.error(chalk32.red(`\u274C L\u1EC7nh kh\xF4ng t\u1ED3n t\u1EA1i: ${commandName}`));
15010
+ console.error(chalk33.red(`\u274C L\u1EC7nh kh\xF4ng t\u1ED3n t\u1EA1i: ${commandName}`));
15493
15011
  const name = getCliName();
15494
- console.error(chalk32.dim(`
15012
+ console.error(chalk33.dim(`
15495
15013
  G\u1EE3i \xFD: Ch\u1EA1y ${name} --help \u0111\u1EC3 xem danh s\xE1ch l\u1EC7nh`));
15496
15014
  }
15497
15015
 
15498
15016
  // src/cli.ts
15499
15017
  checkNodeVersion();
15500
- var program = new Command79();
15018
+ var program = new Command78();
15501
15019
  if (process.argv.includes("-v") || process.argv.includes("--version")) {
15502
15020
  console.log(package_default.version);
15503
15021
  if (!process.argv.includes("--skip-update-check")) {
@@ -15536,9 +15054,9 @@ program.addCommand(createKitCommand());
15536
15054
  program.addCommand(createRulesCommand());
15537
15055
  program.addCommand(createUpgradeCommand());
15538
15056
  program.addCommand(createCleanCommand());
15539
- var redmineCommand = new Command79("redmine").description("Redmine context sync commands");
15057
+ var redmineCommand = new Command78("redmine").description("Redmine context sync commands");
15540
15058
  redmineCommand.addCommand(createRedmineCheckCommand());
15541
- var syncCommand = new Command79("sync").description("Sync Redmine issues to markdown files");
15059
+ var syncCommand = new Command78("sync").description("Sync Redmine issues to markdown files");
15542
15060
  syncCommand.addCommand(createSyncIssueCommand());
15543
15061
  syncCommand.addCommand(createSyncProjectCommand());
15544
15062
  redmineCommand.addCommand(syncCommand);