@jvittechs/j 1.0.13 → 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 +925 -1395
  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.13",
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,54 +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 AI TOOLS \u2501\u2501\u2501"));
4422
- console.log(` ${chalk7.cyan(`${name} chat`)} Chat AI qua Jai1 LLM Proxy`);
4423
- console.log(` ${chalk7.cyan(`${name} translate`)} D\u1ECBch v\u0103n b\u1EA3n/file b\u1EB1ng AI`);
4424
- console.log(` ${chalk7.cyan(`${name} image`)} T\u1EA1o \u1EA3nh b\u1EB1ng AI`);
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`);
4425
4026
  console.log();
4426
- console.log(chalk7.dim(`\u{1F4A1} Ch\u1EA1y "${name} <l\u1EC7nh> --help" \u0111\u1EC3 xem chi ti\u1EBFt t\u1EEBng l\u1EC7nh.`));
4427
- 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.`));
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"));
4031
+ console.log();
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`);
4036
+ console.log();
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.`));
4428
4039
  console.log();
4429
4040
  }
4430
4041
 
4431
4042
  // src/commands/doctor.ts
4432
4043
  import { Command as Command13 } from "commander";
4433
- import chalk8 from "chalk";
4044
+ import chalk9 from "chalk";
4434
4045
  import { promises as fs9 } from "fs";
4435
4046
  import { join as join6 } from "path";
4436
4047
  var CORE_FILES = [
@@ -4458,8 +4069,8 @@ async function runDoctor(options) {
4458
4069
  const name = getCliName();
4459
4070
  const results = [];
4460
4071
  if (!options.json) {
4461
- console.log(chalk8.cyan.bold("\n\u{1FA7A} Jai1 Doctor\n"));
4462
- 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()}
4463
4074
  `));
4464
4075
  }
4465
4076
  results.push(await checkAuth(name));
@@ -4472,27 +4083,27 @@ async function runDoctor(options) {
4472
4083
  return;
4473
4084
  }
4474
4085
  for (const result of results) {
4475
- const icon = result.passed ? chalk8.green("\u2713") : chalk8.red("\u2717");
4476
- const label = result.passed ? chalk8.green(result.message) : chalk8.red(result.message);
4477
- 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}`);
4478
4089
  if (result.details && result.details.length > 0) {
4479
4090
  for (const detail of result.details) {
4480
- console.log(chalk8.dim(` ${detail}`));
4091
+ console.log(chalk9.dim(` ${detail}`));
4481
4092
  }
4482
4093
  }
4483
4094
  if (!result.passed && result.suggestion) {
4484
- console.log(chalk8.yellow(` \u{1F4A1} ${result.suggestion}`));
4095
+ console.log(chalk9.yellow(` \u{1F4A1} ${result.suggestion}`));
4485
4096
  }
4486
4097
  console.log();
4487
4098
  }
4488
4099
  const passed = results.filter((r) => r.passed).length;
4489
4100
  const total = results.length;
4490
4101
  if (passed === total) {
4491
- 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!
4492
4103
  `));
4493
4104
  } else {
4494
4105
  console.log(
4495
- 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.
4496
4107
  `)
4497
4108
  );
4498
4109
  }
@@ -4644,8 +4255,8 @@ async function checkIde(cliName) {
4644
4255
 
4645
4256
  // src/commands/chat.ts
4646
4257
  import { Command as Command14 } from "commander";
4647
- import React18 from "react";
4648
- import { render as render4 } from "ink";
4258
+ import React12 from "react";
4259
+ import { render as render3 } from "ink";
4649
4260
 
4650
4261
  // src/services/llm-proxy.service.ts
4651
4262
  var LlmProxyService = class {
@@ -4872,16 +4483,16 @@ var LlmProxyService = class {
4872
4483
  };
4873
4484
 
4874
4485
  // src/ui/llm/LlmApp.tsx
4875
- import React17, { useState as useState11, useEffect as useEffect5, useMemo as useMemo3, useCallback as useCallback3, useRef as useRef2 } from "react";
4876
- 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";
4877
4488
  import Spinner4 from "ink-spinner";
4878
4489
 
4879
4490
  // src/ui/llm/hooks/useChat.ts
4880
- import { useState as useState8, useCallback } from "react";
4491
+ import { useState as useState3, useCallback } from "react";
4881
4492
  function useChat(service) {
4882
- const [messages, setMessages] = useState8([]);
4883
- const [isStreaming, setIsStreaming] = useState8(false);
4884
- const [error, setError] = useState8(null);
4493
+ const [messages, setMessages] = useState3([]);
4494
+ const [isStreaming, setIsStreaming] = useState3(false);
4495
+ const [error, setError] = useState3(null);
4885
4496
  const sendMessage = useCallback(
4886
4497
  async (content, model) => {
4887
4498
  if (!content.trim() || isStreaming) return;
@@ -4950,9 +4561,9 @@ function useChat(service) {
4950
4561
  }
4951
4562
 
4952
4563
  // src/ui/llm/hooks/useLlmApi.ts
4953
- 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";
4954
4565
  function useLlmApi(service) {
4955
- const [state, setState] = useState9({
4566
+ const [state, setState] = useState4({
4956
4567
  models: [],
4957
4568
  limits: null,
4958
4569
  usage: null,
@@ -4985,7 +4596,7 @@ function useLlmApi(service) {
4985
4596
  }));
4986
4597
  }
4987
4598
  }, [service]);
4988
- useEffect4(() => {
4599
+ useEffect3(() => {
4989
4600
  if (!hasFetched.current) {
4990
4601
  hasFetched.current = true;
4991
4602
  fetchData(true);
@@ -5001,26 +4612,26 @@ function useLlmApi(service) {
5001
4612
  }
5002
4613
 
5003
4614
  // src/ui/llm/components/ChatPanel.tsx
5004
- import React15, { memo as memo3 } from "react";
5005
- 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";
5006
4617
  import Spinner3 from "ink-spinner";
5007
4618
 
5008
4619
  // src/ui/llm/components/MessageItem.tsx
5009
- import React13, { memo } from "react";
5010
- 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";
5011
4622
  var MessageItem = memo(({ message }) => {
5012
4623
  if (message.role === "user") {
5013
- 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));
5014
4625
  }
5015
4626
  if (message.role === "assistant") {
5016
- 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));
5017
4628
  }
5018
- 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));
5019
4630
  });
5020
4631
 
5021
4632
  // src/ui/llm/components/InputBox.tsx
5022
- import React14, { memo as memo2 } from "react";
5023
- 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";
5024
4635
  import TextInput3 from "ink-text-input";
5025
4636
  var InputBox = memo2(({
5026
4637
  value,
@@ -5028,7 +4639,7 @@ var InputBox = memo2(({
5028
4639
  onSubmit,
5029
4640
  disabled = false,
5030
4641
  focused = true
5031
- }) => /* @__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(
5032
4643
  TextInput3,
5033
4644
  {
5034
4645
  value,
@@ -5037,19 +4648,19 @@ var InputBox = memo2(({
5037
4648
  placeholder: "Type your message...",
5038
4649
  focus: focused
5039
4650
  }
5040
- ) : /* @__PURE__ */ React14.createElement(Text11, { dimColor: true }, "Waiting...")));
4651
+ ) : /* @__PURE__ */ React8.createElement(Text6, { dimColor: true }, "Waiting...")));
5041
4652
 
5042
4653
  // src/ui/llm/components/ChatPanel.tsx
5043
4654
  var MessageList = memo3(({ messages }) => {
5044
4655
  const visible = messages.slice(-8);
5045
4656
  const hidden = messages.length - visible.length;
5046
4657
  if (visible.length === 0) {
5047
- 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"));
5048
4659
  }
5049
- 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 })));
5050
4661
  });
5051
- 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(
5052
- 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,
5053
4664
  {
5054
4665
  key: cmd.name,
5055
4666
  backgroundColor: i === index ? "cyan" : void 0,
@@ -5074,7 +4685,7 @@ var ChatPanel = ({
5074
4685
  minHeight = 15
5075
4686
  }) => {
5076
4687
  const messagesMinHeight = Math.max(5, minHeight - 4 - (showSlashMenu ? 5 : 0));
5077
- 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(
5078
4689
  InputBox,
5079
4690
  {
5080
4691
  value: inputValue,
@@ -5087,8 +4698,8 @@ var ChatPanel = ({
5087
4698
  };
5088
4699
 
5089
4700
  // src/ui/llm/components/ModelSelector.tsx
5090
- import React16, { useState as useState10 } from "react";
5091
- 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";
5092
4703
  var ModelSelector = ({
5093
4704
  models,
5094
4705
  currentModel,
@@ -5097,8 +4708,8 @@ var ModelSelector = ({
5097
4708
  }) => {
5098
4709
  const allowedModels = models.filter((m) => m.allowed);
5099
4710
  const currentIndex = allowedModels.findIndex((m) => m.id === currentModel);
5100
- const [selectedIndex, setSelectedIndex] = useState10(Math.max(0, currentIndex));
5101
- useInput8((input5, key) => {
4711
+ const [selectedIndex, setSelectedIndex] = useState5(Math.max(0, currentIndex));
4712
+ useInput3((input5, key) => {
5102
4713
  if (key.escape) {
5103
4714
  onCancel();
5104
4715
  return;
@@ -5115,8 +4726,8 @@ var ModelSelector = ({
5115
4726
  }
5116
4727
  });
5117
4728
  if (allowedModels.length === 0) {
5118
- return /* @__PURE__ */ React16.createElement(
5119
- Box12,
4729
+ return /* @__PURE__ */ React10.createElement(
4730
+ Box7,
5120
4731
  {
5121
4732
  flexDirection: "column",
5122
4733
  borderStyle: "round",
@@ -5124,12 +4735,12 @@ var ModelSelector = ({
5124
4735
  padding: 1,
5125
4736
  width: 60
5126
4737
  },
5127
- /* @__PURE__ */ React16.createElement(Text13, { color: "red", bold: true }, "No models available"),
5128
- /* @__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")
5129
4740
  );
5130
4741
  }
5131
- return /* @__PURE__ */ React16.createElement(
5132
- Box12,
4742
+ return /* @__PURE__ */ React10.createElement(
4743
+ Box7,
5133
4744
  {
5134
4745
  flexDirection: "column",
5135
4746
  borderStyle: "round",
@@ -5137,8 +4748,8 @@ var ModelSelector = ({
5137
4748
  padding: 1,
5138
4749
  width: 70
5139
4750
  },
5140
- /* @__PURE__ */ React16.createElement(Box12, { marginBottom: 1 }, /* @__PURE__ */ React16.createElement(Text13, { bold: true, color: "cyan" }, "\u2699\uFE0F Select Model")),
5141
- /* @__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) => {
5142
4753
  const isSelected = i === selectedIndex;
5143
4754
  const isCurrent = model.id === currentModel;
5144
4755
  const icon = isSelected ? "\u25CF" : "\u25CB";
@@ -5146,8 +4757,8 @@ var ModelSelector = ({
5146
4757
  if (model.dailyLimit !== void 0 && model.usedToday !== void 0) {
5147
4758
  usageText = ` (${model.usedToday}/${model.dailyLimit})`;
5148
4759
  }
5149
- return /* @__PURE__ */ React16.createElement(Box12, { key: model.id, marginY: 0 }, /* @__PURE__ */ React16.createElement(
5150
- Text13,
4760
+ return /* @__PURE__ */ React10.createElement(Box7, { key: model.id, marginY: 0 }, /* @__PURE__ */ React10.createElement(
4761
+ Text8,
5151
4762
  {
5152
4763
  backgroundColor: isSelected ? "cyan" : void 0,
5153
4764
  color: isSelected ? "black" : "white"
@@ -5160,7 +4771,7 @@ var ModelSelector = ({
5160
4771
  usageText
5161
4772
  ));
5162
4773
  })),
5163
- /* @__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"))
5164
4775
  );
5165
4776
  };
5166
4777
 
@@ -5171,17 +4782,17 @@ var SLASH_COMMANDS = [
5171
4782
  { name: "quit", description: "Exit the chat", aliases: ["q", "exit"] }
5172
4783
  ];
5173
4784
  var ChatApp = ({ service, initialModel }) => {
5174
- const { exit } = useApp4();
4785
+ const { exit } = useApp3();
5175
4786
  const { stdout } = useStdout();
5176
4787
  const contentHeight = useRef2(Math.max(10, (stdout?.rows || 24) - 6));
5177
- const [currentView, setCurrentView] = useState11("loading");
5178
- const [showSlashMenu, setShowSlashMenu] = useState11(false);
5179
- const [slashMenuIndex, setSlashMenuIndex] = useState11(0);
5180
- const [inputValue, setInputValue] = useState11("");
5181
- 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("");
5182
4793
  const { models, loading, error, refetch } = useLlmApi(service);
5183
4794
  const { messages, isStreaming, sendMessage } = useChat(service);
5184
- useEffect5(() => {
4795
+ useEffect4(() => {
5185
4796
  if (error && !loading) {
5186
4797
  setCurrentView("error");
5187
4798
  return;
@@ -5224,7 +4835,7 @@ var ChatApp = ({ service, initialModel }) => {
5224
4835
  }
5225
4836
  return false;
5226
4837
  }, [refetch, exit]);
5227
- useInput9((input5, key) => {
4838
+ useInput4((input5, key) => {
5228
4839
  if (showSlashMenu) {
5229
4840
  if (key.upArrow) {
5230
4841
  setSlashMenuIndex((i) => Math.max(0, i - 1));
@@ -5285,16 +4896,16 @@ var ChatApp = ({ service, initialModel }) => {
5285
4896
  }, []);
5286
4897
  const statsView = useMemo3(() => {
5287
4898
  const allowed = models.filter((m) => m.allowed);
5288
- 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) => {
5289
4900
  const limit = m.dailyLimit ?? 0;
5290
4901
  const used = m.usedToday ?? 0;
5291
4902
  const pct = limit > 0 ? Math.round(used / limit * 100) : 0;
5292
4903
  const bar = "\u2588".repeat(Math.round(pct / 5)) + "\u2591".repeat(20 - Math.round(pct / 5));
5293
- 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)));
5294
- }), /* @__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"));
5295
4906
  }, [models, selectedModel]);
5296
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";
5297
- 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(
5298
4909
  ModelSelector,
5299
4910
  {
5300
4911
  models,
@@ -5302,7 +4913,7 @@ var ChatApp = ({ service, initialModel }) => {
5302
4913
  onSelect: onSelectModel,
5303
4914
  onCancel: () => setCurrentView("chat")
5304
4915
  }
5305
- )) : 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(
5306
4917
  ChatPanel,
5307
4918
  {
5308
4919
  messages,
@@ -5316,7 +4927,7 @@ var ChatApp = ({ service, initialModel }) => {
5316
4927
  slashMenuIndex,
5317
4928
  minHeight: contentHeight.current
5318
4929
  }
5319
- ), /* @__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)));
5320
4931
  };
5321
4932
 
5322
4933
  // src/server/web-chat-server.ts
@@ -6220,8 +5831,8 @@ async function handleTerminalChat(options) {
6220
5831
  throw new ValidationError('Not initialized. Run "jai1 auth" first.');
6221
5832
  }
6222
5833
  const service = new LlmProxyService(config);
6223
- const { waitUntilExit, clear } = render4(
6224
- React18.createElement(ChatApp, {
5834
+ const { waitUntilExit, clear } = render3(
5835
+ React12.createElement(ChatApp, {
6225
5836
  service,
6226
5837
  initialModel: options.model
6227
5838
  }),
@@ -6293,7 +5904,7 @@ function createChatCommand() {
6293
5904
 
6294
5905
  // src/commands/openai-keys.ts
6295
5906
  import { Command as Command15 } from "commander";
6296
- import chalk9 from "chalk";
5907
+ import chalk10 from "chalk";
6297
5908
  import boxen3 from "boxen";
6298
5909
  function maskKey2(key) {
6299
5910
  if (key.length <= 8) return "****";
@@ -6307,17 +5918,17 @@ async function handleOpenAiKeysCommand(options) {
6307
5918
  }
6308
5919
  const service = new LlmProxyService(config);
6309
5920
  console.log(
6310
- 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"), {
6311
5922
  padding: { top: 0, bottom: 0, left: 1, right: 1 },
6312
5923
  borderStyle: "round",
6313
5924
  borderColor: "cyan"
6314
5925
  })
6315
5926
  );
6316
5927
  console.log();
6317
- console.log(chalk9.bold("\u{1F511} API Credentials"));
6318
- 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())}`);
6319
5930
  console.log(
6320
- ` ${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()))}`
6321
5932
  );
6322
5933
  console.log();
6323
5934
  try {
@@ -6326,39 +5937,39 @@ async function handleOpenAiKeysCommand(options) {
6326
5937
  service.getLimits()
6327
5938
  ]);
6328
5939
  const allowedModels = models.filter((m) => m.allowed);
6329
- console.log(chalk9.bold("\u{1F4E6} Available Models"));
5940
+ console.log(chalk10.bold("\u{1F4E6} Available Models"));
6330
5941
  if (allowedModels.length === 0) {
6331
- 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"));
6332
5943
  } else {
6333
5944
  for (const model of allowedModels) {
6334
- const usageText = model.dailyLimit !== void 0 && model.usedToday !== void 0 ? chalk9.dim(` (${model.usedToday}/${model.dailyLimit} h\xF4m nay)`) : "";
6335
- 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}`);
6336
5947
  }
6337
5948
  }
6338
5949
  console.log();
6339
5950
  const defaultModel = allowedModels[0]?.id || "gpt-4o";
6340
- console.log(chalk9.bold("\u{1F4DD} Sample cURL"));
5951
+ console.log(chalk10.bold("\u{1F4DD} Sample cURL"));
6341
5952
  console.log();
6342
5953
  const curlSample = options.full ? service.generateFullCurlSample(defaultModel) : service.generateCurlSample(defaultModel);
6343
5954
  const curlLines = curlSample.split("\n");
6344
5955
  for (const line of curlLines) {
6345
- console.log(chalk9.dim(` ${line}`));
5956
+ console.log(chalk10.dim(` ${line}`));
6346
5957
  }
6347
5958
  console.log();
6348
- console.log(chalk9.bold("\u{1F4A1} C\xE1ch s\u1EED d\u1EE5ng"));
6349
- console.log(chalk9.dim(" - Thay th\u1EBF OpenAI API URL v\xE0 API Key"));
6350
- console.log(chalk9.dim(" - T\u01B0\u01A1ng th\xEDch: OpenAI SDK, LangChain, LlamaIndex, v.v."));
6351
- 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'));
6352
5963
  if (!options.full) {
6353
- 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'));
6354
5965
  }
6355
5966
  } catch (error) {
6356
5967
  console.log();
6357
5968
  console.log(
6358
- chalk9.red("\u274C L\u1ED7i khi l\u1EA5y th\xF4ng tin API:"),
6359
- 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))
6360
5971
  );
6361
- 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"'));
6362
5973
  }
6363
5974
  }
6364
5975
  function createOpenAiKeysCommand() {
@@ -6371,7 +5982,7 @@ function createOpenAiKeysCommand() {
6371
5982
  // src/commands/stats.ts
6372
5983
  import { Command as Command16 } from "commander";
6373
5984
  import Table2 from "cli-table3";
6374
- import chalk10 from "chalk";
5985
+ import chalk11 from "chalk";
6375
5986
  async function handleStatsCommand() {
6376
5987
  const configService = new ConfigService();
6377
5988
  const config = await configService.load();
@@ -6381,8 +5992,8 @@ async function handleStatsCommand() {
6381
5992
  );
6382
5993
  }
6383
5994
  const service = new LlmProxyService(config);
6384
- console.log(chalk10.bold("\n\u{1F4CA} Th\u1ED1ng K\xEA S\u1EED D\u1EE5ng LLM"));
6385
- 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)));
6386
5997
  try {
6387
5998
  const [limits, usage7Days, usageToday] = await Promise.all([
6388
5999
  service.getLimits(),
@@ -6392,7 +6003,7 @@ async function handleStatsCommand() {
6392
6003
  const today = (/* @__PURE__ */ new Date()).toLocaleDateString("en-CA", {
6393
6004
  timeZone: "Asia/Ho_Chi_Minh"
6394
6005
  });
6395
- 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"));
6396
6007
  const usageByModel = /* @__PURE__ */ new Map();
6397
6008
  let total7DaysRequests = 0;
6398
6009
  usage7Days.data?.forEach((record) => {
@@ -6412,16 +6023,16 @@ async function handleStatsCommand() {
6412
6023
  modelData.today = record.count;
6413
6024
  }
6414
6025
  });
6415
- console.log(chalk10.bold("\u{1F4C8} T\u1ED5ng quan s\u1EED d\u1EE5ng"));
6416
- 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)}
6417
6028
  `);
6418
- 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"));
6419
6030
  const table = new Table2({
6420
6031
  head: [
6421
- chalk10.bold("Model"),
6422
- chalk10.bold("H\xF4m nay"),
6423
- chalk10.bold("Gi\u1EDBi h\u1EA1n"),
6424
- 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")
6425
6036
  ],
6426
6037
  style: {
6427
6038
  head: ["cyan"],
@@ -6433,7 +6044,7 @@ async function handleStatsCommand() {
6433
6044
  const rateLimits = limits.effectiveRateLimits || {};
6434
6045
  if (allowedModels.length === 0) {
6435
6046
  table.push([
6436
- { 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") }
6437
6048
  ]);
6438
6049
  } else {
6439
6050
  allowedModels.forEach((modelId) => {
@@ -6442,25 +6053,25 @@ async function handleStatsCommand() {
6442
6053
  const usagePercent = limit > 0 ? usage.today / limit : 0;
6443
6054
  let todayDisplay = `${usage.today}/${limit}`;
6444
6055
  if (usagePercent >= 0.9) {
6445
- todayDisplay = chalk10.red(todayDisplay);
6056
+ todayDisplay = chalk11.red(todayDisplay);
6446
6057
  } else if (usagePercent >= 0.7) {
6447
- todayDisplay = chalk10.yellow(todayDisplay);
6058
+ todayDisplay = chalk11.yellow(todayDisplay);
6448
6059
  } else {
6449
- todayDisplay = chalk10.green(todayDisplay);
6060
+ todayDisplay = chalk11.green(todayDisplay);
6450
6061
  }
6451
6062
  table.push([modelId, todayDisplay, `${limit}/ng\xE0y`, String(usage.total7Days)]);
6452
6063
  });
6453
6064
  }
6454
6065
  console.log(table.toString());
6455
6066
  console.log(
6456
- 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')
6457
6068
  );
6458
6069
  } catch (error) {
6459
6070
  console.error(
6460
- 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:"),
6461
6072
  error instanceof Error ? error.message : String(error)
6462
6073
  );
6463
- 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"'));
6464
6075
  }
6465
6076
  }
6466
6077
  function createStatsCommand() {
@@ -6827,7 +6438,7 @@ function createTranslateCommand() {
6827
6438
 
6828
6439
  // src/commands/image/index.ts
6829
6440
  import { Command as Command22 } from "commander";
6830
- import chalk11 from "chalk";
6441
+ import chalk12 from "chalk";
6831
6442
 
6832
6443
  // src/commands/image/gen.ts
6833
6444
  import { Command as Command18 } from "commander";
@@ -7102,22 +6713,22 @@ function createImageDeleteCommand() {
7102
6713
 
7103
6714
  // src/commands/image/index.ts
7104
6715
  function showImageHelp() {
7105
- 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"));
7106
6717
  console.log();
7107
- 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"));
7108
6719
  console.log();
7109
- console.log(chalk11.bold("C\xE1c l\u1EC7nh:"));
7110
- console.log(` ${chalk11.cyan("gen")} T\u1EA1o \u1EA3nh t\u1EEB prompt`);
7111
- console.log(` ${chalk11.cyan("list")} Li\u1EC7t k\xEA c\xE1c \u1EA3nh \u0111\xE3 t\u1EA1o`);
7112
- console.log(` ${chalk11.cyan("info")} Xem th\xF4ng tin \u1EA3nh`);
7113
- 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`);
7114
6725
  console.log();
7115
- console.log(chalk11.bold("V\xED d\u1EE5:"));
7116
- console.log(chalk11.dim(' $ jai1 image gen "a cute cat"'));
7117
- console.log(chalk11.dim(" $ jai1 image list"));
7118
- 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>"));
7119
6730
  console.log();
7120
- 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'));
7121
6732
  }
7122
6733
  function createImageCommand() {
7123
6734
  const cmd = new Command22("image").description("Image generation commands (Coming Soon)").action(() => {
@@ -7618,11 +7229,11 @@ async function confirmSubmit(summary, jsonMode) {
7618
7229
 
7619
7230
  // src/commands/errors/index.ts
7620
7231
  import { Command as Command28 } from "commander";
7621
- import chalk13 from "chalk";
7232
+ import chalk14 from "chalk";
7622
7233
 
7623
7234
  // src/commands/errors/list.ts
7624
7235
  import { Command as Command25 } from "commander";
7625
- import chalk12 from "chalk";
7236
+ import chalk13 from "chalk";
7626
7237
  import Table3 from "cli-table3";
7627
7238
  function createErrorsListSubcommand() {
7628
7239
  return new Command25("list").description("Danh s\xE1ch error logs").option("--json", "Output JSON format").action(async (options) => {
@@ -7659,7 +7270,7 @@ function createErrorsListSubcommand() {
7659
7270
  });
7660
7271
  for (const log of logs) {
7661
7272
  table.push([
7662
- chalk12.cyan(log.id),
7273
+ chalk13.cyan(log.id),
7663
7274
  log.timestamp || "-",
7664
7275
  log.command || "-",
7665
7276
  log.message || "-"
@@ -7738,19 +7349,19 @@ function createErrorsClearSubcommand() {
7738
7349
 
7739
7350
  // src/commands/errors/index.ts
7740
7351
  function showErrorsHelp() {
7741
- 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"));
7742
7353
  console.log();
7743
- console.log(chalk13.bold("C\xE1c l\u1EC7nh:"));
7744
- console.log(` ${chalk13.cyan("list")} Danh s\xE1ch error logs`);
7745
- console.log(` ${chalk13.cyan("show")} Xem chi ti\u1EBFt error log`);
7746
- 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`);
7747
7358
  console.log();
7748
- console.log(chalk13.bold("V\xED d\u1EE5:"));
7749
- console.log(chalk13.dim(" $ jai1 errors list"));
7750
- console.log(chalk13.dim(" $ jai1 errors show <id>"));
7751
- 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"));
7752
7363
  console.log();
7753
- 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'));
7754
7365
  }
7755
7366
  function createErrorsCommand() {
7756
7367
  const errorsCommand = new Command28("errors").description("Manage local error logs").action(() => {
@@ -7764,7 +7375,7 @@ function createErrorsCommand() {
7764
7375
 
7765
7376
  // src/commands/utils/index.ts
7766
7377
  import { Command as Command42 } from "commander";
7767
- import chalk14 from "chalk";
7378
+ import chalk15 from "chalk";
7768
7379
 
7769
7380
  // src/commands/utils/password.ts
7770
7381
  import { Command as Command29 } from "commander";
@@ -8686,28 +8297,28 @@ Examples:
8686
8297
  }
8687
8298
 
8688
8299
  // src/commands/utils/interactive.ts
8689
- import React31 from "react";
8690
- import { render as render5 } from "ink";
8300
+ import React25 from "react";
8301
+ import { render as render4 } from "ink";
8691
8302
 
8692
8303
  // src/ui/utils/UtilsApp.tsx
8693
- import React30, { useState as useState23 } from "react";
8694
- 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";
8695
8306
 
8696
8307
  // src/ui/utils/views/PasswordView.tsx
8697
- import React19, { useState as useState12 } from "react";
8698
- 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";
8699
8310
  import TextInput4 from "ink-text-input";
8700
8311
  var PasswordView = () => {
8701
- const [length, setLength] = useState12("16");
8702
- const [count, setCount] = useState12("1");
8703
- const [passwords, setPasswords] = useState12([]);
8704
- const [focusedField, setFocusedField] = useState12("length");
8705
- 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);
8706
8317
  const service = new UtilsService();
8707
- React19.useEffect(() => {
8318
+ React13.useEffect(() => {
8708
8319
  handleGenerate();
8709
8320
  }, []);
8710
- useInput10((input5, key) => {
8321
+ useInput5((input5, key) => {
8711
8322
  if (key.tab) {
8712
8323
  if (focusedField === "length") setFocusedField("count");
8713
8324
  else if (focusedField === "count") setFocusedField("generate");
@@ -8745,8 +8356,8 @@ var PasswordView = () => {
8745
8356
  } catch (error) {
8746
8357
  }
8747
8358
  };
8748
- 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(
8749
- 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,
8750
8361
  {
8751
8362
  flexDirection: "column",
8752
8363
  borderStyle: "single",
@@ -8755,11 +8366,11 @@ var PasswordView = () => {
8755
8366
  paddingY: 1,
8756
8367
  marginBottom: 1
8757
8368
  },
8758
- /* @__PURE__ */ React19.createElement(Text15, { bold: true, color: "yellow", marginBottom: 1 }, "Options:"),
8759
- /* @__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)")),
8760
- /* @__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)")),
8761
- /* @__PURE__ */ React19.createElement(Box14, { marginTop: 1 }, /* @__PURE__ */ React19.createElement(
8762
- 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,
8763
8374
  {
8764
8375
  bold: true,
8765
8376
  backgroundColor: focusedField === "generate" ? "green" : void 0,
@@ -8768,8 +8379,8 @@ var PasswordView = () => {
8768
8379
  focusedField === "generate" ? "\u25B6 " : " ",
8769
8380
  "[ Generate Passwords ]"
8770
8381
  ))
8771
- ), passwords.length > 0 && /* @__PURE__ */ React19.createElement(
8772
- Box14,
8382
+ ), passwords.length > 0 && /* @__PURE__ */ React13.createElement(
8383
+ Box9,
8773
8384
  {
8774
8385
  flexDirection: "column",
8775
8386
  borderStyle: "single",
@@ -8777,27 +8388,27 @@ var PasswordView = () => {
8777
8388
  paddingX: 2,
8778
8389
  paddingY: 1
8779
8390
  },
8780
- /* @__PURE__ */ React19.createElement(Text15, { bold: true, color: "green", marginBottom: 1 }, "\u2713 Generated Passwords:"),
8781
- 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!")))
8782
- ), /* @__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")));
8783
8394
  };
8784
8395
 
8785
8396
  // src/ui/utils/views/UuidView.tsx
8786
- import React20, { useState as useState13 } from "react";
8787
- 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";
8788
8399
  import TextInput5 from "ink-text-input";
8789
8400
  var UuidView = () => {
8790
- const [count, setCount] = useState13("1");
8791
- const [uppercase, setUppercase] = useState13(false);
8792
- const [noHyphens, setNoHyphens] = useState13(false);
8793
- const [uuids, setUuids] = useState13([]);
8794
- const [focusedField, setFocusedField] = useState13("count");
8795
- 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);
8796
8407
  const service = new UtilsService();
8797
- React20.useEffect(() => {
8408
+ React14.useEffect(() => {
8798
8409
  handleGenerate();
8799
8410
  }, []);
8800
- useInput11((input5, key) => {
8411
+ useInput6((input5, key) => {
8801
8412
  if (key.tab) {
8802
8413
  const fields = ["count", "uppercase", "hyphens", "generate"];
8803
8414
  const currentIndex = fields.indexOf(focusedField);
@@ -8832,8 +8443,8 @@ var UuidView = () => {
8832
8443
  } catch (error) {
8833
8444
  }
8834
8445
  };
8835
- 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(
8836
- 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,
8837
8448
  {
8838
8449
  flexDirection: "column",
8839
8450
  borderStyle: "single",
@@ -8842,12 +8453,12 @@ var UuidView = () => {
8842
8453
  paddingY: 1,
8843
8454
  marginBottom: 1
8844
8455
  },
8845
- /* @__PURE__ */ React20.createElement(Text16, { bold: true, color: "yellow", marginBottom: 1 }, "Options:"),
8846
- /* @__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))),
8847
- /* @__PURE__ */ React20.createElement(Box15, { marginBottom: 1 }, /* @__PURE__ */ React20.createElement(Text16, { color: focusedField === "uppercase" ? "green" : void 0 }, focusedField === "uppercase" ? "\u25B6 " : " ", "[", uppercase ? "\u2713" : " ", "] Uppercase")),
8848
- /* @__PURE__ */ React20.createElement(Box15, { marginBottom: 1 }, /* @__PURE__ */ React20.createElement(Text16, { color: focusedField === "hyphens" ? "green" : void 0 }, focusedField === "hyphens" ? "\u25B6 " : " ", "[", noHyphens ? "\u2713" : " ", "] No Hyphens")),
8849
- /* @__PURE__ */ React20.createElement(Box15, { marginTop: 1 }, /* @__PURE__ */ React20.createElement(
8850
- 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,
8851
8462
  {
8852
8463
  bold: true,
8853
8464
  backgroundColor: focusedField === "generate" ? "green" : void 0,
@@ -8856,8 +8467,8 @@ var UuidView = () => {
8856
8467
  focusedField === "generate" ? "\u25B6 " : " ",
8857
8468
  "[ Generate UUIDs ]"
8858
8469
  ))
8859
- ), uuids.length > 0 && /* @__PURE__ */ React20.createElement(
8860
- Box15,
8470
+ ), uuids.length > 0 && /* @__PURE__ */ React14.createElement(
8471
+ Box10,
8861
8472
  {
8862
8473
  flexDirection: "column",
8863
8474
  borderStyle: "single",
@@ -8865,27 +8476,27 @@ var UuidView = () => {
8865
8476
  paddingX: 2,
8866
8477
  paddingY: 1
8867
8478
  },
8868
- /* @__PURE__ */ React20.createElement(Text16, { bold: true, color: "green", marginBottom: 1 }, "\u2713 Generated UUIDs:"),
8869
- 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!")))
8870
- ), /* @__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")));
8871
8482
  };
8872
8483
 
8873
8484
  // src/ui/utils/views/HashView.tsx
8874
- import React21, { useState as useState14 } from "react";
8875
- 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";
8876
8487
  import TextInput6 from "ink-text-input";
8877
8488
  var ALGORITHMS = ["sha256", "sha512", "sha1", "md5", "bcrypt"];
8878
8489
  var HashView = () => {
8879
- const [text, setText] = useState14("hello world");
8880
- const [algorithm, setAlgorithm] = useState14("sha256");
8881
- const [hash, setHash] = useState14("");
8882
- const [focusedField, setFocusedField] = useState14("text");
8883
- 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);
8884
8495
  const service = new UtilsService();
8885
- React21.useEffect(() => {
8496
+ React15.useEffect(() => {
8886
8497
  handleGenerate();
8887
8498
  }, []);
8888
- useInput12((input5, key) => {
8499
+ useInput7((input5, key) => {
8889
8500
  if (key.tab) {
8890
8501
  const fields = ["text", "algorithm", "generate"];
8891
8502
  const currentIndex = fields.indexOf(focusedField);
@@ -8922,8 +8533,8 @@ var HashView = () => {
8922
8533
  } catch (error) {
8923
8534
  }
8924
8535
  };
8925
- 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(
8926
- 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,
8927
8538
  {
8928
8539
  flexDirection: "column",
8929
8540
  borderStyle: "single",
@@ -8932,11 +8543,11 @@ var HashView = () => {
8932
8543
  paddingY: 1,
8933
8544
  marginBottom: 1
8934
8545
  },
8935
- /* @__PURE__ */ React21.createElement(Text17, { bold: true, color: "yellow", marginBottom: 1 }, "Options:"),
8936
- /* @__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)"))),
8937
- /* @__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)")),
8938
- /* @__PURE__ */ React21.createElement(Box16, { marginTop: 1 }, /* @__PURE__ */ React21.createElement(
8939
- 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,
8940
8551
  {
8941
8552
  bold: true,
8942
8553
  backgroundColor: focusedField === "generate" ? "green" : void 0,
@@ -8945,8 +8556,8 @@ var HashView = () => {
8945
8556
  focusedField === "generate" ? "\u25B6 " : " ",
8946
8557
  "[ Generate Hash ]"
8947
8558
  ))
8948
- ), hash && /* @__PURE__ */ React21.createElement(
8949
- Box16,
8559
+ ), hash && /* @__PURE__ */ React15.createElement(
8560
+ Box11,
8950
8561
  {
8951
8562
  flexDirection: "column",
8952
8563
  borderStyle: "single",
@@ -8954,25 +8565,25 @@ var HashView = () => {
8954
8565
  paddingX: 2,
8955
8566
  paddingY: 1
8956
8567
  },
8957
- /* @__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!"))),
8958
- /* @__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)))
8959
- ), /* @__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")));
8960
8571
  };
8961
8572
 
8962
8573
  // src/ui/utils/views/Base64View.tsx
8963
- import React22, { useState as useState15 } from "react";
8964
- 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";
8965
8576
  import TextInput7 from "ink-text-input";
8966
8577
  var Base64View = () => {
8967
- const [input5, setInput] = useState15("");
8968
- const [mode, setMode] = useState15("encode");
8969
- const [urlSafe, setUrlSafe] = useState15(false);
8970
- const [result, setResult] = useState15("");
8971
- const [error, setError] = useState15("");
8972
- const [focusedField, setFocusedField] = useState15("input");
8973
- 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);
8974
8585
  const service = new UtilsService();
8975
- useInput13((input6, key) => {
8586
+ useInput8((input6, key) => {
8976
8587
  if (key.tab) {
8977
8588
  const fields = ["input", "mode", "urlsafe", "convert"];
8978
8589
  const currentIndex = fields.indexOf(focusedField);
@@ -9020,8 +8631,8 @@ var Base64View = () => {
9020
8631
  } catch (error2) {
9021
8632
  }
9022
8633
  };
9023
- 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(
9024
- 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,
9025
8636
  {
9026
8637
  flexDirection: "column",
9027
8638
  borderStyle: "single",
@@ -9030,12 +8641,12 @@ var Base64View = () => {
9030
8641
  paddingY: 1,
9031
8642
  marginBottom: 1
9032
8643
  },
9033
- /* @__PURE__ */ React22.createElement(Text18, { bold: true, color: "yellow", marginBottom: 1 }, "Options:"),
9034
- /* @__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)"))),
9035
- /* @__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)")),
9036
- 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 _)")),
9037
- /* @__PURE__ */ React22.createElement(Box17, { marginTop: 1 }, /* @__PURE__ */ React22.createElement(
9038
- 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,
9039
8650
  {
9040
8651
  bold: true,
9041
8652
  backgroundColor: focusedField === "convert" ? "green" : void 0,
@@ -9046,8 +8657,8 @@ var Base64View = () => {
9046
8657
  mode === "encode" ? "Encode" : "Decode",
9047
8658
  " ]"
9048
8659
  ))
9049
- ), error && /* @__PURE__ */ React22.createElement(
9050
- Box17,
8660
+ ), error && /* @__PURE__ */ React16.createElement(
8661
+ Box12,
9051
8662
  {
9052
8663
  flexDirection: "column",
9053
8664
  borderStyle: "single",
@@ -9056,9 +8667,9 @@ var Base64View = () => {
9056
8667
  paddingY: 1,
9057
8668
  marginBottom: 1
9058
8669
  },
9059
- /* @__PURE__ */ React22.createElement(Text18, { color: "red" }, "\u2717 Error: ", error)
9060
- ), result && /* @__PURE__ */ React22.createElement(
9061
- Box17,
8670
+ /* @__PURE__ */ React16.createElement(Text13, { color: "red" }, "\u2717 Error: ", error)
8671
+ ), result && /* @__PURE__ */ React16.createElement(
8672
+ Box12,
9062
8673
  {
9063
8674
  flexDirection: "column",
9064
8675
  borderStyle: "single",
@@ -9066,24 +8677,24 @@ var Base64View = () => {
9066
8677
  paddingX: 2,
9067
8678
  paddingY: 1
9068
8679
  },
9069
- /* @__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!"))),
9070
- /* @__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)))
9071
- ), /* @__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")));
9072
8683
  };
9073
8684
 
9074
8685
  // src/ui/utils/views/UrlView.tsx
9075
- import React23, { useState as useState16 } from "react";
9076
- 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";
9077
8688
  import TextInput8 from "ink-text-input";
9078
8689
  var UrlView = () => {
9079
- const [input5, setInput] = useState16("");
9080
- const [mode, setMode] = useState16("encode");
9081
- const [fullUrl, setFullUrl] = useState16(false);
9082
- const [result, setResult] = useState16("");
9083
- const [focusedField, setFocusedField] = useState16("input");
9084
- 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);
9085
8696
  const service = new UtilsService();
9086
- useInput14((input6, key) => {
8697
+ useInput9((input6, key) => {
9087
8698
  if (key.tab) {
9088
8699
  const fields = ["input", "mode", "full", "convert"];
9089
8700
  const currentIndex = fields.indexOf(focusedField);
@@ -9121,8 +8732,8 @@ var UrlView = () => {
9121
8732
  } catch (error) {
9122
8733
  }
9123
8734
  };
9124
- 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(
9125
- 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,
9126
8737
  {
9127
8738
  flexDirection: "column",
9128
8739
  borderStyle: "single",
@@ -9131,12 +8742,12 @@ var UrlView = () => {
9131
8742
  paddingY: 1,
9132
8743
  marginBottom: 1
9133
8744
  },
9134
- /* @__PURE__ */ React23.createElement(Text19, { bold: true, color: "yellow", marginBottom: 1 }, "Options:"),
9135
- /* @__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)"))),
9136
- /* @__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)")),
9137
- /* @__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)")),
9138
- /* @__PURE__ */ React23.createElement(Box18, { marginTop: 1 }, /* @__PURE__ */ React23.createElement(
9139
- 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,
9140
8751
  {
9141
8752
  bold: true,
9142
8753
  backgroundColor: focusedField === "convert" ? "green" : void 0,
@@ -9147,8 +8758,8 @@ var UrlView = () => {
9147
8758
  mode === "encode" ? "Encode" : "Decode",
9148
8759
  " ]"
9149
8760
  ))
9150
- ), result && /* @__PURE__ */ React23.createElement(
9151
- Box18,
8761
+ ), result && /* @__PURE__ */ React17.createElement(
8762
+ Box13,
9152
8763
  {
9153
8764
  flexDirection: "column",
9154
8765
  borderStyle: "single",
@@ -9156,26 +8767,26 @@ var UrlView = () => {
9156
8767
  paddingX: 2,
9157
8768
  paddingY: 1
9158
8769
  },
9159
- /* @__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!"))),
9160
- /* @__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)))
9161
- ), /* @__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")));
9162
8773
  };
9163
8774
 
9164
8775
  // src/ui/utils/views/UnixTimeView.tsx
9165
- import React24, { useState as useState17 } from "react";
9166
- 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";
9167
8778
  import TextInput9 from "ink-text-input";
9168
8779
  var UnixTimeView = () => {
9169
- const [input5, setInput] = useState17("");
9170
- const [mode, setMode] = useState17("now");
9171
- const [format, setFormat] = useState17("iso");
9172
- const [useMs, setUseMs] = useState17(false);
9173
- const [result, setResult] = useState17("");
9174
- const [error, setError] = useState17("");
9175
- const [focusedField, setFocusedField] = useState17("mode");
9176
- 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);
9177
8788
  const service = new UtilsService();
9178
- useInput15((input6, key) => {
8789
+ useInput10((input6, key) => {
9179
8790
  if (key.tab) {
9180
8791
  const fields = mode === "now" ? ["mode", "ms", "convert"] : mode === "to-human" ? ["mode", "input", "format", "convert"] : ["mode", "input", "convert"];
9181
8792
  const currentIndex = fields.indexOf(focusedField);
@@ -9236,8 +8847,8 @@ var UnixTimeView = () => {
9236
8847
  } catch (error2) {
9237
8848
  }
9238
8849
  };
9239
- 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(
9240
- 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,
9241
8852
  {
9242
8853
  flexDirection: "column",
9243
8854
  borderStyle: "single",
@@ -9246,20 +8857,20 @@ var UnixTimeView = () => {
9246
8857
  paddingY: 1,
9247
8858
  marginBottom: 1
9248
8859
  },
9249
- /* @__PURE__ */ React24.createElement(Text20, { bold: true, color: "yellow", marginBottom: 1 }, "Options:"),
9250
- /* @__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)")),
9251
- 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(
9252
8863
  TextInput9,
9253
8864
  {
9254
8865
  value: input5,
9255
8866
  onChange: setInput,
9256
8867
  placeholder: mode === "to-human" ? "1702550400" : "2024-01-15 10:30:00"
9257
8868
  }
9258
- ) : /* @__PURE__ */ React24.createElement(Text20, { dimColor: !input5 }, input5 || "(empty)"))),
9259
- 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)")),
9260
- mode === "now" && /* @__PURE__ */ React24.createElement(Box19, { marginBottom: 1 }, /* @__PURE__ */ React24.createElement(Text20, { color: focusedField === "ms" ? "green" : void 0 }, focusedField === "ms" ? "\u25B6 " : " ", "[", useMs ? "\u2713" : " ", "] Milliseconds")),
9261
- /* @__PURE__ */ React24.createElement(Box19, { marginTop: 1 }, /* @__PURE__ */ React24.createElement(
9262
- 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,
9263
8874
  {
9264
8875
  bold: true,
9265
8876
  backgroundColor: focusedField === "convert" ? "green" : void 0,
@@ -9270,8 +8881,8 @@ var UnixTimeView = () => {
9270
8881
  mode === "now" ? "Get Current" : "Convert",
9271
8882
  " ]"
9272
8883
  ))
9273
- ), error && /* @__PURE__ */ React24.createElement(
9274
- Box19,
8884
+ ), error && /* @__PURE__ */ React18.createElement(
8885
+ Box14,
9275
8886
  {
9276
8887
  flexDirection: "column",
9277
8888
  borderStyle: "single",
@@ -9280,9 +8891,9 @@ var UnixTimeView = () => {
9280
8891
  paddingY: 1,
9281
8892
  marginBottom: 1
9282
8893
  },
9283
- /* @__PURE__ */ React24.createElement(Text20, { color: "red" }, "\u2717 Error: ", error)
9284
- ), result && /* @__PURE__ */ React24.createElement(
9285
- Box19,
8894
+ /* @__PURE__ */ React18.createElement(Text15, { color: "red" }, "\u2717 Error: ", error)
8895
+ ), result && /* @__PURE__ */ React18.createElement(
8896
+ Box14,
9286
8897
  {
9287
8898
  flexDirection: "column",
9288
8899
  borderStyle: "single",
@@ -9290,26 +8901,26 @@ var UnixTimeView = () => {
9290
8901
  paddingX: 2,
9291
8902
  paddingY: 1
9292
8903
  },
9293
- /* @__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!"))),
9294
- /* @__PURE__ */ React24.createElement(Box19, { flexDirection: "column" }, /* @__PURE__ */ React24.createElement(Box19, { marginTop: 1 }, /* @__PURE__ */ React24.createElement(Text20, { wrap: "wrap" }, result)))
9295
- ), /* @__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")));
9296
8907
  };
9297
8908
 
9298
8909
  // src/ui/utils/views/JwtView.tsx
9299
- import React25, { useState as useState18 } from "react";
9300
- 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";
9301
8912
  import TextInput10 from "ink-text-input";
9302
8913
  var JwtView = () => {
9303
- const [mode, setMode] = useState18("decode");
9304
- const [token, setToken] = useState18("");
9305
- const [payload, setPayload] = useState18("");
9306
- const [secret, setSecret] = useState18("");
9307
- const [result, setResult] = useState18({});
9308
- const [error, setError] = useState18("");
9309
- const [focusedField, setFocusedField] = useState18("mode");
9310
- 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);
9311
8922
  const service = new UtilsService();
9312
- useInput16((input5, key) => {
8923
+ useInput11((input5, key) => {
9313
8924
  if (key.tab) {
9314
8925
  const fields = mode === "decode" ? ["mode", "token", "process"] : ["mode", "payload", "secret", "process"];
9315
8926
  const currentIndex = fields.indexOf(focusedField);
@@ -9364,8 +8975,8 @@ var JwtView = () => {
9364
8975
  } catch (error2) {
9365
8976
  }
9366
8977
  };
9367
- 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(
9368
- 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,
9369
8980
  {
9370
8981
  flexDirection: "column",
9371
8982
  borderStyle: "single",
@@ -9374,23 +8985,23 @@ var JwtView = () => {
9374
8985
  paddingY: 1,
9375
8986
  marginBottom: 1
9376
8987
  },
9377
- /* @__PURE__ */ React25.createElement(Text21, { bold: true, color: "yellow", marginBottom: 1 }, "Options:"),
9378
- /* @__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)")),
9379
- 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(
9380
8991
  TextInput10,
9381
8992
  {
9382
8993
  value: token,
9383
8994
  onChange: setToken,
9384
8995
  placeholder: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
9385
8996
  }
9386
- ) : /* @__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(
9387
8998
  TextInput10,
9388
8999
  {
9389
9000
  value: payload,
9390
9001
  onChange: setPayload,
9391
9002
  placeholder: '{"sub":"123","name":"John"}'
9392
9003
  }
9393
- ) : /* @__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(
9394
9005
  TextInput10,
9395
9006
  {
9396
9007
  value: secret,
@@ -9398,9 +9009,9 @@ var JwtView = () => {
9398
9009
  placeholder: "your-secret-key",
9399
9010
  mask: "*"
9400
9011
  }
9401
- ) : /* @__PURE__ */ React25.createElement(Text21, { dimColor: !secret }, secret ? "*".repeat(secret.length) : "(empty)")))),
9402
- /* @__PURE__ */ React25.createElement(Box20, { marginTop: 1 }, /* @__PURE__ */ React25.createElement(
9403
- 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,
9404
9015
  {
9405
9016
  bold: true,
9406
9017
  backgroundColor: focusedField === "process" ? "green" : void 0,
@@ -9411,8 +9022,8 @@ var JwtView = () => {
9411
9022
  mode === "decode" ? "Decode" : "Encode",
9412
9023
  " ]"
9413
9024
  ))
9414
- ), error && /* @__PURE__ */ React25.createElement(
9415
- Box20,
9025
+ ), error && /* @__PURE__ */ React19.createElement(
9026
+ Box15,
9416
9027
  {
9417
9028
  flexDirection: "column",
9418
9029
  borderStyle: "single",
@@ -9421,9 +9032,9 @@ var JwtView = () => {
9421
9032
  paddingY: 1,
9422
9033
  marginBottom: 1
9423
9034
  },
9424
- /* @__PURE__ */ React25.createElement(Text21, { color: "red" }, "\u2717 Error: ", error)
9425
- ), (result.header || result.token) && /* @__PURE__ */ React25.createElement(
9426
- Box20,
9035
+ /* @__PURE__ */ React19.createElement(Text16, { color: "red" }, "\u2717 Error: ", error)
9036
+ ), (result.header || result.token) && /* @__PURE__ */ React19.createElement(
9037
+ Box15,
9427
9038
  {
9428
9039
  flexDirection: "column",
9429
9040
  borderStyle: "single",
@@ -9431,23 +9042,23 @@ var JwtView = () => {
9431
9042
  paddingX: 2,
9432
9043
  paddingY: 1
9433
9044
  },
9434
- /* @__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!"))),
9435
- /* @__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)))
9436
- ), /* @__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")));
9437
9048
  };
9438
9049
 
9439
9050
  // src/ui/utils/views/CronView.tsx
9440
- import React26, { useState as useState19 } from "react";
9441
- 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";
9442
9053
  import TextInput11 from "ink-text-input";
9443
9054
  var CronView = () => {
9444
- const [expression, setExpression] = useState19("");
9445
- const [result, setResult] = useState19(null);
9446
- const [error, setError] = useState19("");
9447
- const [focusedField, setFocusedField] = useState19("expression");
9448
- 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);
9449
9060
  const service = new UtilsService();
9450
- useInput17((input5, key) => {
9061
+ useInput12((input5, key) => {
9451
9062
  if (key.tab) {
9452
9063
  setFocusedField(focusedField === "expression" ? "parse" : "expression");
9453
9064
  } else if (key.return) {
@@ -9485,8 +9096,8 @@ ${result.nextRuns.join("\n")}`;
9485
9096
  } catch (error2) {
9486
9097
  }
9487
9098
  };
9488
- 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(
9489
- 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,
9490
9101
  {
9491
9102
  flexDirection: "column",
9492
9103
  borderStyle: "single",
@@ -9495,18 +9106,18 @@ ${result.nextRuns.join("\n")}`;
9495
9106
  paddingY: 1,
9496
9107
  marginBottom: 1
9497
9108
  },
9498
- /* @__PURE__ */ React26.createElement(Text22, { bold: true, color: "yellow", marginBottom: 1 }, "Options:"),
9499
- /* @__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(
9500
9111
  TextInput11,
9501
9112
  {
9502
9113
  value: expression,
9503
9114
  onChange: setExpression,
9504
9115
  placeholder: "0 5 * * * (5-field or 6-field)"
9505
9116
  }
9506
- ) : /* @__PURE__ */ React26.createElement(Text22, { dimColor: !expression }, expression || "(empty)"))),
9507
- /* @__PURE__ */ React26.createElement(Box21, { marginTop: 1, marginBottom: 1 }, /* @__PURE__ */ React26.createElement(Text22, { dimColor: true }, 'Examples: "0 5 * * *" (daily at 5am), "*/15 * * * *" (every 15 min)')),
9508
- /* @__PURE__ */ React26.createElement(Box21, { marginTop: 1 }, /* @__PURE__ */ React26.createElement(
9509
- 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,
9510
9121
  {
9511
9122
  bold: true,
9512
9123
  backgroundColor: focusedField === "parse" ? "green" : void 0,
@@ -9515,8 +9126,8 @@ ${result.nextRuns.join("\n")}`;
9515
9126
  focusedField === "parse" ? "\u25B6 " : " ",
9516
9127
  "[ Parse Expression ]"
9517
9128
  ))
9518
- ), error && /* @__PURE__ */ React26.createElement(
9519
- Box21,
9129
+ ), error && /* @__PURE__ */ React20.createElement(
9130
+ Box16,
9520
9131
  {
9521
9132
  flexDirection: "column",
9522
9133
  borderStyle: "single",
@@ -9525,9 +9136,9 @@ ${result.nextRuns.join("\n")}`;
9525
9136
  paddingY: 1,
9526
9137
  marginBottom: 1
9527
9138
  },
9528
- /* @__PURE__ */ React26.createElement(Text22, { color: "red" }, "\u2717 Error: ", error)
9529
- ), result && /* @__PURE__ */ React26.createElement(
9530
- Box21,
9139
+ /* @__PURE__ */ React20.createElement(Text17, { color: "red" }, "\u2717 Error: ", error)
9140
+ ), result && /* @__PURE__ */ React20.createElement(
9141
+ Box16,
9531
9142
  {
9532
9143
  flexDirection: "column",
9533
9144
  borderStyle: "single",
@@ -9535,25 +9146,25 @@ ${result.nextRuns.join("\n")}`;
9535
9146
  paddingX: 2,
9536
9147
  paddingY: 1
9537
9148
  },
9538
- /* @__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!"))),
9539
- /* @__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)))
9540
- ), /* @__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")));
9541
9152
  };
9542
9153
 
9543
9154
  // src/ui/utils/views/TimezoneView.tsx
9544
- import React27, { useState as useState20 } from "react";
9545
- 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";
9546
9157
  import TextInput12 from "ink-text-input";
9547
9158
  var TimezoneView = () => {
9548
- const [time, setTime] = useState20("");
9549
- const [fromTz, setFromTz] = useState20("UTC");
9550
- const [toTz, setToTz] = useState20("America/New_York");
9551
- const [result, setResult] = useState20("");
9552
- const [error, setError] = useState20("");
9553
- const [focusedField, setFocusedField] = useState20("time");
9554
- 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);
9555
9166
  const service = new UtilsService();
9556
- useInput18((input5, key) => {
9167
+ useInput13((input5, key) => {
9557
9168
  if (key.tab) {
9558
9169
  const fields = ["time", "from", "to", "convert"];
9559
9170
  const currentIndex = fields.indexOf(focusedField);
@@ -9592,8 +9203,8 @@ var TimezoneView = () => {
9592
9203
  } catch (error2) {
9593
9204
  }
9594
9205
  };
9595
- 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(
9596
- 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,
9597
9208
  {
9598
9209
  flexDirection: "column",
9599
9210
  borderStyle: "single",
@@ -9602,34 +9213,34 @@ var TimezoneView = () => {
9602
9213
  paddingY: 1,
9603
9214
  marginBottom: 1
9604
9215
  },
9605
- /* @__PURE__ */ React27.createElement(Text23, { bold: true, color: "yellow", marginBottom: 1 }, "Options:"),
9606
- /* @__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(
9607
9218
  TextInput12,
9608
9219
  {
9609
9220
  value: time,
9610
9221
  onChange: setTime,
9611
9222
  placeholder: "2024-01-15 10:00:00"
9612
9223
  }
9613
- ) : /* @__PURE__ */ React27.createElement(Text23, { dimColor: !time }, time || "(empty)"))),
9614
- /* @__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(
9615
9226
  TextInput12,
9616
9227
  {
9617
9228
  value: fromTz,
9618
9229
  onChange: setFromTz,
9619
9230
  placeholder: "UTC or America/New_York"
9620
9231
  }
9621
- ) : /* @__PURE__ */ React27.createElement(Text23, { dimColor: !fromTz }, fromTz || "(empty)"))),
9622
- /* @__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(
9623
9234
  TextInput12,
9624
9235
  {
9625
9236
  value: toTz,
9626
9237
  onChange: setToTz,
9627
9238
  placeholder: "Asia/Tokyo or Europe/London"
9628
9239
  }
9629
- ) : /* @__PURE__ */ React27.createElement(Text23, { dimColor: !toTz }, toTz || "(empty)"))),
9630
- /* @__PURE__ */ React27.createElement(Box22, { marginBottom: 1 }, /* @__PURE__ */ React27.createElement(Text23, { dimColor: true }, "Common: UTC, America/New_York, Europe/London, Asia/Tokyo")),
9631
- /* @__PURE__ */ React27.createElement(Box22, { marginTop: 1 }, /* @__PURE__ */ React27.createElement(
9632
- 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,
9633
9244
  {
9634
9245
  bold: true,
9635
9246
  backgroundColor: focusedField === "convert" ? "green" : void 0,
@@ -9638,8 +9249,8 @@ var TimezoneView = () => {
9638
9249
  focusedField === "convert" ? "\u25B6 " : " ",
9639
9250
  "[ Convert ]"
9640
9251
  ))
9641
- ), error && /* @__PURE__ */ React27.createElement(
9642
- Box22,
9252
+ ), error && /* @__PURE__ */ React21.createElement(
9253
+ Box17,
9643
9254
  {
9644
9255
  flexDirection: "column",
9645
9256
  borderStyle: "single",
@@ -9648,9 +9259,9 @@ var TimezoneView = () => {
9648
9259
  paddingY: 1,
9649
9260
  marginBottom: 1
9650
9261
  },
9651
- /* @__PURE__ */ React27.createElement(Text23, { color: "red" }, "\u2717 Error: ", error)
9652
- ), result && /* @__PURE__ */ React27.createElement(
9653
- Box22,
9262
+ /* @__PURE__ */ React21.createElement(Text18, { color: "red" }, "\u2717 Error: ", error)
9263
+ ), result && /* @__PURE__ */ React21.createElement(
9264
+ Box17,
9654
9265
  {
9655
9266
  flexDirection: "column",
9656
9267
  borderStyle: "single",
@@ -9658,28 +9269,28 @@ var TimezoneView = () => {
9658
9269
  paddingX: 2,
9659
9270
  paddingY: 1
9660
9271
  },
9661
- /* @__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!"))),
9662
- /* @__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)))
9663
- ), /* @__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")));
9664
9275
  };
9665
9276
 
9666
9277
  // src/ui/utils/views/HttpView.tsx
9667
- import React28, { useState as useState21 } from "react";
9668
- 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";
9669
9280
  import TextInput13 from "ink-text-input";
9670
9281
  var METHODS = ["GET", "POST", "PUT", "PATCH", "DELETE"];
9671
9282
  var HttpView = () => {
9672
- const [url, setUrl] = useState21("");
9673
- const [method, setMethod] = useState21("GET");
9674
- const [headers, setHeaders] = useState21("");
9675
- const [body, setBody] = useState21("");
9676
- const [response, setResponse] = useState21(null);
9677
- const [error, setError] = useState21("");
9678
- const [loading, setLoading] = useState21(false);
9679
- const [focusedField, setFocusedField] = useState21("url");
9680
- 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);
9681
9292
  const service = new UtilsService();
9682
- useInput19((input5, key) => {
9293
+ useInput14((input5, key) => {
9683
9294
  if (loading) return;
9684
9295
  if (key.tab) {
9685
9296
  const fields = ["url", "method", "headers", "body", "send"];
@@ -9740,8 +9351,8 @@ var HttpView = () => {
9740
9351
  } catch (error2) {
9741
9352
  }
9742
9353
  };
9743
- 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(
9744
- 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,
9745
9356
  {
9746
9357
  flexDirection: "column",
9747
9358
  borderStyle: "single",
@@ -9750,34 +9361,34 @@ var HttpView = () => {
9750
9361
  paddingY: 1,
9751
9362
  marginBottom: 1
9752
9363
  },
9753
- /* @__PURE__ */ React28.createElement(Text24, { bold: true, color: "yellow", marginBottom: 1 }, "Request:"),
9754
- /* @__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(
9755
9366
  TextInput13,
9756
9367
  {
9757
9368
  value: url,
9758
9369
  onChange: setUrl,
9759
9370
  placeholder: "https://api.example.com/endpoint"
9760
9371
  }
9761
- ) : /* @__PURE__ */ React28.createElement(Text24, { dimColor: !url }, url || "(empty)"))),
9762
- /* @__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)")),
9763
- /* @__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(
9764
9375
  TextInput13,
9765
9376
  {
9766
9377
  value: headers,
9767
9378
  onChange: setHeaders,
9768
9379
  placeholder: "Authorization: Bearer token"
9769
9380
  }
9770
- ) : /* @__PURE__ */ React28.createElement(Text24, { dimColor: !headers }, headers || "(none)"))),
9771
- (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(
9772
9383
  TextInput13,
9773
9384
  {
9774
9385
  value: body,
9775
9386
  onChange: setBody,
9776
9387
  placeholder: '{"key":"value"}'
9777
9388
  }
9778
- ) : /* @__PURE__ */ React28.createElement(Text24, { dimColor: !body }, body || "(empty)"))),
9779
- /* @__PURE__ */ React28.createElement(Box23, { marginTop: 1 }, /* @__PURE__ */ React28.createElement(
9780
- Text24,
9389
+ ) : /* @__PURE__ */ React22.createElement(Text19, { dimColor: !body }, body || "(empty)"))),
9390
+ /* @__PURE__ */ React22.createElement(Box18, { marginTop: 1 }, /* @__PURE__ */ React22.createElement(
9391
+ Text19,
9781
9392
  {
9782
9393
  bold: true,
9783
9394
  backgroundColor: focusedField === "send" ? "green" : void 0,
@@ -9788,8 +9399,8 @@ var HttpView = () => {
9788
9399
  loading ? "Sending..." : "Send Request",
9789
9400
  " ]"
9790
9401
  ))
9791
- ), error && /* @__PURE__ */ React28.createElement(
9792
- Box23,
9402
+ ), error && /* @__PURE__ */ React22.createElement(
9403
+ Box18,
9793
9404
  {
9794
9405
  flexDirection: "column",
9795
9406
  borderStyle: "single",
@@ -9798,9 +9409,9 @@ var HttpView = () => {
9798
9409
  paddingY: 1,
9799
9410
  marginBottom: 1
9800
9411
  },
9801
- /* @__PURE__ */ React28.createElement(Text24, { color: "red" }, "\u2717 Error: ", error)
9802
- ), response && /* @__PURE__ */ React28.createElement(
9803
- Box23,
9412
+ /* @__PURE__ */ React22.createElement(Text19, { color: "red" }, "\u2717 Error: ", error)
9413
+ ), response && /* @__PURE__ */ React22.createElement(
9414
+ Box18,
9804
9415
  {
9805
9416
  flexDirection: "column",
9806
9417
  borderStyle: "single",
@@ -9808,23 +9419,23 @@ var HttpView = () => {
9808
9419
  paddingX: 2,
9809
9420
  paddingY: 1
9810
9421
  },
9811
- /* @__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!"))),
9812
- /* @__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)))
9813
- ), /* @__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")));
9814
9425
  };
9815
9426
 
9816
9427
  // src/ui/utils/views/MarkdownView.tsx
9817
- import React29, { useState as useState22 } from "react";
9818
- 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";
9819
9430
  import TextInput14 from "ink-text-input";
9820
9431
  import * as fs15 from "fs";
9821
9432
  import * as path7 from "path";
9822
9433
  var MarkdownView = () => {
9823
- const [filePath, setFilePath] = useState22("");
9824
- const [content, setContent] = useState22("");
9825
- const [error, setError] = useState22("");
9826
- const [focusedField, setFocusedField] = useState22("file");
9827
- 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) => {
9828
9439
  if (key.tab) {
9829
9440
  setFocusedField(focusedField === "file" ? "preview" : "file");
9830
9441
  } else if (key.return) {
@@ -9865,8 +9476,8 @@ ${code.trim()}
9865
9476
  setContent("");
9866
9477
  }
9867
9478
  };
9868
- 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(
9869
- 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,
9870
9481
  {
9871
9482
  flexDirection: "column",
9872
9483
  borderStyle: "single",
@@ -9875,17 +9486,17 @@ ${code.trim()}
9875
9486
  paddingY: 1,
9876
9487
  marginBottom: 1
9877
9488
  },
9878
- /* @__PURE__ */ React29.createElement(Text25, { bold: true, color: "yellow", marginBottom: 1 }, "Options:"),
9879
- /* @__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(
9880
9491
  TextInput14,
9881
9492
  {
9882
9493
  value: filePath,
9883
9494
  onChange: setFilePath,
9884
9495
  placeholder: "./README.md or /path/to/file.md"
9885
9496
  }
9886
- ) : /* @__PURE__ */ React29.createElement(Text25, { dimColor: !filePath }, filePath || "(empty)"))),
9887
- /* @__PURE__ */ React29.createElement(Box24, { marginTop: 1 }, /* @__PURE__ */ React29.createElement(
9888
- Text25,
9497
+ ) : /* @__PURE__ */ React23.createElement(Text20, { dimColor: !filePath }, filePath || "(empty)"))),
9498
+ /* @__PURE__ */ React23.createElement(Box19, { marginTop: 1 }, /* @__PURE__ */ React23.createElement(
9499
+ Text20,
9889
9500
  {
9890
9501
  bold: true,
9891
9502
  backgroundColor: focusedField === "preview" ? "green" : void 0,
@@ -9894,8 +9505,8 @@ ${code.trim()}
9894
9505
  focusedField === "preview" ? "\u25B6 " : " ",
9895
9506
  "[ Preview File ]"
9896
9507
  ))
9897
- ), error && /* @__PURE__ */ React29.createElement(
9898
- Box24,
9508
+ ), error && /* @__PURE__ */ React23.createElement(
9509
+ Box19,
9899
9510
  {
9900
9511
  flexDirection: "column",
9901
9512
  borderStyle: "single",
@@ -9904,9 +9515,9 @@ ${code.trim()}
9904
9515
  paddingY: 1,
9905
9516
  marginBottom: 1
9906
9517
  },
9907
- /* @__PURE__ */ React29.createElement(Text25, { color: "red" }, "\u2717 Error: ", error)
9908
- ), content && /* @__PURE__ */ React29.createElement(
9909
- Box24,
9518
+ /* @__PURE__ */ React23.createElement(Text20, { color: "red" }, "\u2717 Error: ", error)
9519
+ ), content && /* @__PURE__ */ React23.createElement(
9520
+ Box19,
9910
9521
  {
9911
9522
  flexDirection: "column",
9912
9523
  borderStyle: "single",
@@ -9914,9 +9525,9 @@ ${code.trim()}
9914
9525
  paddingX: 2,
9915
9526
  paddingY: 1
9916
9527
  },
9917
- /* @__PURE__ */ React29.createElement(Box24, { marginBottom: 1 }, /* @__PURE__ */ React29.createElement(Text25, { bold: true, color: "green" }, "\u2713 Preview:")),
9918
- /* @__PURE__ */ React29.createElement(Box24, { flexDirection: "column" }, /* @__PURE__ */ React29.createElement(Text25, null, content))
9919
- ), /* @__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")));
9920
9531
  };
9921
9532
 
9922
9533
  // src/ui/utils/UtilsApp.tsx
@@ -9936,10 +9547,10 @@ var MENU_ITEMS = [
9936
9547
  { id: "markdown", icon: "\u{1F4C4}", label: "Markdown", description: "Preview markdown" }
9937
9548
  ];
9938
9549
  var UtilsApp = ({ onExit }) => {
9939
- const [selectedIndex, setSelectedIndex] = useState23(0);
9940
- const [activeView, setActiveView] = useState23(null);
9941
- const { exit } = useApp5();
9942
- useInput21((input5, key) => {
9550
+ const [selectedIndex, setSelectedIndex] = useState18(0);
9551
+ const [activeView, setActiveView] = useState18(null);
9552
+ const { exit } = useApp4();
9553
+ useInput16((input5, key) => {
9943
9554
  if (activeView) {
9944
9555
  if (key.escape) {
9945
9556
  setActiveView(null);
@@ -9957,8 +9568,8 @@ var UtilsApp = ({ onExit }) => {
9957
9568
  exit();
9958
9569
  }
9959
9570
  });
9960
- return /* @__PURE__ */ React30.createElement(Box25, { flexDirection: "column", width: "100%", height: "100%" }, /* @__PURE__ */ React30.createElement(
9961
- Box25,
9571
+ return /* @__PURE__ */ React24.createElement(Box20, { flexDirection: "column", width: "100%", height: "100%" }, /* @__PURE__ */ React24.createElement(
9572
+ Box20,
9962
9573
  {
9963
9574
  borderStyle: "single",
9964
9575
  borderColor: "cyan",
@@ -9966,10 +9577,10 @@ var UtilsApp = ({ onExit }) => {
9966
9577
  paddingY: 0,
9967
9578
  marginBottom: 1
9968
9579
  },
9969
- /* @__PURE__ */ React30.createElement(Text26, { bold: true, color: "cyan" }, "\u{1F6E0}\uFE0F Developer Utilities - Interactive Mode"),
9970
- /* @__PURE__ */ React30.createElement(Box25, { marginLeft: "auto" }, /* @__PURE__ */ React30.createElement(Text26, { dimColor: true }, "Press Ctrl+Q to quit"))
9971
- ), /* @__PURE__ */ React30.createElement(Box25, { flexGrow: 1 }, /* @__PURE__ */ React30.createElement(
9972
- 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,
9973
9584
  {
9974
9585
  flexDirection: "column",
9975
9586
  width: 30,
@@ -9979,9 +9590,9 @@ var UtilsApp = ({ onExit }) => {
9979
9590
  paddingY: 1,
9980
9591
  marginRight: 1
9981
9592
  },
9982
- /* @__PURE__ */ React30.createElement(Box25, { marginBottom: 1 }, /* @__PURE__ */ React30.createElement(Text26, { bold: true, color: "yellow" }, "Select Utility:")),
9983
- MENU_ITEMS.map((item, index) => /* @__PURE__ */ React30.createElement(Box25, { key: item.id, marginBottom: 0 }, /* @__PURE__ */ React30.createElement(
9984
- 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,
9985
9596
  {
9986
9597
  color: selectedIndex === index && !activeView ? "green" : void 0,
9987
9598
  bold: selectedIndex === index && !activeView,
@@ -9992,9 +9603,9 @@ var UtilsApp = ({ onExit }) => {
9992
9603
  " ",
9993
9604
  item.label
9994
9605
  ))),
9995
- /* @__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"))
9996
- ), /* @__PURE__ */ React30.createElement(
9997
- 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,
9998
9609
  {
9999
9610
  flexDirection: "column",
10000
9611
  flexGrow: 1,
@@ -10003,21 +9614,21 @@ var UtilsApp = ({ onExit }) => {
10003
9614
  paddingX: 2,
10004
9615
  paddingY: 1
10005
9616
  },
10006
- activeView ? /* @__PURE__ */ React30.createElement(ActiveUtilityView, { utilityType: activeView }) : /* @__PURE__ */ React30.createElement(WelcomeView, { selectedItem: MENU_ITEMS[selectedIndex] })
10007
- )), /* @__PURE__ */ React30.createElement(
10008
- Box25,
9617
+ activeView ? /* @__PURE__ */ React24.createElement(ActiveUtilityView, { utilityType: activeView }) : /* @__PURE__ */ React24.createElement(WelcomeView, { selectedItem: MENU_ITEMS[selectedIndex] })
9618
+ )), /* @__PURE__ */ React24.createElement(
9619
+ Box20,
10009
9620
  {
10010
9621
  borderStyle: "single",
10011
9622
  borderColor: "gray",
10012
9623
  paddingX: 2,
10013
9624
  marginTop: 1
10014
9625
  },
10015
- /* @__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")
10016
9627
  ));
10017
9628
  };
10018
9629
  var WelcomeView = ({ selectedItem }) => {
10019
- 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(
10020
- 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,
10021
9632
  {
10022
9633
  borderStyle: "single",
10023
9634
  borderColor: "yellow",
@@ -10025,49 +9636,49 @@ var WelcomeView = ({ selectedItem }) => {
10025
9636
  paddingY: 1,
10026
9637
  marginBottom: 2
10027
9638
  },
10028
- /* @__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))
10029
- ), /* @__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.")));
10030
9641
  };
10031
9642
  var ActiveUtilityView = ({ utilityType }) => {
10032
9643
  switch (utilityType) {
10033
9644
  case "password":
10034
- return /* @__PURE__ */ React30.createElement(PasswordView, null);
9645
+ return /* @__PURE__ */ React24.createElement(PasswordView, null);
10035
9646
  case "uuid":
10036
- return /* @__PURE__ */ React30.createElement(UuidView, null);
9647
+ return /* @__PURE__ */ React24.createElement(UuidView, null);
10037
9648
  case "hash":
10038
- return /* @__PURE__ */ React30.createElement(HashView, null);
9649
+ return /* @__PURE__ */ React24.createElement(HashView, null);
10039
9650
  case "base64-encode":
10040
9651
  case "base64-decode":
10041
- return /* @__PURE__ */ React30.createElement(Base64View, null);
9652
+ return /* @__PURE__ */ React24.createElement(Base64View, null);
10042
9653
  case "url-encode":
10043
9654
  case "url-decode":
10044
- return /* @__PURE__ */ React30.createElement(UrlView, null);
9655
+ return /* @__PURE__ */ React24.createElement(UrlView, null);
10045
9656
  case "unix-time":
10046
- return /* @__PURE__ */ React30.createElement(UnixTimeView, null);
9657
+ return /* @__PURE__ */ React24.createElement(UnixTimeView, null);
10047
9658
  case "jwt":
10048
- return /* @__PURE__ */ React30.createElement(JwtView, null);
9659
+ return /* @__PURE__ */ React24.createElement(JwtView, null);
10049
9660
  case "cron":
10050
- return /* @__PURE__ */ React30.createElement(CronView, null);
9661
+ return /* @__PURE__ */ React24.createElement(CronView, null);
10051
9662
  case "timezone":
10052
- return /* @__PURE__ */ React30.createElement(TimezoneView, null);
9663
+ return /* @__PURE__ */ React24.createElement(TimezoneView, null);
10053
9664
  case "http":
10054
- return /* @__PURE__ */ React30.createElement(HttpView, null);
9665
+ return /* @__PURE__ */ React24.createElement(HttpView, null);
10055
9666
  case "markdown":
10056
- return /* @__PURE__ */ React30.createElement(MarkdownView, null);
9667
+ return /* @__PURE__ */ React24.createElement(MarkdownView, null);
10057
9668
  default:
10058
- return /* @__PURE__ */ React30.createElement(PlaceholderView, { utilityType });
9669
+ return /* @__PURE__ */ React24.createElement(PlaceholderView, { utilityType });
10059
9670
  }
10060
9671
  };
10061
9672
  var PlaceholderView = ({ utilityType }) => {
10062
9673
  const item = MENU_ITEMS.find((m) => m.id === utilityType);
10063
- 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.")));
10064
9675
  };
10065
9676
 
10066
9677
  // src/commands/utils/interactive.ts
10067
9678
  async function runInteractiveMode() {
10068
9679
  return new Promise((resolve4) => {
10069
- const { unmount, waitUntilExit } = render5(
10070
- React31.createElement(UtilsApp, {
9680
+ const { unmount, waitUntilExit } = render4(
9681
+ React25.createElement(UtilsApp, {
10071
9682
  onExit: () => {
10072
9683
  unmount();
10073
9684
  resolve4();
@@ -10082,40 +9693,40 @@ async function runInteractiveMode() {
10082
9693
 
10083
9694
  // src/commands/utils/index.ts
10084
9695
  function showUtilsHelp() {
10085
- 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"));
10086
9697
  console.log();
10087
- console.log(chalk14.bold("M\xE3 h\xF3a & B\u1EA3o m\u1EADt:"));
10088
- console.log(` ${chalk14.cyan("password")} T\u1EA1o m\u1EADt kh\u1EA9u ng\u1EABu nhi\xEAn`);
10089
- console.log(` ${chalk14.cyan("uuid")} T\u1EA1o UUID v4`);
10090
- console.log(` ${chalk14.cyan("hash")} Hash text (MD5/SHA/bcrypt)`);
10091
- 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`);
10092
9703
  console.log();
10093
- console.log(chalk14.bold("Encoding:"));
10094
- console.log(` ${chalk14.cyan("base64-encode")} Encode sang Base64`);
10095
- console.log(` ${chalk14.cyan("base64-decode")} Decode t\u1EEB Base64`);
10096
- console.log(` ${chalk14.cyan("url-encode")} Encode URL components`);
10097
- 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`);
10098
9709
  console.log();
10099
- console.log(chalk14.bold("Th\u1EDDi gian:"));
10100
- console.log(` ${chalk14.cyan("unix-time")} Chuy\u1EC3n \u0111\u1ED5i unix timestamp`);
10101
- console.log(` ${chalk14.cyan("timezone")} Chuy\u1EC3n \u0111\u1ED5i m\xFAi gi\u1EDD`);
10102
- 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`);
10103
9714
  console.log();
10104
- console.log(chalk14.bold("Kh\xE1c:"));
10105
- console.log(` ${chalk14.cyan("http")} G\u1EEDi HTTP requests`);
10106
- 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`);
10107
9718
  console.log();
10108
- console.log(chalk14.bold("Ch\u1EBF \u0111\u1ED9 Interactive:"));
10109
- console.log(chalk14.dim(" $ jai1 utils -i"));
10110
- 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"));
10111
9722
  console.log();
10112
- console.log(chalk14.bold("V\xED d\u1EE5:"));
10113
- console.log(chalk14.dim(" $ jai1 utils password --length 24"));
10114
- console.log(chalk14.dim(" $ jai1 utils uuid --count 5"));
10115
- console.log(chalk14.dim(' $ jai1 utils hash "text" --algorithm sha256'));
10116
- 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"));
10117
9728
  console.log();
10118
- 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'));
10119
9730
  }
10120
9731
  function createUtilsCommand() {
10121
9732
  const utilsCommand = new Command42("utils").description("Developer utilities for common tasks").option("-i, --interactive", "Run in interactive mode");
@@ -10144,11 +9755,11 @@ function createUtilsCommand() {
10144
9755
 
10145
9756
  // src/commands/deps/index.ts
10146
9757
  import { Command as Command45 } from "commander";
10147
- import chalk17 from "chalk";
9758
+ import chalk18 from "chalk";
10148
9759
 
10149
9760
  // src/commands/deps/check.ts
10150
9761
  import { Command as Command43 } from "commander";
10151
- import chalk15 from "chalk";
9762
+ import chalk16 from "chalk";
10152
9763
  import Table4 from "cli-table3";
10153
9764
  import ora from "ora";
10154
9765
 
@@ -10751,7 +10362,7 @@ function createDepsCheckCommand() {
10751
10362
  if (projects.length === 0) {
10752
10363
  spinner.fail("Kh\xF4ng t\xECm th\u1EA5y project n\xE0o \u0111\u01B0\u1EE3c h\u1ED7 tr\u1EE3");
10753
10364
  console.log();
10754
- 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)"));
10755
10366
  process.exit(1);
10756
10367
  }
10757
10368
  spinner.succeed(`Ph\xE1t hi\u1EC7n ${projects.length} project:`);
@@ -10765,7 +10376,7 @@ function createDepsCheckCommand() {
10765
10376
  await checkEcosystem(project.ecosystem, project.manager, cwd);
10766
10377
  }
10767
10378
  console.log();
10768
- 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.'));
10769
10380
  });
10770
10381
  return checkCommand;
10771
10382
  }
@@ -10798,7 +10409,7 @@ async function checkEcosystem(ecosystem, manager, cwd) {
10798
10409
  });
10799
10410
  } catch (error) {
10800
10411
  spinner.fail(`L\u1ED7i ki\u1EC3m tra ${label}`);
10801
- console.log(chalk15.red(error.message));
10412
+ console.log(chalk16.red(error.message));
10802
10413
  console.log();
10803
10414
  return;
10804
10415
  }
@@ -10811,10 +10422,10 @@ async function checkEcosystem(ecosystem, manager, cwd) {
10811
10422
  console.log();
10812
10423
  const table = new Table4({
10813
10424
  head: [
10814
- chalk15.cyan("Package"),
10815
- chalk15.cyan("Hi\u1EC7n t\u1EA1i"),
10816
- chalk15.cyan("M\u1EDBi nh\u1EA5t"),
10817
- 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")
10818
10429
  ],
10819
10430
  style: {
10820
10431
  head: [],
@@ -10825,9 +10436,9 @@ async function checkEcosystem(ecosystem, manager, cwd) {
10825
10436
  const upgradeIcon = pkg.upgradeType === "major" ? "\u{1F534}" : pkg.upgradeType === "minor" ? "\u{1F7E1}" : "\u{1F7E2}";
10826
10437
  table.push([
10827
10438
  `${upgradeIcon} ${pkg.name}`,
10828
- chalk15.dim(pkg.current),
10829
- chalk15.green(pkg.latest),
10830
- 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"
10831
10442
  ]);
10832
10443
  }
10833
10444
  console.log(table.toString());
@@ -10835,13 +10446,13 @@ async function checkEcosystem(ecosystem, manager, cwd) {
10835
10446
  if (result.isLaravel) {
10836
10447
  const blockedPackages = result.packages.filter((p) => p.blockedReason);
10837
10448
  if (blockedPackages.length > 0) {
10838
- 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):"));
10839
10450
  for (const pkg of blockedPackages) {
10840
- console.log(chalk15.dim(` - ${pkg.name}: ${pkg.current} \u2192 ${pkg.latest}`));
10451
+ console.log(chalk16.dim(` - ${pkg.name}: ${pkg.current} \u2192 ${pkg.latest}`));
10841
10452
  }
10842
10453
  console.log();
10843
- console.log(chalk15.dim("\u{1F4A1} \u0110\u1EC3 n\xE2ng c\u1EA5p Laravel major version, ch\u1EA1y th\u1EE7 c\xF4ng:"));
10844
- 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}`));
10845
10456
  console.log();
10846
10457
  }
10847
10458
  }
@@ -10850,7 +10461,7 @@ async function checkEcosystem(ecosystem, manager, cwd) {
10850
10461
  // src/commands/deps/upgrade.ts
10851
10462
  import { Command as Command44 } from "commander";
10852
10463
  import { checkbox as checkbox3, confirm as confirm8 } from "@inquirer/prompts";
10853
- import chalk16 from "chalk";
10464
+ import chalk17 from "chalk";
10854
10465
  import ora2 from "ora";
10855
10466
  import Table5 from "cli-table3";
10856
10467
  function createDepsUpgradeCommand() {
@@ -10867,7 +10478,7 @@ async function handleDepsUpgrade(options) {
10867
10478
  if (projects.length === 0) {
10868
10479
  spinner.fail("Kh\xF4ng t\xECm th\u1EA5y project n\xE0o \u0111\u01B0\u1EE3c h\u1ED7 tr\u1EE3");
10869
10480
  console.log();
10870
- 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)"));
10871
10482
  process.exit(1);
10872
10483
  }
10873
10484
  spinner.succeed(`Ph\xE1t hi\u1EC7n ${projects.length} project:`);
@@ -10881,9 +10492,9 @@ async function handleDepsUpgrade(options) {
10881
10492
  await upgradeEcosystem(project, cwd, options);
10882
10493
  }
10883
10494
  console.log();
10884
- console.log(chalk16.green("\u2705 Ho\xE0n th\xE0nh!"));
10495
+ console.log(chalk17.green("\u2705 Ho\xE0n th\xE0nh!"));
10885
10496
  } catch (error) {
10886
- console.error(chalk16.red(`
10497
+ console.error(chalk17.red(`
10887
10498
  \u274C ${error.message}
10888
10499
  `));
10889
10500
  process.exit(1);
@@ -10892,10 +10503,10 @@ async function handleDepsUpgrade(options) {
10892
10503
  async function upgradeEcosystem(project, cwd, options) {
10893
10504
  const service = getService(project.ecosystem);
10894
10505
  const label = `${getEcosystemIcon(project.ecosystem)} ${getEcosystemLabel(project.ecosystem)}`;
10895
- console.log(chalk16.bold.cyan(`
10506
+ console.log(chalk17.bold.cyan(`
10896
10507
  ${"\u2501".repeat(80)}`));
10897
- console.log(chalk16.bold.cyan(`${label}`));
10898
- console.log(chalk16.bold.cyan("\u2501".repeat(80)));
10508
+ console.log(chalk17.bold.cyan(`${label}`));
10509
+ console.log(chalk17.bold.cyan("\u2501".repeat(80)));
10899
10510
  console.log();
10900
10511
  const spinner = ora2("\u0110ang ki\u1EC3m tra packages...").start();
10901
10512
  let packages;
@@ -10906,7 +10517,7 @@ ${"\u2501".repeat(80)}`));
10906
10517
  packages = result.packages;
10907
10518
  } catch (error) {
10908
10519
  spinner.fail("L\u1ED7i ki\u1EC3m tra packages");
10909
- console.log(chalk16.red(error.message));
10520
+ console.log(chalk17.red(error.message));
10910
10521
  return;
10911
10522
  }
10912
10523
  if (packages.length === 0) {
@@ -10919,7 +10530,7 @@ ${"\u2501".repeat(80)}`));
10919
10530
  let selectedPackages;
10920
10531
  if (options.all) {
10921
10532
  selectedPackages = packages;
10922
- 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
10923
10534
  `));
10924
10535
  } else {
10925
10536
  try {
@@ -10937,12 +10548,12 @@ ${"\u2501".repeat(80)}`));
10937
10548
  theme: checkboxTheme
10938
10549
  });
10939
10550
  if (selected.length === 0) {
10940
- 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"));
10941
10552
  return;
10942
10553
  }
10943
10554
  selectedPackages = packages.filter((p) => selected.includes(p.name));
10944
10555
  } catch {
10945
- 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"));
10946
10557
  return;
10947
10558
  }
10948
10559
  }
@@ -10953,35 +10564,35 @@ ${"\u2501".repeat(80)}`));
10953
10564
  default: true
10954
10565
  });
10955
10566
  } catch {
10956
- 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"));
10957
10568
  return;
10958
10569
  }
10959
10570
  if (!shouldProceed) {
10960
- 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"));
10961
10572
  return;
10962
10573
  }
10963
10574
  console.log();
10964
- console.log(chalk16.cyan(`\u{1F527} Package manager: ${project.manager}`));
10965
- 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"));
10966
10577
  const commands = service.getUpgradeCommands(selectedPackages);
10967
10578
  try {
10968
10579
  if (commands.deps) {
10969
- console.log(chalk16.dim(`$ ${commands.deps}
10580
+ console.log(chalk17.dim(`$ ${commands.deps}
10970
10581
  `));
10971
10582
  }
10972
10583
  if (commands.devDeps) {
10973
- console.log(chalk16.dim(`$ ${commands.devDeps}
10584
+ console.log(chalk17.dim(`$ ${commands.devDeps}
10974
10585
  `));
10975
10586
  }
10976
10587
  await service.upgrade(cwd, { packages: selectedPackages });
10977
- console.log(chalk16.green(`
10588
+ console.log(chalk17.green(`
10978
10589
  \u2705 \u0110\xE3 upgrade ${selectedPackages.length} packages th\xE0nh c\xF4ng!`));
10979
10590
  } catch (error) {
10980
- console.error(chalk16.red("\n\u274C L\u1ED7i khi upgrade:"));
10981
- console.error(chalk16.red(error.message));
10982
- console.log(chalk16.yellow("\n\u{1F4A1} B\u1EA1n c\xF3 th\u1EC3 th\u1EED upgrade th\u1EE7 c\xF4ng:"));
10983
- if (commands.deps) console.log(chalk16.cyan(` ${commands.deps}`));
10984
- 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}`));
10985
10596
  console.log();
10986
10597
  throw error;
10987
10598
  }
@@ -10989,10 +10600,10 @@ ${"\u2501".repeat(80)}`));
10989
10600
  function displayUpgradeTable(packages) {
10990
10601
  const table = new Table5({
10991
10602
  head: [
10992
- chalk16.cyan("Package"),
10993
- chalk16.cyan("Hi\u1EC7n t\u1EA1i"),
10994
- chalk16.cyan("M\u1EDBi nh\u1EA5t"),
10995
- 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")
10996
10607
  ],
10997
10608
  style: {
10998
10609
  head: [],
@@ -11003,9 +10614,9 @@ function displayUpgradeTable(packages) {
11003
10614
  const upgradeIcon = pkg.upgradeType === "major" ? "\u{1F534}" : pkg.upgradeType === "minor" ? "\u{1F7E1}" : "\u{1F7E2}";
11004
10615
  table.push([
11005
10616
  `${upgradeIcon} ${pkg.name}`,
11006
- chalk16.dim(pkg.current),
11007
- chalk16.green(pkg.latest),
11008
- 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"
11009
10620
  ]);
11010
10621
  }
11011
10622
  console.log(table.toString());
@@ -11048,23 +10659,23 @@ function getEcosystemLabel(ecosystem) {
11048
10659
 
11049
10660
  // src/commands/deps/index.ts
11050
10661
  function showDepsHelp() {
11051
- 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"));
11052
10663
  console.log();
11053
- console.log(chalk17.bold("C\xE1c l\u1EC7nh:"));
11054
- console.log(` ${chalk17.cyan("check")} Ki\u1EC3m tra c\xE1c packages c\u1EA7n upgrade`);
11055
- 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`);
11056
10667
  console.log();
11057
- console.log(chalk17.bold("H\u1ED7 tr\u1EE3:"));
11058
- console.log(chalk17.dim(" \u2022 Node.js (npm, pnpm, yarn, bun)"));
11059
- console.log(chalk17.dim(" \u2022 PHP/Composer (v\u1EDBi b\u1EA3o v\u1EC7 Laravel major version)"));
11060
- 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)"));
11061
10672
  console.log();
11062
- console.log(chalk17.bold("V\xED d\u1EE5:"));
11063
- console.log(chalk17.dim(" $ jai1 deps check"));
11064
- console.log(chalk17.dim(" $ jai1 deps upgrade"));
11065
- 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"));
11066
10677
  console.log();
11067
- 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'));
11068
10679
  }
11069
10680
  function createDepsCommand() {
11070
10681
  const depsCommand = new Command45("deps").description("Qu\u1EA3n l\xFD dependencies trong project").action(() => {
@@ -11080,13 +10691,13 @@ import { Command as Command56 } from "commander";
11080
10691
 
11081
10692
  // src/commands/tasks/add.ts
11082
10693
  import { Command as Command46 } from "commander";
11083
- import chalk18 from "chalk";
10694
+ import chalk19 from "chalk";
11084
10695
  function createTaskAddCommand() {
11085
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) => {
11086
10697
  const service = new TaskService();
11087
10698
  const priority = Number(options.priority ?? 2);
11088
10699
  if (priority < 0 || priority > 3) {
11089
- console.error(chalk18.red("\u274C Priority must be 0-3"));
10700
+ console.error(chalk19.red("\u274C Priority must be 0-3"));
11090
10701
  process.exit(1);
11091
10702
  }
11092
10703
  const tags = options.tags ? options.tags.split(",").map((t) => t.trim()) : [];
@@ -11102,21 +10713,21 @@ function createTaskAddCommand() {
11102
10713
  }
11103
10714
  const icon = PRIORITY_ICONS[task.priority] || "\u{1F7E1}";
11104
10715
  const label = PRIORITY_LABELS[task.priority] || "Medium";
11105
- console.log(chalk18.green(`\u2705 Task added: ${chalk18.bold(task.id)}`));
11106
- console.log(` ${chalk18.dim("Title:")} ${task.title}`);
11107
- 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}`);
11108
10719
  if (task.parent) {
11109
- console.log(` ${chalk18.dim("Parent:")} ${task.parent}`);
10720
+ console.log(` ${chalk19.dim("Parent:")} ${task.parent}`);
11110
10721
  }
11111
10722
  if (task.tags.length > 0) {
11112
- console.log(` ${chalk18.dim("Tags:")} ${task.tags.join(", ")}`);
10723
+ console.log(` ${chalk19.dim("Tags:")} ${task.tags.join(", ")}`);
11113
10724
  }
11114
10725
  });
11115
10726
  }
11116
10727
 
11117
10728
  // src/commands/tasks/list.ts
11118
10729
  import { Command as Command47 } from "commander";
11119
- import chalk19 from "chalk";
10730
+ import chalk20 from "chalk";
11120
10731
  function createTaskListCommand() {
11121
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) => {
11122
10733
  await handleTaskList(options);
@@ -11137,12 +10748,12 @@ async function handleTaskList(options) {
11137
10748
  return;
11138
10749
  }
11139
10750
  if (tasks.length === 0) {
11140
- console.log(chalk19.dim("No tasks found."));
10751
+ console.log(chalk20.dim("No tasks found."));
11141
10752
  return;
11142
10753
  }
11143
10754
  const doneIds = new Set(allTasks.filter((t) => t.status === "done").map((t) => t.id));
11144
10755
  const header = options.parent ? `\u{1F4CB} ${options.parent} (${tasks.length} tasks)` : `\u{1F4CB} All tasks (${tasks.length})`;
11145
- console.log(chalk19.bold(header));
10756
+ console.log(chalk20.bold(header));
11146
10757
  console.log();
11147
10758
  for (const task of tasks) {
11148
10759
  printTaskLine(task, doneIds);
@@ -11152,23 +10763,23 @@ function printTaskLine(task, doneIds) {
11152
10763
  const isBlocked = task.status === "todo" && task.depends_on.length > 0 && !task.depends_on.every((id) => doneIds.has(id));
11153
10764
  const statusIcon = isBlocked ? BLOCKED_ICON : STATUS_ICONS[task.status] || "\u{1F4CB}";
11154
10765
  const priorityIcon = PRIORITY_ICONS[task.priority] || "\u{1F7E1}";
11155
- 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}`;
11156
10767
  if (task.status === "in_progress" && task.assigned_to) {
11157
- line += chalk19.cyan(` @${task.assigned_to}`);
10768
+ line += chalk20.cyan(` @${task.assigned_to}`);
11158
10769
  }
11159
10770
  if (isBlocked) {
11160
10771
  const blockedBy = task.depends_on.filter((id) => !doneIds.has(id));
11161
- line += chalk19.red(` (blocked: ${blockedBy.join(", ")})`);
10772
+ line += chalk20.red(` (blocked: ${blockedBy.join(", ")})`);
11162
10773
  }
11163
10774
  if (task.parent) {
11164
- line += chalk19.dim(` [${task.parent}]`);
10775
+ line += chalk20.dim(` [${task.parent}]`);
11165
10776
  }
11166
10777
  console.log(line);
11167
10778
  }
11168
10779
 
11169
10780
  // src/commands/tasks/ready.ts
11170
10781
  import { Command as Command48 } from "commander";
11171
- import chalk20 from "chalk";
10782
+ import chalk21 from "chalk";
11172
10783
  function createTaskReadyCommand() {
11173
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) => {
11174
10785
  const service = new TaskService();
@@ -11178,33 +10789,33 @@ function createTaskReadyCommand() {
11178
10789
  return;
11179
10790
  }
11180
10791
  if (tasks.length === 0) {
11181
- console.log(chalk20.dim("No tasks ready to pick."));
11182
- 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"));
11183
10794
  return;
11184
10795
  }
11185
- 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):`));
11186
10797
  console.log();
11187
10798
  for (const task of tasks) {
11188
10799
  const icon = PRIORITY_ICONS[task.priority] || "\u{1F7E1}";
11189
- 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}`;
11190
10801
  if (task.parent) {
11191
- line += chalk20.dim(` [${task.parent}]`);
10802
+ line += chalk21.dim(` [${task.parent}]`);
11192
10803
  }
11193
10804
  console.log(line);
11194
10805
  }
11195
10806
  console.log();
11196
- console.log(chalk20.dim("\u{1F4A1} Run: jai1 t pick"));
10807
+ console.log(chalk21.dim("\u{1F4A1} Run: jai1 t pick"));
11197
10808
  });
11198
10809
  }
11199
10810
 
11200
10811
  // src/commands/tasks/update.ts
11201
10812
  import { Command as Command49 } from "commander";
11202
- import chalk21 from "chalk";
10813
+ import chalk22 from "chalk";
11203
10814
  var VALID_STATUSES = ["todo", "in_progress", "done", "cancelled"];
11204
10815
  function createTaskUpdateCommand() {
11205
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) => {
11206
10817
  if (!VALID_STATUSES.includes(options.status)) {
11207
- 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(", ")}`));
11208
10819
  process.exit(1);
11209
10820
  }
11210
10821
  const service = new TaskService();
@@ -11215,9 +10826,9 @@ function createTaskUpdateCommand() {
11215
10826
  return;
11216
10827
  }
11217
10828
  const icon = STATUS_ICONS[task.status] || "\u{1F4CB}";
11218
- console.log(chalk21.green(`\u2705 ${task.id} \u2192 ${icon} ${task.status}`));
10829
+ console.log(chalk22.green(`\u2705 ${task.id} \u2192 ${icon} ${task.status}`));
11219
10830
  } catch (error) {
11220
- 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)}`));
11221
10832
  process.exit(1);
11222
10833
  }
11223
10834
  });
@@ -11225,14 +10836,14 @@ function createTaskUpdateCommand() {
11225
10836
 
11226
10837
  // src/commands/tasks/show.ts
11227
10838
  import { Command as Command50 } from "commander";
11228
- import chalk22 from "chalk";
10839
+ import chalk23 from "chalk";
11229
10840
  function createTaskShowCommand() {
11230
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) => {
11231
10842
  const service = new TaskService();
11232
10843
  if (query.startsWith("T-")) {
11233
10844
  const task = await service.findById(query);
11234
10845
  if (!task) {
11235
- console.error(chalk22.red(`\u274C Task ${query} not found`));
10846
+ console.error(chalk23.red(`\u274C Task ${query} not found`));
11236
10847
  process.exit(1);
11237
10848
  }
11238
10849
  if (options.json) {
@@ -11243,34 +10854,34 @@ function createTaskShowCommand() {
11243
10854
  const statusIcon = blocked ? BLOCKED_ICON : STATUS_ICONS[task.status] || "\u{1F4CB}";
11244
10855
  const priIcon = PRIORITY_ICONS[task.priority] || "\u{1F7E1}";
11245
10856
  const priLabel = PRIORITY_LABELS[task.priority] || "Medium";
11246
- console.log(chalk22.bold(`
10857
+ console.log(chalk23.bold(`
11247
10858
  \u{1F4CC} ${task.id}: ${task.title}
11248
10859
  `));
11249
- console.log(` ${chalk22.dim("Status:")} ${statusIcon} ${task.status}${blocked ? chalk22.red(" (BLOCKED)") : ""}`);
11250
- 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}`);
11251
10862
  if (task.parent) {
11252
- console.log(` ${chalk22.dim("Parent:")} ${task.parent}`);
10863
+ console.log(` ${chalk23.dim("Parent:")} ${task.parent}`);
11253
10864
  }
11254
10865
  if (task.assigned_to) {
11255
- console.log(` ${chalk22.dim("Assigned:")} @${task.assigned_to} (${task.claimed_at})`);
10866
+ console.log(` ${chalk23.dim("Assigned:")} @${task.assigned_to} (${task.claimed_at})`);
11256
10867
  }
11257
10868
  if (task.depends_on.length > 0) {
11258
- console.log(` ${chalk22.dim("Depends on:")} ${task.depends_on.join(", ")}`);
10869
+ console.log(` ${chalk23.dim("Depends on:")} ${task.depends_on.join(", ")}`);
11259
10870
  if (blocked) {
11260
- console.log(` ${chalk22.dim("Blocked by:")} ${chalk22.red(blockedBy.join(", "))}`);
10871
+ console.log(` ${chalk23.dim("Blocked by:")} ${chalk23.red(blockedBy.join(", "))}`);
11261
10872
  }
11262
10873
  }
11263
10874
  if (task.tags.length > 0) {
11264
- console.log(` ${chalk22.dim("Tags:")} ${task.tags.join(", ")}`);
10875
+ console.log(` ${chalk23.dim("Tags:")} ${task.tags.join(", ")}`);
11265
10876
  }
11266
10877
  if (task.branch) {
11267
- console.log(` ${chalk22.dim("Branch:")} ${task.branch}`);
10878
+ console.log(` ${chalk23.dim("Branch:")} ${task.branch}`);
11268
10879
  }
11269
10880
  if (task.notes) {
11270
- console.log(` ${chalk22.dim("Notes:")} ${task.notes}`);
10881
+ console.log(` ${chalk23.dim("Notes:")} ${task.notes}`);
11271
10882
  }
11272
- console.log(` ${chalk22.dim("Created:")} ${task.created}`);
11273
- console.log(` ${chalk22.dim("Updated:")} ${task.updated}`);
10883
+ console.log(` ${chalk23.dim("Created:")} ${task.created}`);
10884
+ console.log(` ${chalk23.dim("Updated:")} ${task.updated}`);
11274
10885
  console.log();
11275
10886
  } else {
11276
10887
  const tasks = await service.filter({ parent: query });
@@ -11279,10 +10890,10 @@ function createTaskShowCommand() {
11279
10890
  return;
11280
10891
  }
11281
10892
  if (tasks.length === 0) {
11282
- console.log(chalk22.dim(`No tasks for parent: ${query}`));
10893
+ console.log(chalk23.dim(`No tasks for parent: ${query}`));
11283
10894
  return;
11284
10895
  }
11285
- console.log(chalk22.bold(`
10896
+ console.log(chalk23.bold(`
11286
10897
  \u{1F4CB} ${query} (${tasks.length} tasks)
11287
10898
  `));
11288
10899
  const allTasks = await service.readAll();
@@ -11290,11 +10901,11 @@ function createTaskShowCommand() {
11290
10901
  for (const task of tasks) {
11291
10902
  const isBlocked = task.status === "todo" && task.depends_on.length > 0 && !task.depends_on.every((id) => doneIds.has(id));
11292
10903
  const icon = isBlocked ? BLOCKED_ICON : STATUS_ICONS[task.status] || "\u{1F4CB}";
11293
- let line = ` ${icon} ${chalk22.dim(task.id)} P${task.priority} ${task.title}`;
11294
- 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}`);
11295
10906
  if (isBlocked) {
11296
10907
  const bb = task.depends_on.filter((id) => !doneIds.has(id));
11297
- line += chalk22.red(` (blocked: ${bb.join(", ")})`);
10908
+ line += chalk23.red(` (blocked: ${bb.join(", ")})`);
11298
10909
  }
11299
10910
  console.log(line);
11300
10911
  }
@@ -11305,7 +10916,7 @@ function createTaskShowCommand() {
11305
10916
 
11306
10917
  // src/commands/tasks/pick.ts
11307
10918
  import { Command as Command51 } from "commander";
11308
- import chalk23 from "chalk";
10919
+ import chalk24 from "chalk";
11309
10920
  import { confirm as confirm9 } from "@inquirer/prompts";
11310
10921
  function createTaskPickCommand() {
11311
10922
  return new Command51("pick").description("Claim the next available task").option("-j, --json", "Output JSON").action(async (options) => {
@@ -11316,8 +10927,8 @@ function createTaskPickCommand() {
11316
10927
  console.log(JSON.stringify({ picked: null, message: "No tasks ready" }));
11317
10928
  return;
11318
10929
  }
11319
- console.log(chalk23.dim("No tasks ready to pick."));
11320
- 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 "..."'));
11321
10932
  return;
11322
10933
  }
11323
10934
  const top = ready[0];
@@ -11327,13 +10938,13 @@ function createTaskPickCommand() {
11327
10938
  console.log(JSON.stringify(picked2, null, 2));
11328
10939
  return;
11329
10940
  }
11330
- console.log(chalk23.bold("\n\u{1F4CC} Next available task:"));
11331
- 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}`);
11332
10943
  if (top.parent) {
11333
- console.log(` ${chalk23.dim("Parent:")} ${top.parent}`);
10944
+ console.log(` ${chalk24.dim("Parent:")} ${top.parent}`);
11334
10945
  }
11335
10946
  if (ready.length > 1) {
11336
- console.log(chalk23.dim(`
10947
+ console.log(chalk24.dim(`
11337
10948
  +${ready.length - 1} more tasks ready`));
11338
10949
  }
11339
10950
  const proceed = await confirm9({
@@ -11341,18 +10952,18 @@ function createTaskPickCommand() {
11341
10952
  default: true
11342
10953
  });
11343
10954
  if (!proceed) {
11344
- console.log(chalk23.dim("\nCancelled."));
10955
+ console.log(chalk24.dim("\nCancelled."));
11345
10956
  return;
11346
10957
  }
11347
10958
  const picked = await service.pick(top.id);
11348
- console.log(chalk23.green(`
10959
+ console.log(chalk24.green(`
11349
10960
  \u2705 ${picked.id} assigned to @${picked.assigned_to}, status \u2192 in_progress`));
11350
10961
  });
11351
10962
  }
11352
10963
 
11353
10964
  // src/commands/tasks/done.ts
11354
10965
  import { Command as Command52 } from "commander";
11355
- import chalk24 from "chalk";
10966
+ import chalk25 from "chalk";
11356
10967
  function createTaskDoneCommand() {
11357
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) => {
11358
10969
  const service = new TaskService();
@@ -11362,9 +10973,9 @@ function createTaskDoneCommand() {
11362
10973
  console.log(JSON.stringify(task, null, 2));
11363
10974
  return;
11364
10975
  }
11365
- console.log(chalk24.green(`\u2705 ${task.id}: ${task.title} \u2192 done`));
10976
+ console.log(chalk25.green(`\u2705 ${task.id}: ${task.title} \u2192 done`));
11366
10977
  } catch (error) {
11367
- 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)}`));
11368
10979
  process.exit(1);
11369
10980
  }
11370
10981
  });
@@ -11372,7 +10983,7 @@ function createTaskDoneCommand() {
11372
10983
 
11373
10984
  // src/commands/tasks/dep.ts
11374
10985
  import { Command as Command53 } from "commander";
11375
- import chalk25 from "chalk";
10986
+ import chalk26 from "chalk";
11376
10987
  function createTaskDepCommand() {
11377
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) => {
11378
10989
  const service = new TaskService();
@@ -11382,10 +10993,10 @@ function createTaskDepCommand() {
11382
10993
  console.log(JSON.stringify(task, null, 2));
11383
10994
  return;
11384
10995
  }
11385
- console.log(chalk25.green(`\u2705 ${childId} now depends on ${parentId}`));
11386
- 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}`));
11387
10998
  } catch (error) {
11388
- 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)}`));
11389
11000
  process.exit(1);
11390
11001
  }
11391
11002
  });
@@ -11393,27 +11004,27 @@ function createTaskDepCommand() {
11393
11004
 
11394
11005
  // src/commands/tasks/sync.ts
11395
11006
  import { Command as Command54 } from "commander";
11396
- import chalk26 from "chalk";
11007
+ import chalk27 from "chalk";
11397
11008
  function createTaskSyncCommand() {
11398
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) => {
11399
11010
  const service = new TaskService();
11400
11011
  if (options.pull) {
11401
- console.log(chalk26.dim("\u23F3 Pulling tasks from origin/main..."));
11012
+ console.log(chalk27.dim("\u23F3 Pulling tasks from origin/main..."));
11402
11013
  try {
11403
11014
  const result = await service.syncPull();
11404
- 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`));
11405
11016
  } catch (error) {
11406
- 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)}`));
11407
11018
  process.exit(1);
11408
11019
  }
11409
11020
  return;
11410
11021
  }
11411
- console.log(chalk26.dim("\u23F3 Syncing tasks to git..."));
11022
+ console.log(chalk27.dim("\u23F3 Syncing tasks to git..."));
11412
11023
  try {
11413
11024
  await service.syncPush();
11414
- console.log(chalk26.green("\u2705 Tasks synced to git"));
11025
+ console.log(chalk27.green("\u2705 Tasks synced to git"));
11415
11026
  } catch (error) {
11416
- 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)}`));
11417
11028
  process.exit(1);
11418
11029
  }
11419
11030
  });
@@ -11421,107 +11032,107 @@ function createTaskSyncCommand() {
11421
11032
 
11422
11033
  // src/commands/tasks/guide.ts
11423
11034
  import { Command as Command55 } from "commander";
11424
- import chalk27 from "chalk";
11035
+ import chalk28 from "chalk";
11425
11036
  var GUIDE_TEXT = `
11426
- ${chalk27.cyan.bold("\u{1F4D6} Jai1 Task Management Guide")}
11427
-
11428
- ${chalk27.bold("\u2501\u2501\u2501 STATUSES \u2501\u2501\u2501")}
11429
- ${chalk27.dim("todo")} \u{1F4CB} Ch\u01B0a b\u1EAFt \u0111\u1EA7u
11430
- ${chalk27.dim("in_progress")} \u{1F535} \u0110ang l\xE0m (bao g\u1ED3m review)
11431
- ${chalk27.dim("done")} \u2705 Ho\xE0n th\xE0nh
11432
- ${chalk27.dim("cancelled")} \u26AB Hu\u1EF7
11433
- ${chalk27.dim("(blocked)")} \u{1F534} Computed: depends_on ch\u01B0a done
11434
-
11435
- ${chalk27.bold("\u2501\u2501\u2501 PRIORITY \u2501\u2501\u2501")}
11436
- ${chalk27.dim("0")} = \u{1F525} Critical \u2014 Prod down, security, block c\u1EA3 team
11437
- ${chalk27.dim("1")} = \u{1F534} High \u2014 Feature ch\xEDnh, deadline g\u1EA7n
11438
- ${chalk27.dim("2")} = \u{1F7E1} Medium \u2014 B\xECnh th\u01B0\u1EDDng (default)
11439
- ${chalk27.dim("3")} = \u{1F7E2} Low \u2014 Nice-to-have, docs, refactor
11440
-
11441
- ${chalk27.bold("\u2501\u2501\u2501 QUICK START \u2501\u2501\u2501")}
11442
- ${chalk27.cyan("jai1 t add")} "Fix login bug" -p 1 -P bug/login
11443
- ${chalk27.cyan("jai1 t ready")} Show tasks s\u1EB5n s\xE0ng
11444
- ${chalk27.cyan("jai1 t pick")} Claim & start working
11445
- ${chalk27.cyan("jai1 t done")} T-003 Mark complete
11446
-
11447
- ${chalk27.bold("\u2501\u2501\u2501 DAILY WORKFLOW \u2501\u2501\u2501")}
11448
- ${chalk27.cyan("jai1 t sync --pull")} Pull latest tasks
11449
- ${chalk27.cyan("jai1 t summary")} Dashboard t\u1ED5ng quan
11450
- ${chalk27.cyan("jai1 t ready")} Xem tasks s\u1EB5n s\xE0ng
11451
- ${chalk27.cyan("jai1 t pick")} Claim task m\u1EDBi
11452
- ${chalk27.cyan("jai1 t done")} T-xxx Ho\xE0n th\xE0nh task
11453
- ${chalk27.cyan("jai1 t sync --push")} Push l\xEAn git
11454
-
11455
- ${chalk27.bold("\u2501\u2501\u2501 ADDING TASKS \u2501\u2501\u2501")}
11456
- ${chalk27.yellow("\u26A0 Lu\xF4n ki\u1EC3m tra duplicate tr\u01B0\u1EDBc khi add:")}
11457
- ${chalk27.cyan("jai1 t list -P")} feature/xxx
11458
-
11459
- ${chalk27.dim("Add cho feature:")}
11460
- ${chalk27.cyan("jai1 t add")} "Setup DB schema" -p 1 -P feature/xxx
11461
- ${chalk27.cyan("jai1 t add")} "Create API" -p 1 -P feature/xxx
11462
- ${chalk27.cyan("jai1 t add")} "Build UI" -p 2 -P feature/xxx
11463
-
11464
- ${chalk27.dim("Add cho plan:")}
11465
- ${chalk27.cyan("jai1 t add")} "Refactor middleware" -p 2 -P plan/xxx
11466
-
11467
- ${chalk27.dim("Add standalone:")}
11468
- ${chalk27.cyan("jai1 t add")} "Fix README typo" -p 3
11469
-
11470
- ${chalk27.dim("Add bug fix:")}
11471
- ${chalk27.cyan("jai1 t add")} "Fix login redirect" -p 1 -P bug/xxx
11472
-
11473
- ${chalk27.bold("\u2501\u2501\u2501 DEPENDENCY \u2501\u2501\u2501")}
11474
- ${chalk27.dim("Task dependency:")}
11475
- ${chalk27.cyan("jai1 t dep")} T-002 T-001 T-002 ch\u1EDD T-001 done
11476
- ${chalk27.cyan("jai1 t dep")} T-003 T-002 T-003 ch\u1EDD T-002 done
11477
-
11478
- ${chalk27.dim("Feature-level dependency:")}
11479
- ${chalk27.dim("# N\u1EBFu feature/auth ph\u1EE5 thu\u1ED9c feature/user-model:")}
11480
- ${chalk27.cyan("jai1 t add")} "[DEP] Wait for feature/user-model" -p 1 -P feature/auth
11481
- ${chalk27.dim("# R\u1ED3i dep n\xF3 v\u1EDBi tasks cu\u1ED1i c\u1EE7a user-model")}
11482
-
11483
- ${chalk27.dim("View deps:")}
11484
- ${chalk27.cyan("jai1 t show")} T-002 Hi\u1EC7n depends_on
11485
-
11486
- ${chalk27.bold("\u2501\u2501\u2501 TEAM COLLABORATION \u2501\u2501\u2501")}
11487
- ${chalk27.yellow("\u26A0 Assignment ch\u1EC9 qua pick \u2014 kh\xF4ng set th\u1EE7 c\xF4ng.")}
11488
- ${chalk27.dim("Khi b\u1EA1n pick \u2192 team th\u1EA5y task \u0111\xE3 c\xF3 ng\u01B0\u1EDDi nh\u1EADn.")}
11489
-
11490
- ${chalk27.dim("Sync morning:")} ${chalk27.cyan("jai1 t sync --pull")}
11491
- ${chalk27.dim("Sync evening:")} ${chalk27.cyan("jai1 t sync --push")}
11492
-
11493
- ${chalk27.bold("\u2501\u2501\u2501 FOR AI AGENTS (Workflow Integration) \u2501\u2501\u2501")}
11494
- ${chalk27.dim("Khi t\u1EA1o tasks t\u1EEB feature/plan:")}
11495
- 1. ${chalk27.cyan("jai1 t list -P")} <parent> Check existing (tr\xE1nh duplicate)
11496
- 2. ${chalk27.cyan("jai1 t add")} "..." -p <0-3> -P <parent> Add t\u1EEBng task
11497
- 3. ${chalk27.cyan("jai1 t dep")} <child> <parent> Set dependencies
11498
- 4. ${chalk27.cyan("jai1 t done")} <id> Mark complete
11499
-
11500
- ${chalk27.dim("Khi implement task ti\u1EBFp theo:")}
11501
- 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>)
11502
11113
  2. Implement task
11503
- 3. ${chalk27.cyan("jai1 t done")} <id>
11114
+ 3. ${chalk28.cyan("jai1 t done")} <id>
11504
11115
 
11505
- ${chalk27.dim("Status transitions:")}
11116
+ ${chalk28.dim("Status transitions:")}
11506
11117
  add \u2192 todo (default)
11507
11118
  pick \u2192 in_progress (auto assign)
11508
11119
  done \u2192 done
11509
11120
  update -s \u2192 any valid status
11510
11121
 
11511
- ${chalk27.bold("\u2501\u2501\u2501 ALL COMMANDS \u2501\u2501\u2501")}
11512
- ${chalk27.cyan("jai1 t list")} [-s status] [-P parent] [-j]
11513
- ${chalk27.cyan("jai1 t ready")} [-P parent] [-j]
11514
- ${chalk27.cyan("jai1 t add")} <title> [-p 0-3] [-P parent] [-t tags] [-j]
11515
- ${chalk27.cyan("jai1 t update")} <id> -s <status> [-j]
11516
- ${chalk27.cyan("jai1 t show")} <id|parent> [-j]
11517
- ${chalk27.cyan("jai1 t pick")} [-j]
11518
- ${chalk27.cyan("jai1 t done")} <id> [-j]
11519
- ${chalk27.cyan("jai1 t dep")} <childId> <parentId> [-j]
11520
- ${chalk27.cyan("jai1 t sync")} [--pull] [--push]
11521
- ${chalk27.cyan("jai1 t summary")} [-j]
11522
- ${chalk27.cyan("jai1 t guide")}
11523
-
11524
- ${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)")}
11525
11136
  `;
11526
11137
  function createTaskGuideCommand() {
11527
11138
  return new Command55("guide").description("Show full task management guide").action(() => {
@@ -11556,11 +11167,11 @@ function createTasksCommand() {
11556
11167
 
11557
11168
  // src/commands/kit/index.ts
11558
11169
  import { Command as Command60 } from "commander";
11559
- import chalk29 from "chalk";
11170
+ import chalk30 from "chalk";
11560
11171
 
11561
11172
  // src/commands/kit/list.ts
11562
11173
  import { Command as Command57 } from "commander";
11563
- import chalk28 from "chalk";
11174
+ import chalk29 from "chalk";
11564
11175
  import Table6 from "cli-table3";
11565
11176
 
11566
11177
  // src/services/starter-kit.service.ts
@@ -11634,7 +11245,7 @@ function createKitListCommand() {
11634
11245
  if (!config) {
11635
11246
  throw new ValidationError('Not initialized. Run "jai1 auth" first.');
11636
11247
  }
11637
- 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..."));
11638
11249
  console.log();
11639
11250
  const kitService = new StarterKitService();
11640
11251
  const kits = await kitService.list(config, {
@@ -11642,9 +11253,9 @@ function createKitListCommand() {
11642
11253
  search: options.search
11643
11254
  });
11644
11255
  if (kits.length === 0) {
11645
- 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."));
11646
11257
  if (options.category || options.search) {
11647
- 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."));
11648
11259
  }
11649
11260
  return;
11650
11261
  }
@@ -11668,28 +11279,28 @@ function createKitListCommand() {
11668
11279
  const categoryKits = byCategory[category];
11669
11280
  const categoryIcon = category === "frontend" ? "\u{1F3A8}" : category === "backend" ? "\u2699\uFE0F" : category === "fullstack" ? "\u{1F680}" : "\u{1F4E6}";
11670
11281
  console.log(
11671
- chalk28.bold(`${categoryIcon} ${category.charAt(0).toUpperCase() + category.slice(1)}`)
11282
+ chalk29.bold(`${categoryIcon} ${category.charAt(0).toUpperCase() + category.slice(1)}`)
11672
11283
  );
11673
11284
  const table = new Table6({
11674
11285
  head: [
11675
- chalk28.cyan("Slug"),
11676
- chalk28.cyan("M\xF4 t\u1EA3"),
11677
- chalk28.cyan("Version")
11286
+ chalk29.cyan("Slug"),
11287
+ chalk29.cyan("M\xF4 t\u1EA3"),
11288
+ chalk29.cyan("Version")
11678
11289
  ],
11679
11290
  style: { head: [], border: ["gray"] }
11680
11291
  });
11681
11292
  for (const kit of categoryKits) {
11682
11293
  table.push([
11683
- chalk28.white(kit.slug),
11684
- chalk28.dim(kit.description.slice(0, 50)),
11685
- chalk28.green(`v${kit.version}`)
11294
+ chalk29.white(kit.slug),
11295
+ chalk29.dim(kit.description.slice(0, 50)),
11296
+ chalk29.green(`v${kit.version}`)
11686
11297
  ]);
11687
11298
  }
11688
11299
  console.log(table.toString());
11689
11300
  console.log();
11690
11301
  }
11691
- console.log(chalk28.dim(`T\u1ED5ng c\u1ED9ng: ${kits.length} starter kit(s)`));
11692
- 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'));
11693
11304
  });
11694
11305
  }
11695
11306
 
@@ -11969,20 +11580,20 @@ async function getAllFiles(dir) {
11969
11580
 
11970
11581
  // src/commands/kit/index.ts
11971
11582
  function showKitHelp() {
11972
- 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"));
11973
11584
  console.log();
11974
- console.log(chalk29.bold("C\xE1c l\u1EC7nh:"));
11975
- console.log(` ${chalk29.cyan("list")} Li\u1EC7t k\xEA c\xE1c starter kits c\xF3 s\u1EB5n`);
11976
- console.log(` ${chalk29.cyan("info")} Xem chi ti\u1EBFt m\u1ED9t starter kit`);
11977
- 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`);
11978
11589
  console.log();
11979
- console.log(chalk29.bold("V\xED d\u1EE5:"));
11980
- console.log(chalk29.dim(" $ jai1 kit list"));
11981
- console.log(chalk29.dim(" $ jai1 kit list --category frontend"));
11982
- console.log(chalk29.dim(" $ jai1 kit info next-tw4-shadcn"));
11983
- 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"));
11984
11595
  console.log();
11985
- 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'));
11986
11597
  }
11987
11598
  function createKitCommand() {
11988
11599
  const cmd = new Command60("kit").description("Manage starter kits for new projects").action(() => {
@@ -11996,11 +11607,11 @@ function createKitCommand() {
11996
11607
 
11997
11608
  // src/commands/rules/index.ts
11998
11609
  import { Command as Command67 } from "commander";
11999
- import chalk31 from "chalk";
11610
+ import chalk32 from "chalk";
12000
11611
 
12001
11612
  // src/commands/rules/list.ts
12002
11613
  import { Command as Command61 } from "commander";
12003
- import chalk30 from "chalk";
11614
+ import chalk31 from "chalk";
12004
11615
  import Table7 from "cli-table3";
12005
11616
  function createRulesListCommand() {
12006
11617
  return new Command61("list").description("List available rule presets").option("--json", "Output as JSON").action(async (options) => {
@@ -12009,7 +11620,7 @@ function createRulesListCommand() {
12009
11620
  if (!config) {
12010
11621
  throw new ValidationError('Not initialized. Run "jai1 auth" first.');
12011
11622
  }
12012
- 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..."));
12013
11624
  console.log();
12014
11625
  try {
12015
11626
  const response = await fetch(`${config.apiUrl}/api/rules/presets`, {
@@ -12026,23 +11637,23 @@ function createRulesListCommand() {
12026
11637
  return;
12027
11638
  }
12028
11639
  if (data.total === 0) {
12029
- console.log(chalk30.yellow("Kh\xF4ng c\xF3 presets n\xE0o."));
11640
+ console.log(chalk31.yellow("Kh\xF4ng c\xF3 presets n\xE0o."));
12030
11641
  return;
12031
11642
  }
12032
11643
  console.log(
12033
- 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" : ""}`)
12034
11645
  );
12035
11646
  console.log();
12036
11647
  for (const preset of data.presets) {
12037
- console.log(chalk30.bold.cyan(`\u{1F4E6} ${preset.slug}`));
11648
+ console.log(chalk31.bold.cyan(`\u{1F4E6} ${preset.slug}`));
12038
11649
  const table = new Table7({
12039
11650
  style: { head: [], border: ["gray"], compact: true },
12040
11651
  colWidths: [15, 55]
12041
11652
  });
12042
11653
  table.push(
12043
- [chalk30.dim("T\xEAn"), chalk30.white(preset.name)],
12044
- [chalk30.dim("M\xF4 t\u1EA3"), chalk30.white(preset.description)],
12045
- [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}`)]
12046
11657
  );
12047
11658
  const stackParts = [];
12048
11659
  if (preset.stack.frontend) stackParts.push(preset.stack.frontend);
@@ -12050,16 +11661,16 @@ function createRulesListCommand() {
12050
11661
  if (preset.stack.css) stackParts.push(preset.stack.css);
12051
11662
  if (preset.stack.database) stackParts.push(preset.stack.database);
12052
11663
  if (stackParts.length > 0) {
12053
- table.push([chalk30.dim("Stack"), chalk30.yellow(stackParts.join(" + "))]);
11664
+ table.push([chalk31.dim("Stack"), chalk31.yellow(stackParts.join(" + "))]);
12054
11665
  }
12055
11666
  table.push(
12056
- [chalk30.dim("Tags"), chalk30.dim(preset.tags.join(", ") || "-")],
12057
- [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())]
12058
11669
  );
12059
11670
  console.log(table.toString());
12060
11671
  console.log();
12061
11672
  }
12062
- 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'));
12063
11674
  } catch (error) {
12064
11675
  throw new Error(
12065
11676
  `L\u1ED7i khi t\u1EA3i presets: ${error instanceof Error ? error.message : String(error)}`
@@ -13487,23 +13098,23 @@ async function checkIdeFilesExist(ideId, format) {
13487
13098
 
13488
13099
  // src/commands/rules/index.ts
13489
13100
  function showRulesHelp() {
13490
- 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"));
13491
13102
  console.log();
13492
- console.log(chalk31.bold("C\xE1c l\u1EC7nh:"));
13493
- console.log(` ${chalk31.cyan("list")} Li\u1EC7t k\xEA c\xE1c presets c\xF3 s\u1EB5n`);
13494
- console.log(` ${chalk31.cyan("info")} Xem chi ti\u1EBFt m\u1ED9t preset`);
13495
- console.log(` ${chalk31.cyan("init")} Kh\u1EDFi t\u1EA1o rules t\u1EEB preset`);
13496
- console.log(` ${chalk31.cyan("apply")} \xC1p d\u1EE5ng preset v\xE0o project`);
13497
- console.log(` ${chalk31.cyan("sync")} \u0110\u1ED3ng b\u1ED9 rules sang c\xE1c \u0111\u1ECBnh d\u1EA1ng IDE`);
13498
- 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`);
13499
13110
  console.log();
13500
- console.log(chalk31.bold("V\xED d\u1EE5:"));
13501
- console.log(chalk31.dim(" $ jai1 rules list"));
13502
- console.log(chalk31.dim(" $ jai1 rules info react-typescript"));
13503
- console.log(chalk31.dim(" $ jai1 rules init --preset=react-typescript"));
13504
- 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"));
13505
13116
  console.log();
13506
- 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'));
13507
13118
  }
13508
13119
  function createRulesCommand() {
13509
13120
  const rulesCommand = new Command67("rules").description("Manage rule presets for AI agents").action(() => {
@@ -15236,92 +14847,11 @@ async function resetSettings2(groupKeys) {
15236
14847
  console.log("\u{1F4A1} M\u1EB9o: Kh\u1EDFi \u0111\u1ED9ng l\u1EA1i VSCode \u0111\u1EC3 \xE1p d\u1EE5ng c\xE1c thay \u0111\u1ED5i.");
15237
14848
  }
15238
14849
 
15239
- // src/commands/context.ts
15240
- import React32 from "react";
15241
- import { render as render6 } from "ink";
15242
- import { Command as Command77 } from "commander";
15243
- function createContextCommand() {
15244
- 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) => {
15245
- let initialIDE;
15246
- if (options.ide) {
15247
- const validIDEs = ["cursor", "windsurf", "antigravity", "jai1"];
15248
- if (!validIDEs.includes(options.ide)) {
15249
- console.error(`\u274C IDE kh\xF4ng h\u1EE3p l\u1EC7: ${options.ide}`);
15250
- console.error(` IDE h\u1EE3p l\u1EC7: ${validIDEs.join(", ")}`);
15251
- process.exit(1);
15252
- }
15253
- initialIDE = options.ide;
15254
- }
15255
- let initialType;
15256
- if (options.type) {
15257
- const validTypes = ["rules", "workflows", "skills", "agents", "prompts", "context"];
15258
- if (!validTypes.includes(options.type)) {
15259
- console.error(`\u274C Lo\u1EA1i context kh\xF4ng h\u1EE3p l\u1EC7: ${options.type}`);
15260
- console.error(` Lo\u1EA1i h\u1EE3p l\u1EC7: ${validTypes.join(", ")}`);
15261
- process.exit(1);
15262
- }
15263
- initialType = options.type;
15264
- }
15265
- if (options.stats) {
15266
- await printStats2();
15267
- return;
15268
- }
15269
- const { waitUntilExit } = render6(
15270
- React32.createElement(ContextApp, {
15271
- initialIDE,
15272
- initialType,
15273
- onExit: () => {
15274
- process.exit(0);
15275
- }
15276
- })
15277
- );
15278
- await waitUntilExit();
15279
- });
15280
- return cmd;
15281
- }
15282
- async function printStats2() {
15283
- const scanner = new ContextScannerService();
15284
- console.log("\u{1F50D} \u0110ang qu\xE9t context...\n");
15285
- try {
15286
- const context = await scanner.scanAll();
15287
- if (context.ides.length === 0) {
15288
- console.log("\u26A0\uFE0F Kh\xF4ng t\xECm th\u1EA5y context n\xE0o");
15289
- console.log(" H\xE3y ch\u1EA1y `jai1 apply` \u0111\u1EC3 c\xE0i \u0111\u1EB7t context cho IDE c\u1EE7a b\u1EA1n.\n");
15290
- return;
15291
- }
15292
- console.log("\u{1F4CA} Th\u1ED1ng k\xEA Context\n");
15293
- console.log(`\u{1F4C1} Project: ${context.projectPath}`);
15294
- console.log(`\u{1F550} Scan time: ${context.scanTime.toLocaleString("vi-VN")}
15295
- `);
15296
- for (const ideContext of context.ides) {
15297
- console.log(`${ideContext.config.icon} ${ideContext.config.name}`);
15298
- console.log(` Path: ${ideContext.config.basePath}`);
15299
- console.log(` Items: ${ideContext.stats.totalItems}`);
15300
- const types = [];
15301
- if (ideContext.stats.byType.rules) types.push(`${ideContext.stats.byType.rules} rules`);
15302
- if (ideContext.stats.byType.workflows) types.push(`${ideContext.stats.byType.workflows} workflows`);
15303
- if (ideContext.stats.byType.skills) types.push(`${ideContext.stats.byType.skills} skills`);
15304
- if (ideContext.stats.byType.agents) types.push(`${ideContext.stats.byType.agents} agents`);
15305
- if (ideContext.stats.byType.prompts) types.push(`${ideContext.stats.byType.prompts} prompts`);
15306
- if (ideContext.stats.byType.context) types.push(`${ideContext.stats.byType.context} context`);
15307
- if (types.length > 0) {
15308
- console.log(` Breakdown: ${types.join(", ")}`);
15309
- }
15310
- console.log("");
15311
- }
15312
- console.log(`\u2705 T\u1ED5ng: ${context.totalItems} items
15313
- `);
15314
- } catch (error) {
15315
- console.error("\u274C L\u1ED7i khi qu\xE9t context:", error);
15316
- process.exit(1);
15317
- }
15318
- }
15319
-
15320
14850
  // src/commands/migrate-ide.ts
15321
- import { Command as Command78 } from "commander";
14851
+ import { Command as Command77 } from "commander";
15322
14852
  import { checkbox as checkbox8, confirm as confirm19 } from "@inquirer/prompts";
15323
14853
  function createMigrateIdeCommand() {
15324
- 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) => {
15325
14855
  await runMigrateIde(options);
15326
14856
  });
15327
14857
  return cmd;
@@ -15430,62 +14960,62 @@ async function runMigrateIde(options) {
15430
14960
 
15431
14961
  // src/utils/help-formatter.ts
15432
14962
  import boxen4 from "boxen";
15433
- import chalk32 from "chalk";
14963
+ import chalk33 from "chalk";
15434
14964
  import gradient from "gradient-string";
15435
14965
  import figlet from "figlet";
15436
14966
  function showCustomHelp(version) {
15437
14967
  const title = figlet.textSync("JAI1", { font: "Small" });
15438
14968
  console.log(gradient.pastel(title));
15439
14969
  console.log(
15440
- boxen4(chalk32.cyan(`Agentic Coding CLI v${version}`), {
14970
+ boxen4(chalk33.cyan(`Agentic Coding CLI v${version}`), {
15441
14971
  padding: { left: 1, right: 1, top: 0, bottom: 0 },
15442
14972
  borderStyle: "round",
15443
14973
  borderColor: "cyan"
15444
14974
  })
15445
14975
  );
15446
- 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"));
15447
14977
  console.log(" auth X\xE1c th\u1EF1c v\xE0 c\u1EA5u h\xECnh client");
15448
14978
  console.log(" status Hi\u1EC3n th\u1ECB tr\u1EA1ng th\xE1i c\u1EA5u h\xECnh");
15449
14979
  console.log(" client-info T\u1EA1o th\xF4ng tin client \u0111\u1EC3 g\u1EEDi \u0111\u1ED9i ph\xE1t tri\u1EC3n");
15450
14980
  console.log(" errors Qu\u1EA3n l\xFD error logs c\u1EE5c b\u1ED9");
15451
14981
  console.log(" guide H\u01B0\u1EDBng d\u1EABn s\u1EED d\u1EE5ng nhanh");
15452
14982
  console.log(" doctor Chu\u1EA9n \u0111o\xE1n project hi\u1EC7n t\u1EA1i");
15453
- 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"));
15454
14984
  console.log(" apply C\xE0i \u0111\u1EB7t components (interactive)");
15455
14985
  console.log(" update C\u1EADp nh\u1EADt components \u0111\xE3 c\xE0i");
15456
14986
  console.log(" check Ki\u1EC3m tra c\u1EADp nh\u1EADt t\u1EEB server");
15457
- 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"));
15458
14988
  console.log(" ide L\u1EC7nh c\u1EA5u h\xECnh IDE");
15459
14989
  console.log(" chat Chat AI v\u1EDBi Jai1 LLM Proxy");
15460
14990
  console.log(" openai-keys Th\xF4ng tin API credentials");
15461
- console.log(chalk32.bold("\n\u{1F916} AI Tools"));
14991
+ console.log(chalk33.bold("\n\u{1F916} AI Tools"));
15462
14992
  console.log(" translate D\u1ECBch v\u0103n b\u1EA3n/file b\u1EB1ng AI");
15463
14993
  console.log(" image T\u1EA1o \u1EA3nh (Coming Soon)");
15464
14994
  console.log(" stats Th\u1ED1ng k\xEA s\u1EED d\u1EE5ng LLM");
15465
14995
  console.log(" feedback G\u1EEDi b\xE1o c\xE1o/\u0111\u1EC1 xu\u1EA5t");
15466
- console.log(chalk32.bold("\n\u{1F4C1} Project"));
14996
+ console.log(chalk33.bold("\n\u{1F4C1} Project"));
15467
14997
  console.log(" kit Qu\u1EA3n l\xFD starter kits");
15468
14998
  console.log(" rules Qu\u1EA3n l\xFD rule presets");
15469
14999
  console.log(" deps Qu\u1EA3n l\xFD dependencies");
15470
15000
  console.log(" redmine Redmine context sync");
15471
- console.log(chalk32.bold("\n\u2699\uFE0F B\u1EA3o tr\xEC"));
15001
+ console.log(chalk33.bold("\n\u2699\uFE0F B\u1EA3o tr\xEC"));
15472
15002
  console.log(" upgrade C\u1EADp nh\u1EADt CLI client");
15473
15003
  console.log(" clean D\u1ECDn d\u1EB9p cache/backup");
15474
15004
  console.log(" utils Developer utilities");
15475
15005
  const name = getCliName();
15476
- console.log(chalk32.dim(`
15006
+ console.log(chalk33.dim(`
15477
15007
  S\u1EED d\u1EE5ng: ${name} [l\u1EC7nh] --help \u0111\u1EC3 xem chi ti\u1EBFt`));
15478
15008
  }
15479
15009
  function showUnknownCommand(commandName) {
15480
- 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}`));
15481
15011
  const name = getCliName();
15482
- console.error(chalk32.dim(`
15012
+ console.error(chalk33.dim(`
15483
15013
  G\u1EE3i \xFD: Ch\u1EA1y ${name} --help \u0111\u1EC3 xem danh s\xE1ch l\u1EC7nh`));
15484
15014
  }
15485
15015
 
15486
15016
  // src/cli.ts
15487
15017
  checkNodeVersion();
15488
- var program = new Command79();
15018
+ var program = new Command78();
15489
15019
  if (process.argv.includes("-v") || process.argv.includes("--version")) {
15490
15020
  console.log(package_default.version);
15491
15021
  if (!process.argv.includes("--skip-update-check")) {
@@ -15524,9 +15054,9 @@ program.addCommand(createKitCommand());
15524
15054
  program.addCommand(createRulesCommand());
15525
15055
  program.addCommand(createUpgradeCommand());
15526
15056
  program.addCommand(createCleanCommand());
15527
- var redmineCommand = new Command79("redmine").description("Redmine context sync commands");
15057
+ var redmineCommand = new Command78("redmine").description("Redmine context sync commands");
15528
15058
  redmineCommand.addCommand(createRedmineCheckCommand());
15529
- 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");
15530
15060
  syncCommand.addCommand(createSyncIssueCommand());
15531
15061
  syncCommand.addCommand(createSyncProjectCommand());
15532
15062
  redmineCommand.addCommand(syncCommand);