@jvittechs/jai1-cli 0.1.66 → 0.1.68
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +1314 -65
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -33,7 +33,7 @@ var NetworkError = class extends Jai1Error {
|
|
|
33
33
|
// package.json
|
|
34
34
|
var package_default = {
|
|
35
35
|
name: "@jvittechs/jai1-cli",
|
|
36
|
-
version: "0.1.
|
|
36
|
+
version: "0.1.68",
|
|
37
37
|
description: "Unified CLI for Jai1 Framework Management and Redmine Context Sync",
|
|
38
38
|
type: "module",
|
|
39
39
|
bin: {
|
|
@@ -388,9 +388,9 @@ async function handleAuth(options) {
|
|
|
388
388
|
output: process.stdout
|
|
389
389
|
});
|
|
390
390
|
const question = (prompt) => {
|
|
391
|
-
return new Promise((
|
|
391
|
+
return new Promise((resolve4) => {
|
|
392
392
|
rl.question(prompt, (answer) => {
|
|
393
|
-
|
|
393
|
+
resolve4(answer);
|
|
394
394
|
});
|
|
395
395
|
});
|
|
396
396
|
};
|
|
@@ -3534,7 +3534,7 @@ var AgenticGuideView = ({ onBack }) => {
|
|
|
3534
3534
|
setMessages((prev) => [...prev, userMessage]);
|
|
3535
3535
|
setInputValue("");
|
|
3536
3536
|
setIsTyping(true);
|
|
3537
|
-
await new Promise((
|
|
3537
|
+
await new Promise((resolve4) => setTimeout(resolve4, 800 + Math.random() * 700));
|
|
3538
3538
|
const response = getMockResponse(text);
|
|
3539
3539
|
const assistantMessage = {
|
|
3540
3540
|
id: `assistant-${Date.now()}`,
|
|
@@ -5717,12 +5717,1231 @@ Examples:
|
|
|
5717
5717
|
}
|
|
5718
5718
|
|
|
5719
5719
|
// src/commands/utils/interactive.ts
|
|
5720
|
-
import
|
|
5720
|
+
import React39 from "react";
|
|
5721
5721
|
import { render as render5 } from "ink";
|
|
5722
5722
|
|
|
5723
5723
|
// src/ui/utils/UtilsApp.tsx
|
|
5724
|
+
import React38, { useState as useState25 } from "react";
|
|
5725
|
+
import { Box as Box28, Text as Text29, useInput as useInput23, useApp as useApp5 } from "ink";
|
|
5726
|
+
|
|
5727
|
+
// src/ui/utils/views/PasswordView.tsx
|
|
5724
5728
|
import React27, { useState as useState14 } from "react";
|
|
5725
|
-
import { Box as Box17, Text as Text18, useInput as useInput12
|
|
5729
|
+
import { Box as Box17, Text as Text18, useInput as useInput12 } from "ink";
|
|
5730
|
+
import TextInput4 from "ink-text-input";
|
|
5731
|
+
var PasswordView = () => {
|
|
5732
|
+
const [length, setLength] = useState14("16");
|
|
5733
|
+
const [count, setCount] = useState14("1");
|
|
5734
|
+
const [passwords, setPasswords] = useState14([]);
|
|
5735
|
+
const [focusedField, setFocusedField] = useState14("length");
|
|
5736
|
+
const [copiedIndex, setCopiedIndex] = useState14(null);
|
|
5737
|
+
const service = new UtilsService();
|
|
5738
|
+
useInput12((input, key) => {
|
|
5739
|
+
if (key.tab) {
|
|
5740
|
+
if (focusedField === "length") setFocusedField("count");
|
|
5741
|
+
else if (focusedField === "count") setFocusedField("generate");
|
|
5742
|
+
else setFocusedField("length");
|
|
5743
|
+
} else if (key.return && focusedField === "generate") {
|
|
5744
|
+
handleGenerate();
|
|
5745
|
+
} else if (input === "c" && passwords.length > 0) {
|
|
5746
|
+
handleCopy(0);
|
|
5747
|
+
}
|
|
5748
|
+
});
|
|
5749
|
+
const handleGenerate = () => {
|
|
5750
|
+
const newPasswords = [];
|
|
5751
|
+
const lengthNum = parseInt(length, 10) || 16;
|
|
5752
|
+
const countNum = parseInt(count, 10) || 1;
|
|
5753
|
+
for (let i = 0; i < countNum; i++) {
|
|
5754
|
+
newPasswords.push(
|
|
5755
|
+
service.generatePassword({
|
|
5756
|
+
length: lengthNum,
|
|
5757
|
+
lowercase: true,
|
|
5758
|
+
uppercase: true,
|
|
5759
|
+
digits: true,
|
|
5760
|
+
symbols: true
|
|
5761
|
+
})
|
|
5762
|
+
);
|
|
5763
|
+
}
|
|
5764
|
+
setPasswords(newPasswords);
|
|
5765
|
+
setCopiedIndex(null);
|
|
5766
|
+
};
|
|
5767
|
+
const handleCopy = async (index) => {
|
|
5768
|
+
try {
|
|
5769
|
+
const { default: clipboardy } = await import("clipboardy");
|
|
5770
|
+
await clipboardy.write(passwords[index]);
|
|
5771
|
+
setCopiedIndex(index);
|
|
5772
|
+
setTimeout(() => setCopiedIndex(null), 2e3);
|
|
5773
|
+
} catch (error) {
|
|
5774
|
+
}
|
|
5775
|
+
};
|
|
5776
|
+
return /* @__PURE__ */ React27.createElement(Box17, { flexDirection: "column" }, /* @__PURE__ */ React27.createElement(Box17, { marginBottom: 1 }, /* @__PURE__ */ React27.createElement(Text18, { bold: true, color: "cyan" }, "\u{1F510} Password Generator")), /* @__PURE__ */ React27.createElement(
|
|
5777
|
+
Box17,
|
|
5778
|
+
{
|
|
5779
|
+
flexDirection: "column",
|
|
5780
|
+
borderStyle: "single",
|
|
5781
|
+
borderColor: "gray",
|
|
5782
|
+
paddingX: 2,
|
|
5783
|
+
paddingY: 1,
|
|
5784
|
+
marginBottom: 1
|
|
5785
|
+
},
|
|
5786
|
+
/* @__PURE__ */ React27.createElement(Text18, { bold: true, color: "yellow", marginBottom: 1 }, "Options:"),
|
|
5787
|
+
/* @__PURE__ */ React27.createElement(Box17, { marginBottom: 1 }, /* @__PURE__ */ React27.createElement(Box17, { width: 20 }, /* @__PURE__ */ React27.createElement(Text18, { color: focusedField === "length" ? "green" : void 0 }, focusedField === "length" ? "\u25B6 " : " ", "Length:")), /* @__PURE__ */ React27.createElement(Box17, { width: 10 }, focusedField === "length" ? /* @__PURE__ */ React27.createElement(TextInput4, { value: length, onChange: setLength }) : /* @__PURE__ */ React27.createElement(Text18, null, length)), /* @__PURE__ */ React27.createElement(Text18, { dimColor: true }, "(characters)")),
|
|
5788
|
+
/* @__PURE__ */ React27.createElement(Box17, { marginBottom: 1 }, /* @__PURE__ */ React27.createElement(Box17, { width: 20 }, /* @__PURE__ */ React27.createElement(Text18, { color: focusedField === "count" ? "green" : void 0 }, focusedField === "count" ? "\u25B6 " : " ", "Count:")), /* @__PURE__ */ React27.createElement(Box17, { width: 10 }, focusedField === "count" ? /* @__PURE__ */ React27.createElement(TextInput4, { value: count, onChange: setCount }) : /* @__PURE__ */ React27.createElement(Text18, null, count)), /* @__PURE__ */ React27.createElement(Text18, { dimColor: true }, "(passwords to generate)")),
|
|
5789
|
+
/* @__PURE__ */ React27.createElement(Box17, { marginTop: 1 }, /* @__PURE__ */ React27.createElement(
|
|
5790
|
+
Text18,
|
|
5791
|
+
{
|
|
5792
|
+
bold: true,
|
|
5793
|
+
backgroundColor: focusedField === "generate" ? "green" : void 0,
|
|
5794
|
+
color: focusedField === "generate" ? "black" : "green"
|
|
5795
|
+
},
|
|
5796
|
+
focusedField === "generate" ? "\u25B6 " : " ",
|
|
5797
|
+
"[ Generate Passwords ]"
|
|
5798
|
+
))
|
|
5799
|
+
), passwords.length > 0 && /* @__PURE__ */ React27.createElement(
|
|
5800
|
+
Box17,
|
|
5801
|
+
{
|
|
5802
|
+
flexDirection: "column",
|
|
5803
|
+
borderStyle: "single",
|
|
5804
|
+
borderColor: "green",
|
|
5805
|
+
paddingX: 2,
|
|
5806
|
+
paddingY: 1
|
|
5807
|
+
},
|
|
5808
|
+
/* @__PURE__ */ React27.createElement(Text18, { bold: true, color: "green", marginBottom: 1 }, "\u2713 Generated Passwords:"),
|
|
5809
|
+
passwords.map((password, index) => /* @__PURE__ */ React27.createElement(Box17, { key: index, marginBottom: 0 }, /* @__PURE__ */ React27.createElement(Box17, { width: 4 }, /* @__PURE__ */ React27.createElement(Text18, { dimColor: true }, index + 1, ".")), /* @__PURE__ */ React27.createElement(Box17, { flexGrow: 1 }, /* @__PURE__ */ React27.createElement(Text18, null, password)), copiedIndex === index && /* @__PURE__ */ React27.createElement(Text18, { color: "green" }, " \u2713 Copied!")))
|
|
5810
|
+
), /* @__PURE__ */ React27.createElement(Box17, { marginTop: 1, borderStyle: "single", borderColor: "gray", paddingX: 2 }, /* @__PURE__ */ React27.createElement(Text18, { dimColor: true }, "Tab: Next field | Enter: Generate | C: Copy | Esc: Back")));
|
|
5811
|
+
};
|
|
5812
|
+
|
|
5813
|
+
// src/ui/utils/views/UuidView.tsx
|
|
5814
|
+
import React28, { useState as useState15 } from "react";
|
|
5815
|
+
import { Box as Box18, Text as Text19, useInput as useInput13 } from "ink";
|
|
5816
|
+
import TextInput5 from "ink-text-input";
|
|
5817
|
+
var UuidView = () => {
|
|
5818
|
+
const [count, setCount] = useState15("1");
|
|
5819
|
+
const [uppercase, setUppercase] = useState15(false);
|
|
5820
|
+
const [noHyphens, setNoHyphens] = useState15(false);
|
|
5821
|
+
const [uuids, setUuids] = useState15([]);
|
|
5822
|
+
const [focusedField, setFocusedField] = useState15("count");
|
|
5823
|
+
const [copiedIndex, setCopiedIndex] = useState15(null);
|
|
5824
|
+
const service = new UtilsService();
|
|
5825
|
+
useInput13((input, key) => {
|
|
5826
|
+
if (key.tab) {
|
|
5827
|
+
const fields = ["count", "uppercase", "hyphens", "generate"];
|
|
5828
|
+
const currentIndex = fields.indexOf(focusedField);
|
|
5829
|
+
setFocusedField(fields[(currentIndex + 1) % fields.length]);
|
|
5830
|
+
} else if (key.return) {
|
|
5831
|
+
if (focusedField === "uppercase") {
|
|
5832
|
+
setUppercase(!uppercase);
|
|
5833
|
+
} else if (focusedField === "hyphens") {
|
|
5834
|
+
setNoHyphens(!noHyphens);
|
|
5835
|
+
} else if (focusedField === "generate") {
|
|
5836
|
+
handleGenerate();
|
|
5837
|
+
}
|
|
5838
|
+
} else if (input === "c" && uuids.length > 0) {
|
|
5839
|
+
handleCopy(0);
|
|
5840
|
+
}
|
|
5841
|
+
});
|
|
5842
|
+
const handleGenerate = () => {
|
|
5843
|
+
const newUuids = [];
|
|
5844
|
+
const countNum = parseInt(count, 10) || 1;
|
|
5845
|
+
for (let i = 0; i < countNum; i++) {
|
|
5846
|
+
newUuids.push(service.generateUuid({ uppercase, noHyphens }));
|
|
5847
|
+
}
|
|
5848
|
+
setUuids(newUuids);
|
|
5849
|
+
setCopiedIndex(null);
|
|
5850
|
+
};
|
|
5851
|
+
const handleCopy = async (index) => {
|
|
5852
|
+
try {
|
|
5853
|
+
const { default: clipboardy } = await import("clipboardy");
|
|
5854
|
+
await clipboardy.write(uuids[index]);
|
|
5855
|
+
setCopiedIndex(index);
|
|
5856
|
+
setTimeout(() => setCopiedIndex(null), 2e3);
|
|
5857
|
+
} catch (error) {
|
|
5858
|
+
}
|
|
5859
|
+
};
|
|
5860
|
+
return /* @__PURE__ */ React28.createElement(Box18, { flexDirection: "column" }, /* @__PURE__ */ React28.createElement(Box18, { marginBottom: 1 }, /* @__PURE__ */ React28.createElement(Text19, { bold: true, color: "cyan" }, "\u{1F194} UUID Generator")), /* @__PURE__ */ React28.createElement(
|
|
5861
|
+
Box18,
|
|
5862
|
+
{
|
|
5863
|
+
flexDirection: "column",
|
|
5864
|
+
borderStyle: "single",
|
|
5865
|
+
borderColor: "gray",
|
|
5866
|
+
paddingX: 2,
|
|
5867
|
+
paddingY: 1,
|
|
5868
|
+
marginBottom: 1
|
|
5869
|
+
},
|
|
5870
|
+
/* @__PURE__ */ React28.createElement(Text19, { bold: true, color: "yellow", marginBottom: 1 }, "Options:"),
|
|
5871
|
+
/* @__PURE__ */ React28.createElement(Box18, { marginBottom: 1 }, /* @__PURE__ */ React28.createElement(Box18, { width: 20 }, /* @__PURE__ */ React28.createElement(Text19, { color: focusedField === "count" ? "green" : void 0 }, focusedField === "count" ? "\u25B6 " : " ", "Count:")), /* @__PURE__ */ React28.createElement(Box18, { width: 10 }, focusedField === "count" ? /* @__PURE__ */ React28.createElement(TextInput5, { value: count, onChange: setCount }) : /* @__PURE__ */ React28.createElement(Text19, null, count))),
|
|
5872
|
+
/* @__PURE__ */ React28.createElement(Box18, { marginBottom: 1 }, /* @__PURE__ */ React28.createElement(Text19, { color: focusedField === "uppercase" ? "green" : void 0 }, focusedField === "uppercase" ? "\u25B6 " : " ", "[", uppercase ? "\u2713" : " ", "] Uppercase")),
|
|
5873
|
+
/* @__PURE__ */ React28.createElement(Box18, { marginBottom: 1 }, /* @__PURE__ */ React28.createElement(Text19, { color: focusedField === "hyphens" ? "green" : void 0 }, focusedField === "hyphens" ? "\u25B6 " : " ", "[", noHyphens ? "\u2713" : " ", "] No Hyphens")),
|
|
5874
|
+
/* @__PURE__ */ React28.createElement(Box18, { marginTop: 1 }, /* @__PURE__ */ React28.createElement(
|
|
5875
|
+
Text19,
|
|
5876
|
+
{
|
|
5877
|
+
bold: true,
|
|
5878
|
+
backgroundColor: focusedField === "generate" ? "green" : void 0,
|
|
5879
|
+
color: focusedField === "generate" ? "black" : "green"
|
|
5880
|
+
},
|
|
5881
|
+
focusedField === "generate" ? "\u25B6 " : " ",
|
|
5882
|
+
"[ Generate UUIDs ]"
|
|
5883
|
+
))
|
|
5884
|
+
), uuids.length > 0 && /* @__PURE__ */ React28.createElement(
|
|
5885
|
+
Box18,
|
|
5886
|
+
{
|
|
5887
|
+
flexDirection: "column",
|
|
5888
|
+
borderStyle: "single",
|
|
5889
|
+
borderColor: "green",
|
|
5890
|
+
paddingX: 2,
|
|
5891
|
+
paddingY: 1
|
|
5892
|
+
},
|
|
5893
|
+
/* @__PURE__ */ React28.createElement(Text19, { bold: true, color: "green", marginBottom: 1 }, "\u2713 Generated UUIDs:"),
|
|
5894
|
+
uuids.map((uuid, index) => /* @__PURE__ */ React28.createElement(Box18, { key: index, marginBottom: 0 }, /* @__PURE__ */ React28.createElement(Box18, { width: 4 }, /* @__PURE__ */ React28.createElement(Text19, { dimColor: true }, index + 1, ".")), /* @__PURE__ */ React28.createElement(Box18, { flexGrow: 1 }, /* @__PURE__ */ React28.createElement(Text19, null, uuid)), copiedIndex === index && /* @__PURE__ */ React28.createElement(Text19, { color: "green" }, " \u2713 Copied!")))
|
|
5895
|
+
), /* @__PURE__ */ React28.createElement(Box18, { marginTop: 1, borderStyle: "single", borderColor: "gray", paddingX: 2 }, /* @__PURE__ */ React28.createElement(Text19, { dimColor: true }, "Tab: Next | Enter: Toggle/Generate | C: Copy | Esc: Back")));
|
|
5896
|
+
};
|
|
5897
|
+
|
|
5898
|
+
// src/ui/utils/views/HashView.tsx
|
|
5899
|
+
import React29, { useState as useState16 } from "react";
|
|
5900
|
+
import { Box as Box19, Text as Text20, useInput as useInput14 } from "ink";
|
|
5901
|
+
import TextInput6 from "ink-text-input";
|
|
5902
|
+
var ALGORITHMS = ["sha256", "sha512", "sha1", "md5", "bcrypt"];
|
|
5903
|
+
var HashView = () => {
|
|
5904
|
+
const [text, setText] = useState16("");
|
|
5905
|
+
const [algorithm, setAlgorithm] = useState16("sha256");
|
|
5906
|
+
const [hash, setHash] = useState16("");
|
|
5907
|
+
const [focusedField, setFocusedField] = useState16("text");
|
|
5908
|
+
const [copied, setCopied] = useState16(false);
|
|
5909
|
+
const service = new UtilsService();
|
|
5910
|
+
useInput14((input, key) => {
|
|
5911
|
+
if (key.tab) {
|
|
5912
|
+
const fields = ["text", "algorithm", "generate"];
|
|
5913
|
+
const currentIndex = fields.indexOf(focusedField);
|
|
5914
|
+
setFocusedField(fields[(currentIndex + 1) % fields.length]);
|
|
5915
|
+
} else if (key.return && focusedField === "generate") {
|
|
5916
|
+
handleGenerate();
|
|
5917
|
+
} else if (key.leftArrow && focusedField === "algorithm") {
|
|
5918
|
+
const currentIndex = ALGORITHMS.indexOf(algorithm);
|
|
5919
|
+
setAlgorithm(ALGORITHMS[currentIndex > 0 ? currentIndex - 1 : ALGORITHMS.length - 1]);
|
|
5920
|
+
} else if (key.rightArrow && focusedField === "algorithm") {
|
|
5921
|
+
const currentIndex = ALGORITHMS.indexOf(algorithm);
|
|
5922
|
+
setAlgorithm(ALGORITHMS[(currentIndex + 1) % ALGORITHMS.length]);
|
|
5923
|
+
} else if (input === "c" && hash) {
|
|
5924
|
+
handleCopy();
|
|
5925
|
+
}
|
|
5926
|
+
});
|
|
5927
|
+
const handleGenerate = async () => {
|
|
5928
|
+
if (!text) return;
|
|
5929
|
+
let result;
|
|
5930
|
+
if (algorithm === "bcrypt") {
|
|
5931
|
+
result = await service.hashBcrypt(text, 10);
|
|
5932
|
+
} else {
|
|
5933
|
+
result = await service.hash(text, algorithm);
|
|
5934
|
+
}
|
|
5935
|
+
setHash(result);
|
|
5936
|
+
setCopied(false);
|
|
5937
|
+
};
|
|
5938
|
+
const handleCopy = async () => {
|
|
5939
|
+
try {
|
|
5940
|
+
const { default: clipboardy } = await import("clipboardy");
|
|
5941
|
+
await clipboardy.write(hash);
|
|
5942
|
+
setCopied(true);
|
|
5943
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
5944
|
+
} catch (error) {
|
|
5945
|
+
}
|
|
5946
|
+
};
|
|
5947
|
+
return /* @__PURE__ */ React29.createElement(Box19, { flexDirection: "column" }, /* @__PURE__ */ React29.createElement(Box19, { marginBottom: 1 }, /* @__PURE__ */ React29.createElement(Text20, { bold: true, color: "cyan" }, "\u{1F512} Hash Generator")), /* @__PURE__ */ React29.createElement(
|
|
5948
|
+
Box19,
|
|
5949
|
+
{
|
|
5950
|
+
flexDirection: "column",
|
|
5951
|
+
borderStyle: "single",
|
|
5952
|
+
borderColor: "gray",
|
|
5953
|
+
paddingX: 2,
|
|
5954
|
+
paddingY: 1,
|
|
5955
|
+
marginBottom: 1
|
|
5956
|
+
},
|
|
5957
|
+
/* @__PURE__ */ React29.createElement(Text20, { bold: true, color: "yellow", marginBottom: 1 }, "Options:"),
|
|
5958
|
+
/* @__PURE__ */ React29.createElement(Box19, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React29.createElement(Box19, { marginBottom: 0 }, /* @__PURE__ */ React29.createElement(Text20, { color: focusedField === "text" ? "green" : void 0 }, focusedField === "text" ? "\u25B6 " : " ", "Text to hash:")), /* @__PURE__ */ React29.createElement(Box19, { marginLeft: 2, width: 60 }, focusedField === "text" ? /* @__PURE__ */ React29.createElement(TextInput6, { value: text, onChange: setText, placeholder: "Enter text..." }) : /* @__PURE__ */ React29.createElement(Text20, { dimColor: !text }, text || "(empty)"))),
|
|
5959
|
+
/* @__PURE__ */ React29.createElement(Box19, { marginBottom: 1 }, /* @__PURE__ */ React29.createElement(Box19, { width: 20 }, /* @__PURE__ */ React29.createElement(Text20, { color: focusedField === "algorithm" ? "green" : void 0 }, focusedField === "algorithm" ? "\u25B6 " : " ", "Algorithm:")), /* @__PURE__ */ React29.createElement(Text20, { bold: true, color: focusedField === "algorithm" ? "yellow" : void 0 }, algorithm.toUpperCase()), focusedField === "algorithm" && /* @__PURE__ */ React29.createElement(Text20, { dimColor: true }, " (\u2190 \u2192 to change)")),
|
|
5960
|
+
/* @__PURE__ */ React29.createElement(Box19, { marginTop: 1 }, /* @__PURE__ */ React29.createElement(
|
|
5961
|
+
Text20,
|
|
5962
|
+
{
|
|
5963
|
+
bold: true,
|
|
5964
|
+
backgroundColor: focusedField === "generate" ? "green" : void 0,
|
|
5965
|
+
color: focusedField === "generate" ? "black" : "green"
|
|
5966
|
+
},
|
|
5967
|
+
focusedField === "generate" ? "\u25B6 " : " ",
|
|
5968
|
+
"[ Generate Hash ]"
|
|
5969
|
+
))
|
|
5970
|
+
), hash && /* @__PURE__ */ React29.createElement(
|
|
5971
|
+
Box19,
|
|
5972
|
+
{
|
|
5973
|
+
flexDirection: "column",
|
|
5974
|
+
borderStyle: "single",
|
|
5975
|
+
borderColor: "green",
|
|
5976
|
+
paddingX: 2,
|
|
5977
|
+
paddingY: 1
|
|
5978
|
+
},
|
|
5979
|
+
/* @__PURE__ */ React29.createElement(Box19, { marginBottom: 1 }, /* @__PURE__ */ React29.createElement(Text20, { bold: true, color: "green" }, "\u2713 Hash Result:"), copied && /* @__PURE__ */ React29.createElement(Box19, { marginLeft: 2 }, /* @__PURE__ */ React29.createElement(Text20, { color: "green" }, "\u2713 Copied to clipboard!"))),
|
|
5980
|
+
/* @__PURE__ */ React29.createElement(Box19, { flexDirection: "column" }, /* @__PURE__ */ React29.createElement(Text20, { dimColor: true }, "Algorithm: ", algorithm.toUpperCase()), /* @__PURE__ */ React29.createElement(Box19, { marginTop: 1 }, /* @__PURE__ */ React29.createElement(Text20, { wrap: "wrap" }, hash)))
|
|
5981
|
+
), /* @__PURE__ */ React29.createElement(Box19, { marginTop: 1, borderStyle: "single", borderColor: "gray", paddingX: 2 }, /* @__PURE__ */ React29.createElement(Text20, { dimColor: true }, "Tab: Next | \u2190/\u2192: Change algorithm | Enter: Generate | C: Copy | Esc: Back")));
|
|
5982
|
+
};
|
|
5983
|
+
|
|
5984
|
+
// src/ui/utils/views/Base64View.tsx
|
|
5985
|
+
import React30, { useState as useState17 } from "react";
|
|
5986
|
+
import { Box as Box20, Text as Text21, useInput as useInput15 } from "ink";
|
|
5987
|
+
import TextInput7 from "ink-text-input";
|
|
5988
|
+
var Base64View = () => {
|
|
5989
|
+
const [input, setInput] = useState17("");
|
|
5990
|
+
const [mode, setMode] = useState17("encode");
|
|
5991
|
+
const [urlSafe, setUrlSafe] = useState17(false);
|
|
5992
|
+
const [result, setResult] = useState17("");
|
|
5993
|
+
const [error, setError] = useState17("");
|
|
5994
|
+
const [focusedField, setFocusedField] = useState17("input");
|
|
5995
|
+
const [copied, setCopied] = useState17(false);
|
|
5996
|
+
const service = new UtilsService();
|
|
5997
|
+
useInput15((input2, key) => {
|
|
5998
|
+
if (key.tab) {
|
|
5999
|
+
const fields = ["input", "mode", "urlsafe", "convert"];
|
|
6000
|
+
const currentIndex = fields.indexOf(focusedField);
|
|
6001
|
+
setFocusedField(fields[(currentIndex + 1) % fields.length]);
|
|
6002
|
+
} else if (key.return) {
|
|
6003
|
+
if (focusedField === "mode") {
|
|
6004
|
+
setMode(mode === "encode" ? "decode" : "encode");
|
|
6005
|
+
setResult("");
|
|
6006
|
+
setError("");
|
|
6007
|
+
} else if (focusedField === "urlsafe") {
|
|
6008
|
+
setUrlSafe(!urlSafe);
|
|
6009
|
+
} else if (focusedField === "convert") {
|
|
6010
|
+
handleConvert();
|
|
6011
|
+
}
|
|
6012
|
+
} else if (input2 === "c" && result) {
|
|
6013
|
+
handleCopy();
|
|
6014
|
+
}
|
|
6015
|
+
});
|
|
6016
|
+
const handleConvert = () => {
|
|
6017
|
+
if (!input) {
|
|
6018
|
+
setError("Input cannot be empty");
|
|
6019
|
+
return;
|
|
6020
|
+
}
|
|
6021
|
+
try {
|
|
6022
|
+
setError("");
|
|
6023
|
+
if (mode === "encode") {
|
|
6024
|
+
const encoded = service.base64Encode(input, urlSafe);
|
|
6025
|
+
setResult(encoded);
|
|
6026
|
+
} else {
|
|
6027
|
+
const decoded = service.base64Decode(input);
|
|
6028
|
+
setResult(decoded.toString("utf-8"));
|
|
6029
|
+
}
|
|
6030
|
+
setCopied(false);
|
|
6031
|
+
} catch (err) {
|
|
6032
|
+
setError(`Failed to ${mode}: ${err instanceof Error ? err.message : "Unknown error"}`);
|
|
6033
|
+
setResult("");
|
|
6034
|
+
}
|
|
6035
|
+
};
|
|
6036
|
+
const handleCopy = async () => {
|
|
6037
|
+
try {
|
|
6038
|
+
const { default: clipboardy } = await import("clipboardy");
|
|
6039
|
+
await clipboardy.write(result);
|
|
6040
|
+
setCopied(true);
|
|
6041
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
6042
|
+
} catch (error2) {
|
|
6043
|
+
}
|
|
6044
|
+
};
|
|
6045
|
+
return /* @__PURE__ */ React30.createElement(Box20, { flexDirection: "column" }, /* @__PURE__ */ React30.createElement(Box20, { marginBottom: 1 }, /* @__PURE__ */ React30.createElement(Text21, { bold: true, color: "cyan" }, "\u{1F4DD} Base64 Encoder/Decoder")), /* @__PURE__ */ React30.createElement(
|
|
6046
|
+
Box20,
|
|
6047
|
+
{
|
|
6048
|
+
flexDirection: "column",
|
|
6049
|
+
borderStyle: "single",
|
|
6050
|
+
borderColor: "gray",
|
|
6051
|
+
paddingX: 2,
|
|
6052
|
+
paddingY: 1,
|
|
6053
|
+
marginBottom: 1
|
|
6054
|
+
},
|
|
6055
|
+
/* @__PURE__ */ React30.createElement(Text21, { bold: true, color: "yellow", marginBottom: 1 }, "Options:"),
|
|
6056
|
+
/* @__PURE__ */ React30.createElement(Box20, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React30.createElement(Box20, { marginBottom: 0 }, /* @__PURE__ */ React30.createElement(Text21, { color: focusedField === "input" ? "green" : void 0 }, focusedField === "input" ? "\u25B6 " : " ", "Input text:")), /* @__PURE__ */ React30.createElement(Box20, { marginLeft: 2, width: 60 }, focusedField === "input" ? /* @__PURE__ */ React30.createElement(TextInput7, { value: input, onChange: setInput, placeholder: "Enter text..." }) : /* @__PURE__ */ React30.createElement(Text21, { dimColor: !input }, input || "(empty)"))),
|
|
6057
|
+
/* @__PURE__ */ React30.createElement(Box20, { marginBottom: 1 }, /* @__PURE__ */ React30.createElement(Box20, { width: 20 }, /* @__PURE__ */ React30.createElement(Text21, { color: focusedField === "mode" ? "green" : void 0 }, focusedField === "mode" ? "\u25B6 " : " ", "Mode:")), /* @__PURE__ */ React30.createElement(Text21, { bold: true, color: focusedField === "mode" ? "yellow" : void 0 }, mode === "encode" ? "ENCODE" : "DECODE"), focusedField === "mode" && /* @__PURE__ */ React30.createElement(Text21, { dimColor: true }, " (Enter to toggle)")),
|
|
6058
|
+
mode === "encode" && /* @__PURE__ */ React30.createElement(Box20, { marginBottom: 1 }, /* @__PURE__ */ React30.createElement(Text21, { color: focusedField === "urlsafe" ? "green" : void 0 }, focusedField === "urlsafe" ? "\u25B6 " : " ", "[", urlSafe ? "\u2713" : " ", "] URL-Safe (+ \u2192 -, / \u2192 _)")),
|
|
6059
|
+
/* @__PURE__ */ React30.createElement(Box20, { marginTop: 1 }, /* @__PURE__ */ React30.createElement(
|
|
6060
|
+
Text21,
|
|
6061
|
+
{
|
|
6062
|
+
bold: true,
|
|
6063
|
+
backgroundColor: focusedField === "convert" ? "green" : void 0,
|
|
6064
|
+
color: focusedField === "convert" ? "black" : "green"
|
|
6065
|
+
},
|
|
6066
|
+
focusedField === "convert" ? "\u25B6 " : " ",
|
|
6067
|
+
"[ ",
|
|
6068
|
+
mode === "encode" ? "Encode" : "Decode",
|
|
6069
|
+
" ]"
|
|
6070
|
+
))
|
|
6071
|
+
), error && /* @__PURE__ */ React30.createElement(
|
|
6072
|
+
Box20,
|
|
6073
|
+
{
|
|
6074
|
+
flexDirection: "column",
|
|
6075
|
+
borderStyle: "single",
|
|
6076
|
+
borderColor: "red",
|
|
6077
|
+
paddingX: 2,
|
|
6078
|
+
paddingY: 1,
|
|
6079
|
+
marginBottom: 1
|
|
6080
|
+
},
|
|
6081
|
+
/* @__PURE__ */ React30.createElement(Text21, { color: "red" }, "\u2717 Error: ", error)
|
|
6082
|
+
), result && /* @__PURE__ */ React30.createElement(
|
|
6083
|
+
Box20,
|
|
6084
|
+
{
|
|
6085
|
+
flexDirection: "column",
|
|
6086
|
+
borderStyle: "single",
|
|
6087
|
+
borderColor: "green",
|
|
6088
|
+
paddingX: 2,
|
|
6089
|
+
paddingY: 1
|
|
6090
|
+
},
|
|
6091
|
+
/* @__PURE__ */ React30.createElement(Box20, { marginBottom: 1 }, /* @__PURE__ */ React30.createElement(Text21, { bold: true, color: "green" }, "\u2713 Result:"), copied && /* @__PURE__ */ React30.createElement(Box20, { marginLeft: 2 }, /* @__PURE__ */ React30.createElement(Text21, { color: "green" }, "\u2713 Copied to clipboard!"))),
|
|
6092
|
+
/* @__PURE__ */ React30.createElement(Box20, { flexDirection: "column" }, /* @__PURE__ */ React30.createElement(Text21, { dimColor: true }, "Mode: ", mode.toUpperCase()), /* @__PURE__ */ React30.createElement(Box20, { marginTop: 1 }, /* @__PURE__ */ React30.createElement(Text21, { wrap: "wrap" }, result)))
|
|
6093
|
+
), /* @__PURE__ */ React30.createElement(Box20, { marginTop: 1, borderStyle: "single", borderColor: "gray", paddingX: 2 }, /* @__PURE__ */ React30.createElement(Text21, { dimColor: true }, "Tab: Next | Enter: Toggle/Convert | C: Copy | Esc: Back")));
|
|
6094
|
+
};
|
|
6095
|
+
|
|
6096
|
+
// src/ui/utils/views/UrlView.tsx
|
|
6097
|
+
import React31, { useState as useState18 } from "react";
|
|
6098
|
+
import { Box as Box21, Text as Text22, useInput as useInput16 } from "ink";
|
|
6099
|
+
import TextInput8 from "ink-text-input";
|
|
6100
|
+
var UrlView = () => {
|
|
6101
|
+
const [input, setInput] = useState18("");
|
|
6102
|
+
const [mode, setMode] = useState18("encode");
|
|
6103
|
+
const [fullUrl, setFullUrl] = useState18(false);
|
|
6104
|
+
const [result, setResult] = useState18("");
|
|
6105
|
+
const [focusedField, setFocusedField] = useState18("input");
|
|
6106
|
+
const [copied, setCopied] = useState18(false);
|
|
6107
|
+
const service = new UtilsService();
|
|
6108
|
+
useInput16((input2, key) => {
|
|
6109
|
+
if (key.tab) {
|
|
6110
|
+
const fields = ["input", "mode", "full", "convert"];
|
|
6111
|
+
const currentIndex = fields.indexOf(focusedField);
|
|
6112
|
+
setFocusedField(fields[(currentIndex + 1) % fields.length]);
|
|
6113
|
+
} else if (key.return) {
|
|
6114
|
+
if (focusedField === "mode") {
|
|
6115
|
+
setMode(mode === "encode" ? "decode" : "encode");
|
|
6116
|
+
setResult("");
|
|
6117
|
+
} else if (focusedField === "full") {
|
|
6118
|
+
setFullUrl(!fullUrl);
|
|
6119
|
+
} else if (focusedField === "convert") {
|
|
6120
|
+
handleConvert();
|
|
6121
|
+
}
|
|
6122
|
+
} else if (input2 === "c" && result) {
|
|
6123
|
+
handleCopy();
|
|
6124
|
+
}
|
|
6125
|
+
});
|
|
6126
|
+
const handleConvert = () => {
|
|
6127
|
+
if (!input) return;
|
|
6128
|
+
if (mode === "encode") {
|
|
6129
|
+
const encoded = fullUrl ? service.urlEncode(input, true) : service.urlEncode(input, false);
|
|
6130
|
+
setResult(encoded);
|
|
6131
|
+
} else {
|
|
6132
|
+
const decoded = fullUrl ? service.urlDecode(input, true) : service.urlDecode(input, false);
|
|
6133
|
+
setResult(decoded);
|
|
6134
|
+
}
|
|
6135
|
+
setCopied(false);
|
|
6136
|
+
};
|
|
6137
|
+
const handleCopy = async () => {
|
|
6138
|
+
try {
|
|
6139
|
+
const { default: clipboardy } = await import("clipboardy");
|
|
6140
|
+
await clipboardy.write(result);
|
|
6141
|
+
setCopied(true);
|
|
6142
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
6143
|
+
} catch (error) {
|
|
6144
|
+
}
|
|
6145
|
+
};
|
|
6146
|
+
return /* @__PURE__ */ React31.createElement(Box21, { flexDirection: "column" }, /* @__PURE__ */ React31.createElement(Box21, { marginBottom: 1 }, /* @__PURE__ */ React31.createElement(Text22, { bold: true, color: "cyan" }, "\u{1F517} URL Encoder/Decoder")), /* @__PURE__ */ React31.createElement(
|
|
6147
|
+
Box21,
|
|
6148
|
+
{
|
|
6149
|
+
flexDirection: "column",
|
|
6150
|
+
borderStyle: "single",
|
|
6151
|
+
borderColor: "gray",
|
|
6152
|
+
paddingX: 2,
|
|
6153
|
+
paddingY: 1,
|
|
6154
|
+
marginBottom: 1
|
|
6155
|
+
},
|
|
6156
|
+
/* @__PURE__ */ React31.createElement(Text22, { bold: true, color: "yellow", marginBottom: 1 }, "Options:"),
|
|
6157
|
+
/* @__PURE__ */ React31.createElement(Box21, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React31.createElement(Box21, { marginBottom: 0 }, /* @__PURE__ */ React31.createElement(Text22, { color: focusedField === "input" ? "green" : void 0 }, focusedField === "input" ? "\u25B6 " : " ", "Input text:")), /* @__PURE__ */ React31.createElement(Box21, { marginLeft: 2, width: 60 }, focusedField === "input" ? /* @__PURE__ */ React31.createElement(TextInput8, { value: input, onChange: setInput, placeholder: "Enter text or URL..." }) : /* @__PURE__ */ React31.createElement(Text22, { dimColor: !input }, input || "(empty)"))),
|
|
6158
|
+
/* @__PURE__ */ React31.createElement(Box21, { marginBottom: 1 }, /* @__PURE__ */ React31.createElement(Box21, { width: 20 }, /* @__PURE__ */ React31.createElement(Text22, { color: focusedField === "mode" ? "green" : void 0 }, focusedField === "mode" ? "\u25B6 " : " ", "Mode:")), /* @__PURE__ */ React31.createElement(Text22, { bold: true, color: focusedField === "mode" ? "yellow" : void 0 }, mode === "encode" ? "ENCODE" : "DECODE"), focusedField === "mode" && /* @__PURE__ */ React31.createElement(Text22, { dimColor: true }, " (Enter to toggle)")),
|
|
6159
|
+
/* @__PURE__ */ React31.createElement(Box21, { marginBottom: 1 }, /* @__PURE__ */ React31.createElement(Text22, { color: focusedField === "full" ? "green" : void 0 }, focusedField === "full" ? "\u25B6 " : " ", "[", fullUrl ? "\u2713" : " ", "] Full URL (encode/decode entire URL)")),
|
|
6160
|
+
/* @__PURE__ */ React31.createElement(Box21, { marginTop: 1 }, /* @__PURE__ */ React31.createElement(
|
|
6161
|
+
Text22,
|
|
6162
|
+
{
|
|
6163
|
+
bold: true,
|
|
6164
|
+
backgroundColor: focusedField === "convert" ? "green" : void 0,
|
|
6165
|
+
color: focusedField === "convert" ? "black" : "green"
|
|
6166
|
+
},
|
|
6167
|
+
focusedField === "convert" ? "\u25B6 " : " ",
|
|
6168
|
+
"[ ",
|
|
6169
|
+
mode === "encode" ? "Encode" : "Decode",
|
|
6170
|
+
" ]"
|
|
6171
|
+
))
|
|
6172
|
+
), result && /* @__PURE__ */ React31.createElement(
|
|
6173
|
+
Box21,
|
|
6174
|
+
{
|
|
6175
|
+
flexDirection: "column",
|
|
6176
|
+
borderStyle: "single",
|
|
6177
|
+
borderColor: "green",
|
|
6178
|
+
paddingX: 2,
|
|
6179
|
+
paddingY: 1
|
|
6180
|
+
},
|
|
6181
|
+
/* @__PURE__ */ React31.createElement(Box21, { marginBottom: 1 }, /* @__PURE__ */ React31.createElement(Text22, { bold: true, color: "green" }, "\u2713 Result:"), copied && /* @__PURE__ */ React31.createElement(Box21, { marginLeft: 2 }, /* @__PURE__ */ React31.createElement(Text22, { color: "green" }, "\u2713 Copied to clipboard!"))),
|
|
6182
|
+
/* @__PURE__ */ React31.createElement(Box21, { flexDirection: "column" }, /* @__PURE__ */ React31.createElement(Text22, { dimColor: true }, "Mode: ", mode.toUpperCase(), " ", fullUrl ? "(Full URL)" : "(Component)"), /* @__PURE__ */ React31.createElement(Box21, { marginTop: 1 }, /* @__PURE__ */ React31.createElement(Text22, { wrap: "wrap" }, result)))
|
|
6183
|
+
), /* @__PURE__ */ React31.createElement(Box21, { marginTop: 1, borderStyle: "single", borderColor: "gray", paddingX: 2 }, /* @__PURE__ */ React31.createElement(Text22, { dimColor: true }, "Tab: Next | Enter: Toggle/Convert | C: Copy | Esc: Back")));
|
|
6184
|
+
};
|
|
6185
|
+
|
|
6186
|
+
// src/ui/utils/views/UnixTimeView.tsx
|
|
6187
|
+
import React32, { useState as useState19 } from "react";
|
|
6188
|
+
import { Box as Box22, Text as Text23, useInput as useInput17 } from "ink";
|
|
6189
|
+
import TextInput9 from "ink-text-input";
|
|
6190
|
+
var UnixTimeView = () => {
|
|
6191
|
+
const [input, setInput] = useState19("");
|
|
6192
|
+
const [mode, setMode] = useState19("now");
|
|
6193
|
+
const [format, setFormat] = useState19("iso");
|
|
6194
|
+
const [useMs, setUseMs] = useState19(false);
|
|
6195
|
+
const [result, setResult] = useState19("");
|
|
6196
|
+
const [error, setError] = useState19("");
|
|
6197
|
+
const [focusedField, setFocusedField] = useState19("mode");
|
|
6198
|
+
const [copied, setCopied] = useState19(false);
|
|
6199
|
+
const service = new UtilsService();
|
|
6200
|
+
useInput17((input2, key) => {
|
|
6201
|
+
if (key.tab) {
|
|
6202
|
+
const fields = mode === "now" ? ["mode", "ms", "convert"] : mode === "to-human" ? ["mode", "input", "format", "convert"] : ["mode", "input", "convert"];
|
|
6203
|
+
const currentIndex = fields.indexOf(focusedField);
|
|
6204
|
+
setFocusedField(fields[(currentIndex + 1) % fields.length]);
|
|
6205
|
+
} else if (key.return) {
|
|
6206
|
+
if (focusedField === "mode") {
|
|
6207
|
+
const modes = ["now", "to-human", "to-unix"];
|
|
6208
|
+
const currentIndex = modes.indexOf(mode);
|
|
6209
|
+
setMode(modes[(currentIndex + 1) % modes.length]);
|
|
6210
|
+
setResult("");
|
|
6211
|
+
setError("");
|
|
6212
|
+
} else if (focusedField === "format") {
|
|
6213
|
+
const formats = ["iso", "local", "utc"];
|
|
6214
|
+
const currentIndex = formats.indexOf(format);
|
|
6215
|
+
setFormat(formats[(currentIndex + 1) % formats.length]);
|
|
6216
|
+
} else if (focusedField === "ms") {
|
|
6217
|
+
setUseMs(!useMs);
|
|
6218
|
+
} else if (focusedField === "convert") {
|
|
6219
|
+
handleConvert();
|
|
6220
|
+
}
|
|
6221
|
+
} else if (input2 === "c" && result) {
|
|
6222
|
+
handleCopy();
|
|
6223
|
+
}
|
|
6224
|
+
});
|
|
6225
|
+
const handleConvert = () => {
|
|
6226
|
+
try {
|
|
6227
|
+
setError("");
|
|
6228
|
+
if (mode === "now") {
|
|
6229
|
+
const timestamp = service.unixTimeCurrent(useMs);
|
|
6230
|
+
setResult(timestamp.toString());
|
|
6231
|
+
} else if (mode === "to-human") {
|
|
6232
|
+
if (!input) {
|
|
6233
|
+
setError("Please enter a timestamp");
|
|
6234
|
+
return;
|
|
6235
|
+
}
|
|
6236
|
+
const human = service.unixTimeToHuman(parseInt(input, 10), format);
|
|
6237
|
+
setResult(human);
|
|
6238
|
+
} else {
|
|
6239
|
+
if (!input) {
|
|
6240
|
+
setError("Please enter a date string");
|
|
6241
|
+
return;
|
|
6242
|
+
}
|
|
6243
|
+
const timestamp = service.unixTimeFromString(input);
|
|
6244
|
+
setResult(timestamp.toString());
|
|
6245
|
+
}
|
|
6246
|
+
setCopied(false);
|
|
6247
|
+
} catch (err) {
|
|
6248
|
+
setError(err instanceof Error ? err.message : "Conversion failed");
|
|
6249
|
+
setResult("");
|
|
6250
|
+
}
|
|
6251
|
+
};
|
|
6252
|
+
const handleCopy = async () => {
|
|
6253
|
+
try {
|
|
6254
|
+
const { default: clipboardy } = await import("clipboardy");
|
|
6255
|
+
await clipboardy.write(result);
|
|
6256
|
+
setCopied(true);
|
|
6257
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
6258
|
+
} catch (error2) {
|
|
6259
|
+
}
|
|
6260
|
+
};
|
|
6261
|
+
return /* @__PURE__ */ React32.createElement(Box22, { flexDirection: "column" }, /* @__PURE__ */ React32.createElement(Box22, { marginBottom: 1 }, /* @__PURE__ */ React32.createElement(Text23, { bold: true, color: "cyan" }, "\u{1F552} Unix Time Converter")), /* @__PURE__ */ React32.createElement(
|
|
6262
|
+
Box22,
|
|
6263
|
+
{
|
|
6264
|
+
flexDirection: "column",
|
|
6265
|
+
borderStyle: "single",
|
|
6266
|
+
borderColor: "gray",
|
|
6267
|
+
paddingX: 2,
|
|
6268
|
+
paddingY: 1,
|
|
6269
|
+
marginBottom: 1
|
|
6270
|
+
},
|
|
6271
|
+
/* @__PURE__ */ React32.createElement(Text23, { bold: true, color: "yellow", marginBottom: 1 }, "Options:"),
|
|
6272
|
+
/* @__PURE__ */ React32.createElement(Box22, { marginBottom: 1 }, /* @__PURE__ */ React32.createElement(Box22, { width: 20 }, /* @__PURE__ */ React32.createElement(Text23, { color: focusedField === "mode" ? "green" : void 0 }, focusedField === "mode" ? "\u25B6 " : " ", "Mode:")), /* @__PURE__ */ React32.createElement(Text23, { bold: true, color: focusedField === "mode" ? "yellow" : void 0 }, mode === "now" ? "CURRENT TIME" : mode === "to-human" ? "TIMESTAMP \u2192 HUMAN" : "HUMAN \u2192 TIMESTAMP"), focusedField === "mode" && /* @__PURE__ */ React32.createElement(Text23, { dimColor: true }, " (Enter to cycle)")),
|
|
6273
|
+
mode !== "now" && /* @__PURE__ */ React32.createElement(Box22, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React32.createElement(Box22, { marginBottom: 0 }, /* @__PURE__ */ React32.createElement(Text23, { color: focusedField === "input" ? "green" : void 0 }, focusedField === "input" ? "\u25B6 " : " ", mode === "to-human" ? "Timestamp:" : "Date string:")), /* @__PURE__ */ React32.createElement(Box22, { marginLeft: 2, width: 50 }, focusedField === "input" ? /* @__PURE__ */ React32.createElement(
|
|
6274
|
+
TextInput9,
|
|
6275
|
+
{
|
|
6276
|
+
value: input,
|
|
6277
|
+
onChange: setInput,
|
|
6278
|
+
placeholder: mode === "to-human" ? "1702550400" : "2024-01-15 10:30:00"
|
|
6279
|
+
}
|
|
6280
|
+
) : /* @__PURE__ */ React32.createElement(Text23, { dimColor: !input }, input || "(empty)"))),
|
|
6281
|
+
mode === "to-human" && /* @__PURE__ */ React32.createElement(Box22, { marginBottom: 1 }, /* @__PURE__ */ React32.createElement(Box22, { width: 20 }, /* @__PURE__ */ React32.createElement(Text23, { color: focusedField === "format" ? "green" : void 0 }, focusedField === "format" ? "\u25B6 " : " ", "Format:")), /* @__PURE__ */ React32.createElement(Text23, { bold: true, color: focusedField === "format" ? "yellow" : void 0 }, format.toUpperCase()), focusedField === "format" && /* @__PURE__ */ React32.createElement(Text23, { dimColor: true }, " (Enter to cycle)")),
|
|
6282
|
+
mode === "now" && /* @__PURE__ */ React32.createElement(Box22, { marginBottom: 1 }, /* @__PURE__ */ React32.createElement(Text23, { color: focusedField === "ms" ? "green" : void 0 }, focusedField === "ms" ? "\u25B6 " : " ", "[", useMs ? "\u2713" : " ", "] Milliseconds")),
|
|
6283
|
+
/* @__PURE__ */ React32.createElement(Box22, { marginTop: 1 }, /* @__PURE__ */ React32.createElement(
|
|
6284
|
+
Text23,
|
|
6285
|
+
{
|
|
6286
|
+
bold: true,
|
|
6287
|
+
backgroundColor: focusedField === "convert" ? "green" : void 0,
|
|
6288
|
+
color: focusedField === "convert" ? "black" : "green"
|
|
6289
|
+
},
|
|
6290
|
+
focusedField === "convert" ? "\u25B6 " : " ",
|
|
6291
|
+
"[ ",
|
|
6292
|
+
mode === "now" ? "Get Current" : "Convert",
|
|
6293
|
+
" ]"
|
|
6294
|
+
))
|
|
6295
|
+
), error && /* @__PURE__ */ React32.createElement(
|
|
6296
|
+
Box22,
|
|
6297
|
+
{
|
|
6298
|
+
flexDirection: "column",
|
|
6299
|
+
borderStyle: "single",
|
|
6300
|
+
borderColor: "red",
|
|
6301
|
+
paddingX: 2,
|
|
6302
|
+
paddingY: 1,
|
|
6303
|
+
marginBottom: 1
|
|
6304
|
+
},
|
|
6305
|
+
/* @__PURE__ */ React32.createElement(Text23, { color: "red" }, "\u2717 Error: ", error)
|
|
6306
|
+
), result && /* @__PURE__ */ React32.createElement(
|
|
6307
|
+
Box22,
|
|
6308
|
+
{
|
|
6309
|
+
flexDirection: "column",
|
|
6310
|
+
borderStyle: "single",
|
|
6311
|
+
borderColor: "green",
|
|
6312
|
+
paddingX: 2,
|
|
6313
|
+
paddingY: 1
|
|
6314
|
+
},
|
|
6315
|
+
/* @__PURE__ */ React32.createElement(Box22, { marginBottom: 1 }, /* @__PURE__ */ React32.createElement(Text23, { bold: true, color: "green" }, "\u2713 Result:"), copied && /* @__PURE__ */ React32.createElement(Box22, { marginLeft: 2 }, /* @__PURE__ */ React32.createElement(Text23, { color: "green" }, "\u2713 Copied to clipboard!"))),
|
|
6316
|
+
/* @__PURE__ */ React32.createElement(Box22, { flexDirection: "column" }, /* @__PURE__ */ React32.createElement(Box22, { marginTop: 1 }, /* @__PURE__ */ React32.createElement(Text23, { wrap: "wrap" }, result)))
|
|
6317
|
+
), /* @__PURE__ */ React32.createElement(Box22, { marginTop: 1, borderStyle: "single", borderColor: "gray", paddingX: 2 }, /* @__PURE__ */ React32.createElement(Text23, { dimColor: true }, "Tab: Next | Enter: Toggle/Convert | C: Copy | Esc: Back")));
|
|
6318
|
+
};
|
|
6319
|
+
|
|
6320
|
+
// src/ui/utils/views/JwtView.tsx
|
|
6321
|
+
import React33, { useState as useState20 } from "react";
|
|
6322
|
+
import { Box as Box23, Text as Text24, useInput as useInput18 } from "ink";
|
|
6323
|
+
import TextInput10 from "ink-text-input";
|
|
6324
|
+
var JwtView = () => {
|
|
6325
|
+
const [mode, setMode] = useState20("decode");
|
|
6326
|
+
const [token, setToken] = useState20("");
|
|
6327
|
+
const [payload, setPayload] = useState20("");
|
|
6328
|
+
const [secret, setSecret] = useState20("");
|
|
6329
|
+
const [result, setResult] = useState20({});
|
|
6330
|
+
const [error, setError] = useState20("");
|
|
6331
|
+
const [focusedField, setFocusedField] = useState20("mode");
|
|
6332
|
+
const [copied, setCopied] = useState20(false);
|
|
6333
|
+
const service = new UtilsService();
|
|
6334
|
+
useInput18((input, key) => {
|
|
6335
|
+
if (key.tab) {
|
|
6336
|
+
const fields = mode === "decode" ? ["mode", "token", "process"] : ["mode", "payload", "secret", "process"];
|
|
6337
|
+
const currentIndex = fields.indexOf(focusedField);
|
|
6338
|
+
setFocusedField(fields[(currentIndex + 1) % fields.length]);
|
|
6339
|
+
} else if (key.return) {
|
|
6340
|
+
if (focusedField === "mode") {
|
|
6341
|
+
setMode(mode === "decode" ? "encode" : "decode");
|
|
6342
|
+
setResult({});
|
|
6343
|
+
setError("");
|
|
6344
|
+
} else if (focusedField === "process") {
|
|
6345
|
+
handleProcess();
|
|
6346
|
+
}
|
|
6347
|
+
} else if (input === "c" && result.token) {
|
|
6348
|
+
handleCopy();
|
|
6349
|
+
}
|
|
6350
|
+
});
|
|
6351
|
+
const handleProcess = () => {
|
|
6352
|
+
try {
|
|
6353
|
+
setError("");
|
|
6354
|
+
if (mode === "decode") {
|
|
6355
|
+
if (!token) {
|
|
6356
|
+
setError("Please enter a JWT token");
|
|
6357
|
+
return;
|
|
6358
|
+
}
|
|
6359
|
+
const decoded = service.jwtDecode(token);
|
|
6360
|
+
setResult(decoded);
|
|
6361
|
+
} else {
|
|
6362
|
+
if (!payload) {
|
|
6363
|
+
setError("Please enter payload JSON");
|
|
6364
|
+
return;
|
|
6365
|
+
}
|
|
6366
|
+
if (!secret) {
|
|
6367
|
+
setError("Please enter a secret key");
|
|
6368
|
+
return;
|
|
6369
|
+
}
|
|
6370
|
+
const payloadObj = JSON.parse(payload);
|
|
6371
|
+
const encoded = service.jwtEncode(payloadObj, secret);
|
|
6372
|
+
setResult({ token: encoded });
|
|
6373
|
+
}
|
|
6374
|
+
setCopied(false);
|
|
6375
|
+
} catch (err) {
|
|
6376
|
+
setError(err instanceof Error ? err.message : "Processing failed");
|
|
6377
|
+
setResult({});
|
|
6378
|
+
}
|
|
6379
|
+
};
|
|
6380
|
+
const handleCopy = async () => {
|
|
6381
|
+
try {
|
|
6382
|
+
const { default: clipboardy } = await import("clipboardy");
|
|
6383
|
+
await clipboardy.write(result.token || "");
|
|
6384
|
+
setCopied(true);
|
|
6385
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
6386
|
+
} catch (error2) {
|
|
6387
|
+
}
|
|
6388
|
+
};
|
|
6389
|
+
return /* @__PURE__ */ React33.createElement(Box23, { flexDirection: "column" }, /* @__PURE__ */ React33.createElement(Box23, { marginBottom: 1 }, /* @__PURE__ */ React33.createElement(Text24, { bold: true, color: "cyan" }, "\u{1F511} JWT Decoder/Encoder")), /* @__PURE__ */ React33.createElement(
|
|
6390
|
+
Box23,
|
|
6391
|
+
{
|
|
6392
|
+
flexDirection: "column",
|
|
6393
|
+
borderStyle: "single",
|
|
6394
|
+
borderColor: "gray",
|
|
6395
|
+
paddingX: 2,
|
|
6396
|
+
paddingY: 1,
|
|
6397
|
+
marginBottom: 1
|
|
6398
|
+
},
|
|
6399
|
+
/* @__PURE__ */ React33.createElement(Text24, { bold: true, color: "yellow", marginBottom: 1 }, "Options:"),
|
|
6400
|
+
/* @__PURE__ */ React33.createElement(Box23, { marginBottom: 1 }, /* @__PURE__ */ React33.createElement(Box23, { width: 20 }, /* @__PURE__ */ React33.createElement(Text24, { color: focusedField === "mode" ? "green" : void 0 }, focusedField === "mode" ? "\u25B6 " : " ", "Mode:")), /* @__PURE__ */ React33.createElement(Text24, { bold: true, color: focusedField === "mode" ? "yellow" : void 0 }, mode === "decode" ? "DECODE" : "ENCODE"), focusedField === "mode" && /* @__PURE__ */ React33.createElement(Text24, { dimColor: true }, " (Enter to toggle)")),
|
|
6401
|
+
mode === "decode" ? /* @__PURE__ */ React33.createElement(Box23, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React33.createElement(Box23, { marginBottom: 0 }, /* @__PURE__ */ React33.createElement(Text24, { color: focusedField === "token" ? "green" : void 0 }, focusedField === "token" ? "\u25B6 " : " ", "JWT Token:")), /* @__PURE__ */ React33.createElement(Box23, { marginLeft: 2, width: 60 }, focusedField === "token" ? /* @__PURE__ */ React33.createElement(
|
|
6402
|
+
TextInput10,
|
|
6403
|
+
{
|
|
6404
|
+
value: token,
|
|
6405
|
+
onChange: setToken,
|
|
6406
|
+
placeholder: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
|
|
6407
|
+
}
|
|
6408
|
+
) : /* @__PURE__ */ React33.createElement(Text24, { dimColor: !token }, token || "(empty)"))) : /* @__PURE__ */ React33.createElement(React33.Fragment, null, /* @__PURE__ */ React33.createElement(Box23, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React33.createElement(Box23, { marginBottom: 0 }, /* @__PURE__ */ React33.createElement(Text24, { color: focusedField === "payload" ? "green" : void 0 }, focusedField === "payload" ? "\u25B6 " : " ", "Payload (JSON):")), /* @__PURE__ */ React33.createElement(Box23, { marginLeft: 2, width: 60 }, focusedField === "payload" ? /* @__PURE__ */ React33.createElement(
|
|
6409
|
+
TextInput10,
|
|
6410
|
+
{
|
|
6411
|
+
value: payload,
|
|
6412
|
+
onChange: setPayload,
|
|
6413
|
+
placeholder: '{"sub":"123","name":"John"}'
|
|
6414
|
+
}
|
|
6415
|
+
) : /* @__PURE__ */ React33.createElement(Text24, { dimColor: !payload }, payload || "(empty)"))), /* @__PURE__ */ React33.createElement(Box23, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React33.createElement(Box23, { marginBottom: 0 }, /* @__PURE__ */ React33.createElement(Text24, { color: focusedField === "secret" ? "green" : void 0 }, focusedField === "secret" ? "\u25B6 " : " ", "Secret Key:")), /* @__PURE__ */ React33.createElement(Box23, { marginLeft: 2, width: 60 }, focusedField === "secret" ? /* @__PURE__ */ React33.createElement(
|
|
6416
|
+
TextInput10,
|
|
6417
|
+
{
|
|
6418
|
+
value: secret,
|
|
6419
|
+
onChange: setSecret,
|
|
6420
|
+
placeholder: "your-secret-key",
|
|
6421
|
+
mask: "*"
|
|
6422
|
+
}
|
|
6423
|
+
) : /* @__PURE__ */ React33.createElement(Text24, { dimColor: !secret }, secret ? "*".repeat(secret.length) : "(empty)")))),
|
|
6424
|
+
/* @__PURE__ */ React33.createElement(Box23, { marginTop: 1 }, /* @__PURE__ */ React33.createElement(
|
|
6425
|
+
Text24,
|
|
6426
|
+
{
|
|
6427
|
+
bold: true,
|
|
6428
|
+
backgroundColor: focusedField === "process" ? "green" : void 0,
|
|
6429
|
+
color: focusedField === "process" ? "black" : "green"
|
|
6430
|
+
},
|
|
6431
|
+
focusedField === "process" ? "\u25B6 " : " ",
|
|
6432
|
+
"[ ",
|
|
6433
|
+
mode === "decode" ? "Decode" : "Encode",
|
|
6434
|
+
" ]"
|
|
6435
|
+
))
|
|
6436
|
+
), error && /* @__PURE__ */ React33.createElement(
|
|
6437
|
+
Box23,
|
|
6438
|
+
{
|
|
6439
|
+
flexDirection: "column",
|
|
6440
|
+
borderStyle: "single",
|
|
6441
|
+
borderColor: "red",
|
|
6442
|
+
paddingX: 2,
|
|
6443
|
+
paddingY: 1,
|
|
6444
|
+
marginBottom: 1
|
|
6445
|
+
},
|
|
6446
|
+
/* @__PURE__ */ React33.createElement(Text24, { color: "red" }, "\u2717 Error: ", error)
|
|
6447
|
+
), (result.header || result.token) && /* @__PURE__ */ React33.createElement(
|
|
6448
|
+
Box23,
|
|
6449
|
+
{
|
|
6450
|
+
flexDirection: "column",
|
|
6451
|
+
borderStyle: "single",
|
|
6452
|
+
borderColor: "green",
|
|
6453
|
+
paddingX: 2,
|
|
6454
|
+
paddingY: 1
|
|
6455
|
+
},
|
|
6456
|
+
/* @__PURE__ */ React33.createElement(Box23, { marginBottom: 1 }, /* @__PURE__ */ React33.createElement(Text24, { bold: true, color: "green" }, "\u2713 Result:"), copied && result.token && /* @__PURE__ */ React33.createElement(Box23, { marginLeft: 2 }, /* @__PURE__ */ React33.createElement(Text24, { color: "green" }, "\u2713 Copied to clipboard!"))),
|
|
6457
|
+
/* @__PURE__ */ React33.createElement(Box23, { flexDirection: "column" }, result.header && /* @__PURE__ */ React33.createElement(React33.Fragment, null, /* @__PURE__ */ React33.createElement(Text24, { bold: true, color: "yellow" }, "Header:"), /* @__PURE__ */ React33.createElement(Text24, null, JSON.stringify(result.header, null, 2)), /* @__PURE__ */ React33.createElement(Text24, null, " "), /* @__PURE__ */ React33.createElement(Text24, { bold: true, color: "yellow" }, "Payload:"), /* @__PURE__ */ React33.createElement(Text24, null, JSON.stringify(result.payload, null, 2)), /* @__PURE__ */ React33.createElement(Text24, null, " "), /* @__PURE__ */ React33.createElement(Text24, { bold: true, color: "yellow" }, "Signature:"), /* @__PURE__ */ React33.createElement(Text24, { dimColor: true }, result.signature)), result.token && /* @__PURE__ */ React33.createElement(React33.Fragment, null, /* @__PURE__ */ React33.createElement(Text24, { bold: true, color: "yellow" }, "Token:"), /* @__PURE__ */ React33.createElement(Text24, { wrap: "wrap" }, result.token)))
|
|
6458
|
+
), /* @__PURE__ */ React33.createElement(Box23, { marginTop: 1, borderStyle: "single", borderColor: "gray", paddingX: 2 }, /* @__PURE__ */ React33.createElement(Text24, { dimColor: true }, "Tab: Next | Enter: Toggle/", mode === "decode" ? "Decode" : "Encode", " | C: Copy | Esc: Back")));
|
|
6459
|
+
};
|
|
6460
|
+
|
|
6461
|
+
// src/ui/utils/views/CronView.tsx
|
|
6462
|
+
import React34, { useState as useState21 } from "react";
|
|
6463
|
+
import { Box as Box24, Text as Text25, useInput as useInput19 } from "ink";
|
|
6464
|
+
import TextInput11 from "ink-text-input";
|
|
6465
|
+
var CronView = () => {
|
|
6466
|
+
const [expression, setExpression] = useState21("");
|
|
6467
|
+
const [result, setResult] = useState21(null);
|
|
6468
|
+
const [error, setError] = useState21("");
|
|
6469
|
+
const [focusedField, setFocusedField] = useState21("expression");
|
|
6470
|
+
const [copied, setCopied] = useState21(false);
|
|
6471
|
+
const service = new UtilsService();
|
|
6472
|
+
useInput19((input, key) => {
|
|
6473
|
+
if (key.tab) {
|
|
6474
|
+
setFocusedField(focusedField === "expression" ? "parse" : "expression");
|
|
6475
|
+
} else if (key.return && focusedField === "parse") {
|
|
6476
|
+
handleParse();
|
|
6477
|
+
} else if (input === "c" && result) {
|
|
6478
|
+
handleCopy();
|
|
6479
|
+
}
|
|
6480
|
+
});
|
|
6481
|
+
const handleParse = () => {
|
|
6482
|
+
if (!expression) {
|
|
6483
|
+
setError("Please enter a cron expression");
|
|
6484
|
+
return;
|
|
6485
|
+
}
|
|
6486
|
+
try {
|
|
6487
|
+
setError("");
|
|
6488
|
+
const parsed = service.parseCron(expression);
|
|
6489
|
+
setResult(parsed);
|
|
6490
|
+
setCopied(false);
|
|
6491
|
+
} catch (err) {
|
|
6492
|
+
setError(err instanceof Error ? err.message : "Failed to parse cron expression");
|
|
6493
|
+
setResult(null);
|
|
6494
|
+
}
|
|
6495
|
+
};
|
|
6496
|
+
const handleCopy = async () => {
|
|
6497
|
+
if (!result) return;
|
|
6498
|
+
try {
|
|
6499
|
+
const { default: clipboardy } = await import("clipboardy");
|
|
6500
|
+
const copyText = `${result.description}
|
|
6501
|
+
|
|
6502
|
+
Next runs:
|
|
6503
|
+
${result.nextRuns.join("\n")}`;
|
|
6504
|
+
await clipboardy.write(copyText);
|
|
6505
|
+
setCopied(true);
|
|
6506
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
6507
|
+
} catch (error2) {
|
|
6508
|
+
}
|
|
6509
|
+
};
|
|
6510
|
+
return /* @__PURE__ */ React34.createElement(Box24, { flexDirection: "column" }, /* @__PURE__ */ React34.createElement(Box24, { marginBottom: 1 }, /* @__PURE__ */ React34.createElement(Text25, { bold: true, color: "cyan" }, "\u23F0 Cron Expression Parser")), /* @__PURE__ */ React34.createElement(
|
|
6511
|
+
Box24,
|
|
6512
|
+
{
|
|
6513
|
+
flexDirection: "column",
|
|
6514
|
+
borderStyle: "single",
|
|
6515
|
+
borderColor: "gray",
|
|
6516
|
+
paddingX: 2,
|
|
6517
|
+
paddingY: 1,
|
|
6518
|
+
marginBottom: 1
|
|
6519
|
+
},
|
|
6520
|
+
/* @__PURE__ */ React34.createElement(Text25, { bold: true, color: "yellow", marginBottom: 1 }, "Options:"),
|
|
6521
|
+
/* @__PURE__ */ React34.createElement(Box24, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React34.createElement(Box24, { marginBottom: 0 }, /* @__PURE__ */ React34.createElement(Text25, { color: focusedField === "expression" ? "green" : void 0 }, focusedField === "expression" ? "\u25B6 " : " ", "Cron Expression:")), /* @__PURE__ */ React34.createElement(Box24, { marginLeft: 2, width: 50 }, focusedField === "expression" ? /* @__PURE__ */ React34.createElement(
|
|
6522
|
+
TextInput11,
|
|
6523
|
+
{
|
|
6524
|
+
value: expression,
|
|
6525
|
+
onChange: setExpression,
|
|
6526
|
+
placeholder: "0 5 * * * (5-field or 6-field)"
|
|
6527
|
+
}
|
|
6528
|
+
) : /* @__PURE__ */ React34.createElement(Text25, { dimColor: !expression }, expression || "(empty)"))),
|
|
6529
|
+
/* @__PURE__ */ React34.createElement(Box24, { marginTop: 1, marginBottom: 1 }, /* @__PURE__ */ React34.createElement(Text25, { dimColor: true }, 'Examples: "0 5 * * *" (daily at 5am), "*/15 * * * *" (every 15 min)')),
|
|
6530
|
+
/* @__PURE__ */ React34.createElement(Box24, { marginTop: 1 }, /* @__PURE__ */ React34.createElement(
|
|
6531
|
+
Text25,
|
|
6532
|
+
{
|
|
6533
|
+
bold: true,
|
|
6534
|
+
backgroundColor: focusedField === "parse" ? "green" : void 0,
|
|
6535
|
+
color: focusedField === "parse" ? "black" : "green"
|
|
6536
|
+
},
|
|
6537
|
+
focusedField === "parse" ? "\u25B6 " : " ",
|
|
6538
|
+
"[ Parse Expression ]"
|
|
6539
|
+
))
|
|
6540
|
+
), error && /* @__PURE__ */ React34.createElement(
|
|
6541
|
+
Box24,
|
|
6542
|
+
{
|
|
6543
|
+
flexDirection: "column",
|
|
6544
|
+
borderStyle: "single",
|
|
6545
|
+
borderColor: "red",
|
|
6546
|
+
paddingX: 2,
|
|
6547
|
+
paddingY: 1,
|
|
6548
|
+
marginBottom: 1
|
|
6549
|
+
},
|
|
6550
|
+
/* @__PURE__ */ React34.createElement(Text25, { color: "red" }, "\u2717 Error: ", error)
|
|
6551
|
+
), result && /* @__PURE__ */ React34.createElement(
|
|
6552
|
+
Box24,
|
|
6553
|
+
{
|
|
6554
|
+
flexDirection: "column",
|
|
6555
|
+
borderStyle: "single",
|
|
6556
|
+
borderColor: "green",
|
|
6557
|
+
paddingX: 2,
|
|
6558
|
+
paddingY: 1
|
|
6559
|
+
},
|
|
6560
|
+
/* @__PURE__ */ React34.createElement(Box24, { marginBottom: 1 }, /* @__PURE__ */ React34.createElement(Text25, { bold: true, color: "green" }, "\u2713 Result:"), copied && /* @__PURE__ */ React34.createElement(Box24, { marginLeft: 2 }, /* @__PURE__ */ React34.createElement(Text25, { color: "green" }, "\u2713 Copied to clipboard!"))),
|
|
6561
|
+
/* @__PURE__ */ React34.createElement(Box24, { flexDirection: "column" }, /* @__PURE__ */ React34.createElement(Text25, { bold: true, color: "yellow" }, "Expression:"), /* @__PURE__ */ React34.createElement(Text25, null, expression), /* @__PURE__ */ React34.createElement(Text25, null, " "), /* @__PURE__ */ React34.createElement(Text25, { bold: true, color: "yellow" }, "Meaning:"), /* @__PURE__ */ React34.createElement(Text25, null, result.description), /* @__PURE__ */ React34.createElement(Text25, null, " "), /* @__PURE__ */ React34.createElement(Text25, { bold: true, color: "yellow" }, "Next 5 executions:"), result.nextRuns.map((run, index) => /* @__PURE__ */ React34.createElement(Text25, { key: index }, " ", index + 1, ". ", run)))
|
|
6562
|
+
), /* @__PURE__ */ React34.createElement(Box24, { marginTop: 1, borderStyle: "single", borderColor: "gray", paddingX: 2 }, /* @__PURE__ */ React34.createElement(Text25, { dimColor: true }, "Tab: Next | Enter: Parse | C: Copy | Esc: Back")));
|
|
6563
|
+
};
|
|
6564
|
+
|
|
6565
|
+
// src/ui/utils/views/TimezoneView.tsx
|
|
6566
|
+
import React35, { useState as useState22 } from "react";
|
|
6567
|
+
import { Box as Box25, Text as Text26, useInput as useInput20 } from "ink";
|
|
6568
|
+
import TextInput12 from "ink-text-input";
|
|
6569
|
+
var TimezoneView = () => {
|
|
6570
|
+
const [time, setTime] = useState22("");
|
|
6571
|
+
const [fromTz, setFromTz] = useState22("UTC");
|
|
6572
|
+
const [toTz, setToTz] = useState22("America/New_York");
|
|
6573
|
+
const [result, setResult] = useState22("");
|
|
6574
|
+
const [error, setError] = useState22("");
|
|
6575
|
+
const [focusedField, setFocusedField] = useState22("time");
|
|
6576
|
+
const [copied, setCopied] = useState22(false);
|
|
6577
|
+
const service = new UtilsService();
|
|
6578
|
+
useInput20((input, key) => {
|
|
6579
|
+
if (key.tab) {
|
|
6580
|
+
const fields = ["time", "from", "to", "convert"];
|
|
6581
|
+
const currentIndex = fields.indexOf(focusedField);
|
|
6582
|
+
setFocusedField(fields[(currentIndex + 1) % fields.length]);
|
|
6583
|
+
} else if (key.return && focusedField === "convert") {
|
|
6584
|
+
handleConvert();
|
|
6585
|
+
} else if (input === "c" && result) {
|
|
6586
|
+
handleCopy();
|
|
6587
|
+
}
|
|
6588
|
+
});
|
|
6589
|
+
const handleConvert = () => {
|
|
6590
|
+
if (!time) {
|
|
6591
|
+
setError("Please enter a time");
|
|
6592
|
+
return;
|
|
6593
|
+
}
|
|
6594
|
+
if (!fromTz || !toTz) {
|
|
6595
|
+
setError("Please enter both timezones");
|
|
6596
|
+
return;
|
|
6597
|
+
}
|
|
6598
|
+
try {
|
|
6599
|
+
setError("");
|
|
6600
|
+
const converted = service.convertTimezone(time, fromTz, toTz);
|
|
6601
|
+
setResult(converted);
|
|
6602
|
+
setCopied(false);
|
|
6603
|
+
} catch (err) {
|
|
6604
|
+
setError(err instanceof Error ? err.message : "Conversion failed");
|
|
6605
|
+
setResult("");
|
|
6606
|
+
}
|
|
6607
|
+
};
|
|
6608
|
+
const handleCopy = async () => {
|
|
6609
|
+
try {
|
|
6610
|
+
const { default: clipboardy } = await import("clipboardy");
|
|
6611
|
+
await clipboardy.write(result);
|
|
6612
|
+
setCopied(true);
|
|
6613
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
6614
|
+
} catch (error2) {
|
|
6615
|
+
}
|
|
6616
|
+
};
|
|
6617
|
+
return /* @__PURE__ */ React35.createElement(Box25, { flexDirection: "column" }, /* @__PURE__ */ React35.createElement(Box25, { marginBottom: 1 }, /* @__PURE__ */ React35.createElement(Text26, { bold: true, color: "cyan" }, "\u{1F30D} Timezone Converter")), /* @__PURE__ */ React35.createElement(
|
|
6618
|
+
Box25,
|
|
6619
|
+
{
|
|
6620
|
+
flexDirection: "column",
|
|
6621
|
+
borderStyle: "single",
|
|
6622
|
+
borderColor: "gray",
|
|
6623
|
+
paddingX: 2,
|
|
6624
|
+
paddingY: 1,
|
|
6625
|
+
marginBottom: 1
|
|
6626
|
+
},
|
|
6627
|
+
/* @__PURE__ */ React35.createElement(Text26, { bold: true, color: "yellow", marginBottom: 1 }, "Options:"),
|
|
6628
|
+
/* @__PURE__ */ React35.createElement(Box25, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React35.createElement(Box25, { marginBottom: 0 }, /* @__PURE__ */ React35.createElement(Text26, { color: focusedField === "time" ? "green" : void 0 }, focusedField === "time" ? "\u25B6 " : " ", "Time:")), /* @__PURE__ */ React35.createElement(Box25, { marginLeft: 2, width: 50 }, focusedField === "time" ? /* @__PURE__ */ React35.createElement(
|
|
6629
|
+
TextInput12,
|
|
6630
|
+
{
|
|
6631
|
+
value: time,
|
|
6632
|
+
onChange: setTime,
|
|
6633
|
+
placeholder: "2024-01-15 10:00:00"
|
|
6634
|
+
}
|
|
6635
|
+
) : /* @__PURE__ */ React35.createElement(Text26, { dimColor: !time }, time || "(empty)"))),
|
|
6636
|
+
/* @__PURE__ */ React35.createElement(Box25, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React35.createElement(Box25, { marginBottom: 0 }, /* @__PURE__ */ React35.createElement(Text26, { color: focusedField === "from" ? "green" : void 0 }, focusedField === "from" ? "\u25B6 " : " ", "From Timezone:")), /* @__PURE__ */ React35.createElement(Box25, { marginLeft: 2, width: 50 }, focusedField === "from" ? /* @__PURE__ */ React35.createElement(
|
|
6637
|
+
TextInput12,
|
|
6638
|
+
{
|
|
6639
|
+
value: fromTz,
|
|
6640
|
+
onChange: setFromTz,
|
|
6641
|
+
placeholder: "UTC or America/New_York"
|
|
6642
|
+
}
|
|
6643
|
+
) : /* @__PURE__ */ React35.createElement(Text26, { dimColor: !fromTz }, fromTz || "(empty)"))),
|
|
6644
|
+
/* @__PURE__ */ React35.createElement(Box25, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React35.createElement(Box25, { marginBottom: 0 }, /* @__PURE__ */ React35.createElement(Text26, { color: focusedField === "to" ? "green" : void 0 }, focusedField === "to" ? "\u25B6 " : " ", "To Timezone:")), /* @__PURE__ */ React35.createElement(Box25, { marginLeft: 2, width: 50 }, focusedField === "to" ? /* @__PURE__ */ React35.createElement(
|
|
6645
|
+
TextInput12,
|
|
6646
|
+
{
|
|
6647
|
+
value: toTz,
|
|
6648
|
+
onChange: setToTz,
|
|
6649
|
+
placeholder: "Asia/Tokyo or Europe/London"
|
|
6650
|
+
}
|
|
6651
|
+
) : /* @__PURE__ */ React35.createElement(Text26, { dimColor: !toTz }, toTz || "(empty)"))),
|
|
6652
|
+
/* @__PURE__ */ React35.createElement(Box25, { marginBottom: 1 }, /* @__PURE__ */ React35.createElement(Text26, { dimColor: true }, "Common: UTC, America/New_York, Europe/London, Asia/Tokyo")),
|
|
6653
|
+
/* @__PURE__ */ React35.createElement(Box25, { marginTop: 1 }, /* @__PURE__ */ React35.createElement(
|
|
6654
|
+
Text26,
|
|
6655
|
+
{
|
|
6656
|
+
bold: true,
|
|
6657
|
+
backgroundColor: focusedField === "convert" ? "green" : void 0,
|
|
6658
|
+
color: focusedField === "convert" ? "black" : "green"
|
|
6659
|
+
},
|
|
6660
|
+
focusedField === "convert" ? "\u25B6 " : " ",
|
|
6661
|
+
"[ Convert ]"
|
|
6662
|
+
))
|
|
6663
|
+
), error && /* @__PURE__ */ React35.createElement(
|
|
6664
|
+
Box25,
|
|
6665
|
+
{
|
|
6666
|
+
flexDirection: "column",
|
|
6667
|
+
borderStyle: "single",
|
|
6668
|
+
borderColor: "red",
|
|
6669
|
+
paddingX: 2,
|
|
6670
|
+
paddingY: 1,
|
|
6671
|
+
marginBottom: 1
|
|
6672
|
+
},
|
|
6673
|
+
/* @__PURE__ */ React35.createElement(Text26, { color: "red" }, "\u2717 Error: ", error)
|
|
6674
|
+
), result && /* @__PURE__ */ React35.createElement(
|
|
6675
|
+
Box25,
|
|
6676
|
+
{
|
|
6677
|
+
flexDirection: "column",
|
|
6678
|
+
borderStyle: "single",
|
|
6679
|
+
borderColor: "green",
|
|
6680
|
+
paddingX: 2,
|
|
6681
|
+
paddingY: 1
|
|
6682
|
+
},
|
|
6683
|
+
/* @__PURE__ */ React35.createElement(Box25, { marginBottom: 1 }, /* @__PURE__ */ React35.createElement(Text26, { bold: true, color: "green" }, "\u2713 Result:"), copied && /* @__PURE__ */ React35.createElement(Box25, { marginLeft: 2 }, /* @__PURE__ */ React35.createElement(Text26, { color: "green" }, "\u2713 Copied to clipboard!"))),
|
|
6684
|
+
/* @__PURE__ */ React35.createElement(Box25, { flexDirection: "column" }, /* @__PURE__ */ React35.createElement(Text26, { dimColor: true }, "From: ", fromTz), /* @__PURE__ */ React35.createElement(Text26, { dimColor: true }, "To: ", toTz), /* @__PURE__ */ React35.createElement(Box25, { marginTop: 1 }, /* @__PURE__ */ React35.createElement(Text26, { wrap: "wrap" }, result)))
|
|
6685
|
+
), /* @__PURE__ */ React35.createElement(Box25, { marginTop: 1, borderStyle: "single", borderColor: "gray", paddingX: 2 }, /* @__PURE__ */ React35.createElement(Text26, { dimColor: true }, "Tab: Next | Enter: Convert | C: Copy | Esc: Back")));
|
|
6686
|
+
};
|
|
6687
|
+
|
|
6688
|
+
// src/ui/utils/views/HttpView.tsx
|
|
6689
|
+
import React36, { useState as useState23 } from "react";
|
|
6690
|
+
import { Box as Box26, Text as Text27, useInput as useInput21 } from "ink";
|
|
6691
|
+
import TextInput13 from "ink-text-input";
|
|
6692
|
+
var METHODS = ["GET", "POST", "PUT", "PATCH", "DELETE"];
|
|
6693
|
+
var HttpView = () => {
|
|
6694
|
+
const [url, setUrl] = useState23("");
|
|
6695
|
+
const [method, setMethod] = useState23("GET");
|
|
6696
|
+
const [headers, setHeaders] = useState23("");
|
|
6697
|
+
const [body, setBody] = useState23("");
|
|
6698
|
+
const [response, setResponse] = useState23(null);
|
|
6699
|
+
const [error, setError] = useState23("");
|
|
6700
|
+
const [loading, setLoading] = useState23(false);
|
|
6701
|
+
const [focusedField, setFocusedField] = useState23("url");
|
|
6702
|
+
const [copied, setCopied] = useState23(false);
|
|
6703
|
+
const service = new UtilsService();
|
|
6704
|
+
useInput21((input, key) => {
|
|
6705
|
+
if (loading) return;
|
|
6706
|
+
if (key.tab) {
|
|
6707
|
+
const fields = ["url", "method", "headers", "body", "send"];
|
|
6708
|
+
const currentIndex = fields.indexOf(focusedField);
|
|
6709
|
+
setFocusedField(fields[(currentIndex + 1) % fields.length]);
|
|
6710
|
+
} else if (key.leftArrow && focusedField === "method") {
|
|
6711
|
+
const currentIndex = METHODS.indexOf(method);
|
|
6712
|
+
setMethod(METHODS[currentIndex > 0 ? currentIndex - 1 : METHODS.length - 1]);
|
|
6713
|
+
} else if (key.rightArrow && focusedField === "method") {
|
|
6714
|
+
const currentIndex = METHODS.indexOf(method);
|
|
6715
|
+
setMethod(METHODS[(currentIndex + 1) % METHODS.length]);
|
|
6716
|
+
} else if (key.return && focusedField === "send") {
|
|
6717
|
+
handleSend();
|
|
6718
|
+
} else if (input === "c" && response) {
|
|
6719
|
+
handleCopy();
|
|
6720
|
+
}
|
|
6721
|
+
});
|
|
6722
|
+
const handleSend = async () => {
|
|
6723
|
+
if (!url) {
|
|
6724
|
+
setError("Please enter a URL");
|
|
6725
|
+
return;
|
|
6726
|
+
}
|
|
6727
|
+
try {
|
|
6728
|
+
setError("");
|
|
6729
|
+
setLoading(true);
|
|
6730
|
+
const headersObj = {};
|
|
6731
|
+
if (headers) {
|
|
6732
|
+
const headerLines = headers.split("\n");
|
|
6733
|
+
for (const line of headerLines) {
|
|
6734
|
+
const [key, ...valueParts] = line.split(":");
|
|
6735
|
+
if (key && valueParts.length > 0) {
|
|
6736
|
+
headersObj[key.trim()] = valueParts.join(":").trim();
|
|
6737
|
+
}
|
|
6738
|
+
}
|
|
6739
|
+
}
|
|
6740
|
+
const result = await service.httpRequest(url, {
|
|
6741
|
+
method,
|
|
6742
|
+
headers: headersObj,
|
|
6743
|
+
body: body || void 0
|
|
6744
|
+
});
|
|
6745
|
+
setResponse(result);
|
|
6746
|
+
setCopied(false);
|
|
6747
|
+
} catch (err) {
|
|
6748
|
+
setError(err instanceof Error ? err.message : "Request failed");
|
|
6749
|
+
setResponse(null);
|
|
6750
|
+
} finally {
|
|
6751
|
+
setLoading(false);
|
|
6752
|
+
}
|
|
6753
|
+
};
|
|
6754
|
+
const handleCopy = async () => {
|
|
6755
|
+
if (!response) return;
|
|
6756
|
+
try {
|
|
6757
|
+
const { default: clipboardy } = await import("clipboardy");
|
|
6758
|
+
const copyText = typeof response.body === "string" ? response.body : JSON.stringify(response.body, null, 2);
|
|
6759
|
+
await clipboardy.write(copyText);
|
|
6760
|
+
setCopied(true);
|
|
6761
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
6762
|
+
} catch (error2) {
|
|
6763
|
+
}
|
|
6764
|
+
};
|
|
6765
|
+
return /* @__PURE__ */ React36.createElement(Box26, { flexDirection: "column" }, /* @__PURE__ */ React36.createElement(Box26, { marginBottom: 1 }, /* @__PURE__ */ React36.createElement(Text27, { bold: true, color: "cyan" }, "\u{1F310} HTTP Request")), /* @__PURE__ */ React36.createElement(
|
|
6766
|
+
Box26,
|
|
6767
|
+
{
|
|
6768
|
+
flexDirection: "column",
|
|
6769
|
+
borderStyle: "single",
|
|
6770
|
+
borderColor: "gray",
|
|
6771
|
+
paddingX: 2,
|
|
6772
|
+
paddingY: 1,
|
|
6773
|
+
marginBottom: 1
|
|
6774
|
+
},
|
|
6775
|
+
/* @__PURE__ */ React36.createElement(Text27, { bold: true, color: "yellow", marginBottom: 1 }, "Request:"),
|
|
6776
|
+
/* @__PURE__ */ React36.createElement(Box26, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React36.createElement(Box26, { marginBottom: 0 }, /* @__PURE__ */ React36.createElement(Text27, { color: focusedField === "url" ? "green" : void 0 }, focusedField === "url" ? "\u25B6 " : " ", "URL:")), /* @__PURE__ */ React36.createElement(Box26, { marginLeft: 2, width: 60 }, focusedField === "url" ? /* @__PURE__ */ React36.createElement(
|
|
6777
|
+
TextInput13,
|
|
6778
|
+
{
|
|
6779
|
+
value: url,
|
|
6780
|
+
onChange: setUrl,
|
|
6781
|
+
placeholder: "https://api.example.com/endpoint"
|
|
6782
|
+
}
|
|
6783
|
+
) : /* @__PURE__ */ React36.createElement(Text27, { dimColor: !url }, url || "(empty)"))),
|
|
6784
|
+
/* @__PURE__ */ React36.createElement(Box26, { marginBottom: 1 }, /* @__PURE__ */ React36.createElement(Box26, { width: 20 }, /* @__PURE__ */ React36.createElement(Text27, { color: focusedField === "method" ? "green" : void 0 }, focusedField === "method" ? "\u25B6 " : " ", "Method:")), /* @__PURE__ */ React36.createElement(Text27, { bold: true, color: focusedField === "method" ? "yellow" : void 0 }, method), focusedField === "method" && /* @__PURE__ */ React36.createElement(Text27, { dimColor: true }, " (\u2190 \u2192 to change)")),
|
|
6785
|
+
/* @__PURE__ */ React36.createElement(Box26, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React36.createElement(Box26, { marginBottom: 0 }, /* @__PURE__ */ React36.createElement(Text27, { color: focusedField === "headers" ? "green" : void 0 }, focusedField === "headers" ? "\u25B6 " : " ", "Headers (one per line, Key: Value):")), /* @__PURE__ */ React36.createElement(Box26, { marginLeft: 2, width: 60 }, focusedField === "headers" ? /* @__PURE__ */ React36.createElement(
|
|
6786
|
+
TextInput13,
|
|
6787
|
+
{
|
|
6788
|
+
value: headers,
|
|
6789
|
+
onChange: setHeaders,
|
|
6790
|
+
placeholder: "Authorization: Bearer token"
|
|
6791
|
+
}
|
|
6792
|
+
) : /* @__PURE__ */ React36.createElement(Text27, { dimColor: !headers }, headers || "(none)"))),
|
|
6793
|
+
(method === "POST" || method === "PUT" || method === "PATCH") && /* @__PURE__ */ React36.createElement(Box26, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React36.createElement(Box26, { marginBottom: 0 }, /* @__PURE__ */ React36.createElement(Text27, { color: focusedField === "body" ? "green" : void 0 }, focusedField === "body" ? "\u25B6 " : " ", "Body (JSON):")), /* @__PURE__ */ React36.createElement(Box26, { marginLeft: 2, width: 60 }, focusedField === "body" ? /* @__PURE__ */ React36.createElement(
|
|
6794
|
+
TextInput13,
|
|
6795
|
+
{
|
|
6796
|
+
value: body,
|
|
6797
|
+
onChange: setBody,
|
|
6798
|
+
placeholder: '{"key":"value"}'
|
|
6799
|
+
}
|
|
6800
|
+
) : /* @__PURE__ */ React36.createElement(Text27, { dimColor: !body }, body || "(empty)"))),
|
|
6801
|
+
/* @__PURE__ */ React36.createElement(Box26, { marginTop: 1 }, /* @__PURE__ */ React36.createElement(
|
|
6802
|
+
Text27,
|
|
6803
|
+
{
|
|
6804
|
+
bold: true,
|
|
6805
|
+
backgroundColor: focusedField === "send" ? "green" : void 0,
|
|
6806
|
+
color: focusedField === "send" ? "black" : "green"
|
|
6807
|
+
},
|
|
6808
|
+
focusedField === "send" ? "\u25B6 " : " ",
|
|
6809
|
+
"[ ",
|
|
6810
|
+
loading ? "Sending..." : "Send Request",
|
|
6811
|
+
" ]"
|
|
6812
|
+
))
|
|
6813
|
+
), error && /* @__PURE__ */ React36.createElement(
|
|
6814
|
+
Box26,
|
|
6815
|
+
{
|
|
6816
|
+
flexDirection: "column",
|
|
6817
|
+
borderStyle: "single",
|
|
6818
|
+
borderColor: "red",
|
|
6819
|
+
paddingX: 2,
|
|
6820
|
+
paddingY: 1,
|
|
6821
|
+
marginBottom: 1
|
|
6822
|
+
},
|
|
6823
|
+
/* @__PURE__ */ React36.createElement(Text27, { color: "red" }, "\u2717 Error: ", error)
|
|
6824
|
+
), response && /* @__PURE__ */ React36.createElement(
|
|
6825
|
+
Box26,
|
|
6826
|
+
{
|
|
6827
|
+
flexDirection: "column",
|
|
6828
|
+
borderStyle: "single",
|
|
6829
|
+
borderColor: "green",
|
|
6830
|
+
paddingX: 2,
|
|
6831
|
+
paddingY: 1
|
|
6832
|
+
},
|
|
6833
|
+
/* @__PURE__ */ React36.createElement(Box26, { marginBottom: 1 }, /* @__PURE__ */ React36.createElement(Text27, { bold: true, color: "green" }, "\u2713 Response:"), copied && /* @__PURE__ */ React36.createElement(Box26, { marginLeft: 2 }, /* @__PURE__ */ React36.createElement(Text27, { color: "green" }, "\u2713 Copied body to clipboard!"))),
|
|
6834
|
+
/* @__PURE__ */ React36.createElement(Box26, { flexDirection: "column" }, /* @__PURE__ */ React36.createElement(Text27, null, "Status: ", /* @__PURE__ */ React36.createElement(Text27, { color: response.status < 400 ? "green" : "red" }, response.status)), /* @__PURE__ */ React36.createElement(Text27, null, "Time: ", response.time, "ms"), /* @__PURE__ */ React36.createElement(Text27, null, "Size: ", response.size), /* @__PURE__ */ React36.createElement(Text27, null, " "), /* @__PURE__ */ React36.createElement(Text27, { bold: true, color: "yellow" }, "Headers:"), Object.entries(response.headers).slice(0, 5).map(([key, value]) => /* @__PURE__ */ React36.createElement(Text27, { key, dimColor: true }, " ", key, ": ", value)), /* @__PURE__ */ React36.createElement(Text27, null, " "), /* @__PURE__ */ React36.createElement(Text27, { bold: true, color: "yellow" }, "Body:"), /* @__PURE__ */ React36.createElement(Text27, null, typeof response.body === "string" ? response.body.slice(0, 500) : JSON.stringify(response.body, null, 2).slice(0, 500)))
|
|
6835
|
+
), /* @__PURE__ */ React36.createElement(Box26, { marginTop: 1, borderStyle: "single", borderColor: "gray", paddingX: 2 }, /* @__PURE__ */ React36.createElement(Text27, { dimColor: true }, "Tab: Next | \u2190/\u2192: Change method | Enter: Send | C: Copy body | Esc: Back")));
|
|
6836
|
+
};
|
|
6837
|
+
|
|
6838
|
+
// src/ui/utils/views/MarkdownView.tsx
|
|
6839
|
+
import React37, { useState as useState24 } from "react";
|
|
6840
|
+
import { Box as Box27, Text as Text28, useInput as useInput22 } from "ink";
|
|
6841
|
+
import TextInput14 from "ink-text-input";
|
|
6842
|
+
import * as fs8 from "fs";
|
|
6843
|
+
import * as path5 from "path";
|
|
6844
|
+
var MarkdownView = () => {
|
|
6845
|
+
const [filePath, setFilePath] = useState24("");
|
|
6846
|
+
const [content, setContent] = useState24("");
|
|
6847
|
+
const [error, setError] = useState24("");
|
|
6848
|
+
const [focusedField, setFocusedField] = useState24("file");
|
|
6849
|
+
useInput22((input, key) => {
|
|
6850
|
+
if (key.tab) {
|
|
6851
|
+
setFocusedField(focusedField === "file" ? "preview" : "file");
|
|
6852
|
+
} else if (key.return && focusedField === "preview") {
|
|
6853
|
+
handlePreview();
|
|
6854
|
+
}
|
|
6855
|
+
});
|
|
6856
|
+
const handlePreview = async () => {
|
|
6857
|
+
if (!filePath) {
|
|
6858
|
+
setError("Please enter a file path");
|
|
6859
|
+
return;
|
|
6860
|
+
}
|
|
6861
|
+
try {
|
|
6862
|
+
setError("");
|
|
6863
|
+
const resolvedPath = path5.resolve(filePath);
|
|
6864
|
+
if (!fs8.existsSync(resolvedPath)) {
|
|
6865
|
+
setError(`File not found: ${resolvedPath}`);
|
|
6866
|
+
return;
|
|
6867
|
+
}
|
|
6868
|
+
let fileContent = fs8.readFileSync(resolvedPath, "utf-8");
|
|
6869
|
+
fileContent = fileContent.replace(/```mermaid\n([\s\S]*?)```/g, (match, code) => {
|
|
6870
|
+
return `
|
|
6871
|
+
\u{1F3A8} **Mermaid Diagram**
|
|
6872
|
+
|
|
6873
|
+
\`\`\`
|
|
6874
|
+
${code.trim()}
|
|
6875
|
+
\`\`\`
|
|
6876
|
+
|
|
6877
|
+
\u{1F4A1} *Tip: Mermaid diagrams cannot be rendered in terminal. View in a Markdown viewer.*
|
|
6878
|
+
`;
|
|
6879
|
+
});
|
|
6880
|
+
const { marked: marked2 } = await import("marked");
|
|
6881
|
+
const { default: markedTerminal } = await import("marked-terminal");
|
|
6882
|
+
marked2.use(markedTerminal());
|
|
6883
|
+
const rendered = marked2(fileContent);
|
|
6884
|
+
setContent(rendered);
|
|
6885
|
+
} catch (err) {
|
|
6886
|
+
setError(err instanceof Error ? err.message : "Failed to preview file");
|
|
6887
|
+
setContent("");
|
|
6888
|
+
}
|
|
6889
|
+
};
|
|
6890
|
+
return /* @__PURE__ */ React37.createElement(Box27, { flexDirection: "column" }, /* @__PURE__ */ React37.createElement(Box27, { marginBottom: 1 }, /* @__PURE__ */ React37.createElement(Text28, { bold: true, color: "cyan" }, "\u{1F4C4} Markdown Preview")), /* @__PURE__ */ React37.createElement(
|
|
6891
|
+
Box27,
|
|
6892
|
+
{
|
|
6893
|
+
flexDirection: "column",
|
|
6894
|
+
borderStyle: "single",
|
|
6895
|
+
borderColor: "gray",
|
|
6896
|
+
paddingX: 2,
|
|
6897
|
+
paddingY: 1,
|
|
6898
|
+
marginBottom: 1
|
|
6899
|
+
},
|
|
6900
|
+
/* @__PURE__ */ React37.createElement(Text28, { bold: true, color: "yellow", marginBottom: 1 }, "Options:"),
|
|
6901
|
+
/* @__PURE__ */ React37.createElement(Box27, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React37.createElement(Box27, { marginBottom: 0 }, /* @__PURE__ */ React37.createElement(Text28, { color: focusedField === "file" ? "green" : void 0 }, focusedField === "file" ? "\u25B6 " : " ", "File path:")), /* @__PURE__ */ React37.createElement(Box27, { marginLeft: 2, width: 60 }, focusedField === "file" ? /* @__PURE__ */ React37.createElement(
|
|
6902
|
+
TextInput14,
|
|
6903
|
+
{
|
|
6904
|
+
value: filePath,
|
|
6905
|
+
onChange: setFilePath,
|
|
6906
|
+
placeholder: "./README.md or /path/to/file.md"
|
|
6907
|
+
}
|
|
6908
|
+
) : /* @__PURE__ */ React37.createElement(Text28, { dimColor: !filePath }, filePath || "(empty)"))),
|
|
6909
|
+
/* @__PURE__ */ React37.createElement(Box27, { marginTop: 1 }, /* @__PURE__ */ React37.createElement(
|
|
6910
|
+
Text28,
|
|
6911
|
+
{
|
|
6912
|
+
bold: true,
|
|
6913
|
+
backgroundColor: focusedField === "preview" ? "green" : void 0,
|
|
6914
|
+
color: focusedField === "preview" ? "black" : "green"
|
|
6915
|
+
},
|
|
6916
|
+
focusedField === "preview" ? "\u25B6 " : " ",
|
|
6917
|
+
"[ Preview File ]"
|
|
6918
|
+
))
|
|
6919
|
+
), error && /* @__PURE__ */ React37.createElement(
|
|
6920
|
+
Box27,
|
|
6921
|
+
{
|
|
6922
|
+
flexDirection: "column",
|
|
6923
|
+
borderStyle: "single",
|
|
6924
|
+
borderColor: "red",
|
|
6925
|
+
paddingX: 2,
|
|
6926
|
+
paddingY: 1,
|
|
6927
|
+
marginBottom: 1
|
|
6928
|
+
},
|
|
6929
|
+
/* @__PURE__ */ React37.createElement(Text28, { color: "red" }, "\u2717 Error: ", error)
|
|
6930
|
+
), content && /* @__PURE__ */ React37.createElement(
|
|
6931
|
+
Box27,
|
|
6932
|
+
{
|
|
6933
|
+
flexDirection: "column",
|
|
6934
|
+
borderStyle: "single",
|
|
6935
|
+
borderColor: "green",
|
|
6936
|
+
paddingX: 2,
|
|
6937
|
+
paddingY: 1
|
|
6938
|
+
},
|
|
6939
|
+
/* @__PURE__ */ React37.createElement(Box27, { marginBottom: 1 }, /* @__PURE__ */ React37.createElement(Text28, { bold: true, color: "green" }, "\u2713 Preview:")),
|
|
6940
|
+
/* @__PURE__ */ React37.createElement(Box27, { flexDirection: "column" }, /* @__PURE__ */ React37.createElement(Text28, null, content))
|
|
6941
|
+
), /* @__PURE__ */ React37.createElement(Box27, { marginTop: 1, borderStyle: "single", borderColor: "gray", paddingX: 2 }, /* @__PURE__ */ React37.createElement(Text28, { dimColor: true }, "Tab: Next | Enter: Preview | Esc: Back")));
|
|
6942
|
+
};
|
|
6943
|
+
|
|
6944
|
+
// src/ui/utils/UtilsApp.tsx
|
|
5726
6945
|
var MENU_ITEMS2 = [
|
|
5727
6946
|
{ id: "password", icon: "\u{1F510}", label: "Password", description: "Generate secure passwords" },
|
|
5728
6947
|
{ id: "uuid", icon: "\u{1F194}", label: "UUID", description: "Generate UUID v4" },
|
|
@@ -5739,10 +6958,10 @@ var MENU_ITEMS2 = [
|
|
|
5739
6958
|
{ id: "markdown", icon: "\u{1F4C4}", label: "Markdown", description: "Preview markdown" }
|
|
5740
6959
|
];
|
|
5741
6960
|
var UtilsApp = ({ onExit }) => {
|
|
5742
|
-
const [selectedIndex, setSelectedIndex] =
|
|
5743
|
-
const [activeView, setActiveView] =
|
|
6961
|
+
const [selectedIndex, setSelectedIndex] = useState25(0);
|
|
6962
|
+
const [activeView, setActiveView] = useState25(null);
|
|
5744
6963
|
const { exit } = useApp5();
|
|
5745
|
-
|
|
6964
|
+
useInput23((input, key) => {
|
|
5746
6965
|
if (activeView) {
|
|
5747
6966
|
if (key.escape) {
|
|
5748
6967
|
setActiveView(null);
|
|
@@ -5760,8 +6979,8 @@ var UtilsApp = ({ onExit }) => {
|
|
|
5760
6979
|
exit();
|
|
5761
6980
|
}
|
|
5762
6981
|
});
|
|
5763
|
-
return /* @__PURE__ */
|
|
5764
|
-
|
|
6982
|
+
return /* @__PURE__ */ React38.createElement(Box28, { flexDirection: "column", width: "100%", height: "100%" }, /* @__PURE__ */ React38.createElement(
|
|
6983
|
+
Box28,
|
|
5765
6984
|
{
|
|
5766
6985
|
borderStyle: "single",
|
|
5767
6986
|
borderColor: "cyan",
|
|
@@ -5769,10 +6988,10 @@ var UtilsApp = ({ onExit }) => {
|
|
|
5769
6988
|
paddingY: 0,
|
|
5770
6989
|
marginBottom: 1
|
|
5771
6990
|
},
|
|
5772
|
-
/* @__PURE__ */
|
|
5773
|
-
/* @__PURE__ */
|
|
5774
|
-
), /* @__PURE__ */
|
|
5775
|
-
|
|
6991
|
+
/* @__PURE__ */ React38.createElement(Text29, { bold: true, color: "cyan" }, "\u{1F6E0}\uFE0F Developer Utilities - Interactive Mode"),
|
|
6992
|
+
/* @__PURE__ */ React38.createElement(Box28, { marginLeft: "auto" }, /* @__PURE__ */ React38.createElement(Text29, { dimColor: true }, "Press 'q' to quit"))
|
|
6993
|
+
), /* @__PURE__ */ React38.createElement(Box28, { flexGrow: 1 }, /* @__PURE__ */ React38.createElement(
|
|
6994
|
+
Box28,
|
|
5776
6995
|
{
|
|
5777
6996
|
flexDirection: "column",
|
|
5778
6997
|
width: 30,
|
|
@@ -5782,9 +7001,9 @@ var UtilsApp = ({ onExit }) => {
|
|
|
5782
7001
|
paddingY: 1,
|
|
5783
7002
|
marginRight: 1
|
|
5784
7003
|
},
|
|
5785
|
-
/* @__PURE__ */
|
|
5786
|
-
MENU_ITEMS2.map((item, index) => /* @__PURE__ */
|
|
5787
|
-
|
|
7004
|
+
/* @__PURE__ */ React38.createElement(Box28, { marginBottom: 1 }, /* @__PURE__ */ React38.createElement(Text29, { bold: true, color: "yellow" }, "Select Utility:")),
|
|
7005
|
+
MENU_ITEMS2.map((item, index) => /* @__PURE__ */ React38.createElement(Box28, { key: item.id, marginBottom: 0 }, /* @__PURE__ */ React38.createElement(
|
|
7006
|
+
Text29,
|
|
5788
7007
|
{
|
|
5789
7008
|
color: selectedIndex === index && !activeView ? "green" : void 0,
|
|
5790
7009
|
bold: selectedIndex === index && !activeView,
|
|
@@ -5795,9 +7014,9 @@ var UtilsApp = ({ onExit }) => {
|
|
|
5795
7014
|
" ",
|
|
5796
7015
|
item.label
|
|
5797
7016
|
))),
|
|
5798
|
-
/* @__PURE__ */
|
|
5799
|
-
), /* @__PURE__ */
|
|
5800
|
-
|
|
7017
|
+
/* @__PURE__ */ React38.createElement(Box28, { marginTop: 1, borderStyle: "single", borderColor: "gray", paddingX: 1 }, /* @__PURE__ */ React38.createElement(Text29, { dimColor: true }, "\u2191/\u2193: Navigate", "\n", "Enter: Select", "\n", "Esc: Back/Quit"))
|
|
7018
|
+
), /* @__PURE__ */ React38.createElement(
|
|
7019
|
+
Box28,
|
|
5801
7020
|
{
|
|
5802
7021
|
flexDirection: "column",
|
|
5803
7022
|
flexGrow: 1,
|
|
@@ -5806,21 +7025,21 @@ var UtilsApp = ({ onExit }) => {
|
|
|
5806
7025
|
paddingX: 2,
|
|
5807
7026
|
paddingY: 1
|
|
5808
7027
|
},
|
|
5809
|
-
activeView ? /* @__PURE__ */
|
|
5810
|
-
)), /* @__PURE__ */
|
|
5811
|
-
|
|
7028
|
+
activeView ? /* @__PURE__ */ React38.createElement(ActiveUtilityView, { utilityType: activeView }) : /* @__PURE__ */ React38.createElement(WelcomeView, { selectedItem: MENU_ITEMS2[selectedIndex] })
|
|
7029
|
+
)), /* @__PURE__ */ React38.createElement(
|
|
7030
|
+
Box28,
|
|
5812
7031
|
{
|
|
5813
7032
|
borderStyle: "single",
|
|
5814
7033
|
borderColor: "gray",
|
|
5815
7034
|
paddingX: 2,
|
|
5816
7035
|
marginTop: 1
|
|
5817
7036
|
},
|
|
5818
|
-
/* @__PURE__ */
|
|
7037
|
+
/* @__PURE__ */ React38.createElement(Text29, { dimColor: true }, "jai1-cli | Use arrow keys or j/k to navigate")
|
|
5819
7038
|
));
|
|
5820
7039
|
};
|
|
5821
7040
|
var WelcomeView = ({ selectedItem }) => {
|
|
5822
|
-
return /* @__PURE__ */
|
|
5823
|
-
|
|
7041
|
+
return /* @__PURE__ */ React38.createElement(Box28, { flexDirection: "column" }, /* @__PURE__ */ React38.createElement(Box28, { marginBottom: 1 }, /* @__PURE__ */ React38.createElement(Text29, { bold: true, color: "cyan" }, "Welcome to Developer Utilities")), /* @__PURE__ */ React38.createElement(Box28, { marginBottom: 2 }, /* @__PURE__ */ React38.createElement(Text29, null, "Select a utility from the left menu to get started.")), /* @__PURE__ */ React38.createElement(
|
|
7042
|
+
Box28,
|
|
5824
7043
|
{
|
|
5825
7044
|
borderStyle: "single",
|
|
5826
7045
|
borderColor: "yellow",
|
|
@@ -5828,27 +7047,57 @@ var WelcomeView = ({ selectedItem }) => {
|
|
|
5828
7047
|
paddingY: 1,
|
|
5829
7048
|
marginBottom: 2
|
|
5830
7049
|
},
|
|
5831
|
-
/* @__PURE__ */
|
|
5832
|
-
), /* @__PURE__ */
|
|
7050
|
+
/* @__PURE__ */ React38.createElement(Box28, { flexDirection: "column" }, /* @__PURE__ */ React38.createElement(Text29, { bold: true, color: "yellow" }, selectedItem.icon, " ", selectedItem.label), /* @__PURE__ */ React38.createElement(Text29, { dimColor: true }, selectedItem.description))
|
|
7051
|
+
), /* @__PURE__ */ React38.createElement(Box28, { marginBottom: 1 }, /* @__PURE__ */ React38.createElement(Text29, { bold: true }, "Quick Actions:")), /* @__PURE__ */ React38.createElement(Box28, { flexDirection: "column", marginLeft: 2 }, /* @__PURE__ */ React38.createElement(Text29, null, "\u2022 Press ", /* @__PURE__ */ React38.createElement(Text29, { color: "green" }, "Enter"), " to open selected utility"), /* @__PURE__ */ React38.createElement(Text29, null, "\u2022 Use ", /* @__PURE__ */ React38.createElement(Text29, { color: "green" }, "\u2191/\u2193"), " or ", /* @__PURE__ */ React38.createElement(Text29, { color: "green" }, "j/k"), " to navigate"), /* @__PURE__ */ React38.createElement(Text29, null, "\u2022 Press ", /* @__PURE__ */ React38.createElement(Text29, { color: "green" }, "Esc"), " to go back or quit"), /* @__PURE__ */ React38.createElement(Text29, null, "\u2022 Press ", /* @__PURE__ */ React38.createElement(Text29, { color: "green" }, "q"), " to quit anytime")), /* @__PURE__ */ React38.createElement(Box28, { marginTop: 2 }, /* @__PURE__ */ React38.createElement(Text29, { dimColor: true }, "\u{1F4A1} Tip: Each utility provides an interactive interface for easy usage.")));
|
|
5833
7052
|
};
|
|
5834
7053
|
var ActiveUtilityView = ({ utilityType }) => {
|
|
5835
|
-
|
|
5836
|
-
|
|
7054
|
+
switch (utilityType) {
|
|
7055
|
+
case "password":
|
|
7056
|
+
return /* @__PURE__ */ React38.createElement(PasswordView, null);
|
|
7057
|
+
case "uuid":
|
|
7058
|
+
return /* @__PURE__ */ React38.createElement(UuidView, null);
|
|
7059
|
+
case "hash":
|
|
7060
|
+
return /* @__PURE__ */ React38.createElement(HashView, null);
|
|
7061
|
+
case "base64-encode":
|
|
7062
|
+
case "base64-decode":
|
|
7063
|
+
return /* @__PURE__ */ React38.createElement(Base64View, null);
|
|
7064
|
+
case "url-encode":
|
|
7065
|
+
case "url-decode":
|
|
7066
|
+
return /* @__PURE__ */ React38.createElement(UrlView, null);
|
|
7067
|
+
case "unix-time":
|
|
7068
|
+
return /* @__PURE__ */ React38.createElement(UnixTimeView, null);
|
|
7069
|
+
case "jwt":
|
|
7070
|
+
return /* @__PURE__ */ React38.createElement(JwtView, null);
|
|
7071
|
+
case "cron":
|
|
7072
|
+
return /* @__PURE__ */ React38.createElement(CronView, null);
|
|
7073
|
+
case "timezone":
|
|
7074
|
+
return /* @__PURE__ */ React38.createElement(TimezoneView, null);
|
|
7075
|
+
case "http":
|
|
7076
|
+
return /* @__PURE__ */ React38.createElement(HttpView, null);
|
|
7077
|
+
case "markdown":
|
|
7078
|
+
return /* @__PURE__ */ React38.createElement(MarkdownView, null);
|
|
7079
|
+
default:
|
|
7080
|
+
return /* @__PURE__ */ React38.createElement(PlaceholderView, { utilityType });
|
|
7081
|
+
}
|
|
7082
|
+
};
|
|
7083
|
+
var PlaceholderView = ({ utilityType }) => {
|
|
7084
|
+
const item = MENU_ITEMS2.find((m) => m.id === utilityType);
|
|
7085
|
+
return /* @__PURE__ */ React38.createElement(Box28, { flexDirection: "column" }, /* @__PURE__ */ React38.createElement(Box28, { marginBottom: 1 }, /* @__PURE__ */ React38.createElement(Text29, { bold: true, color: "cyan" }, item?.icon, " ", item?.label)), /* @__PURE__ */ React38.createElement(Box28, { borderStyle: "single", borderColor: "yellow", paddingX: 2, paddingY: 1 }, /* @__PURE__ */ React38.createElement(Text29, null, "\u{1F6A7} This utility view is under construction.", "\n", "\n", "For now, use the command-line version:", "\n", /* @__PURE__ */ React38.createElement(Text29, { color: "green" }, "$ jai1 utils ", utilityType, " --help"), "\n", "\n", "Press ", /* @__PURE__ */ React38.createElement(Text29, { color: "yellow" }, "Esc"), " to return to the menu.")));
|
|
5837
7086
|
};
|
|
5838
7087
|
|
|
5839
7088
|
// src/commands/utils/interactive.ts
|
|
5840
7089
|
async function runInteractiveMode() {
|
|
5841
|
-
return new Promise((
|
|
7090
|
+
return new Promise((resolve4) => {
|
|
5842
7091
|
const { unmount, waitUntilExit } = render5(
|
|
5843
|
-
|
|
7092
|
+
React39.createElement(UtilsApp, {
|
|
5844
7093
|
onExit: () => {
|
|
5845
7094
|
unmount();
|
|
5846
|
-
|
|
7095
|
+
resolve4();
|
|
5847
7096
|
}
|
|
5848
7097
|
})
|
|
5849
7098
|
);
|
|
5850
7099
|
waitUntilExit().then(() => {
|
|
5851
|
-
|
|
7100
|
+
resolve4();
|
|
5852
7101
|
});
|
|
5853
7102
|
});
|
|
5854
7103
|
}
|
|
@@ -6171,7 +7420,7 @@ import { Command as Command30 } from "commander";
|
|
|
6171
7420
|
|
|
6172
7421
|
// src/services/redmine-config.service.ts
|
|
6173
7422
|
import { readFile as readFile6 } from "fs/promises";
|
|
6174
|
-
import { resolve } from "path";
|
|
7423
|
+
import { resolve as resolve2 } from "path";
|
|
6175
7424
|
|
|
6176
7425
|
// src/types/redmine.types.ts
|
|
6177
7426
|
import { z } from "zod";
|
|
@@ -6222,7 +7471,7 @@ import { z as z2 } from "zod";
|
|
|
6222
7471
|
var RedmineConfigService = class {
|
|
6223
7472
|
configPath;
|
|
6224
7473
|
constructor(configPath) {
|
|
6225
|
-
this.configPath = configPath ??
|
|
7474
|
+
this.configPath = configPath ?? resolve2(process.cwd(), "redmine.config.yaml");
|
|
6226
7475
|
}
|
|
6227
7476
|
/**
|
|
6228
7477
|
* Load Redmine configuration from YAML file
|
|
@@ -6288,8 +7537,8 @@ var RedmineApiClient = class {
|
|
|
6288
7537
|
this.retryConfig = config.defaults.retry;
|
|
6289
7538
|
this.concurrencyLimit = pLimit2(config.defaults.concurrency);
|
|
6290
7539
|
}
|
|
6291
|
-
async request(
|
|
6292
|
-
const url = `${this.baseUrl}${
|
|
7540
|
+
async request(path7, options = {}) {
|
|
7541
|
+
const url = `${this.baseUrl}${path7}`;
|
|
6293
7542
|
const headers = {
|
|
6294
7543
|
"X-Redmine-API-Key": this.apiAccessToken,
|
|
6295
7544
|
"Content-Type": "application/json",
|
|
@@ -6350,8 +7599,8 @@ var RedmineApiClient = class {
|
|
|
6350
7599
|
if (include && include.length > 0) {
|
|
6351
7600
|
params.append("include", include.join(","));
|
|
6352
7601
|
}
|
|
6353
|
-
const
|
|
6354
|
-
return this.request(
|
|
7602
|
+
const path7 = `/issues/${issueId}.json${params.toString() ? `?${params.toString()}` : ""}`;
|
|
7603
|
+
return this.request(path7);
|
|
6355
7604
|
}
|
|
6356
7605
|
async getIssues(projectId, options = {}) {
|
|
6357
7606
|
const params = new URLSearchParams();
|
|
@@ -6371,8 +7620,8 @@ var RedmineApiClient = class {
|
|
|
6371
7620
|
if (options.updatedSince) {
|
|
6372
7621
|
params.append("updated_on", `>=${options.updatedSince}`);
|
|
6373
7622
|
}
|
|
6374
|
-
const
|
|
6375
|
-
return this.request(
|
|
7623
|
+
const path7 = `/issues.json?${params.toString()}`;
|
|
7624
|
+
return this.request(path7);
|
|
6376
7625
|
}
|
|
6377
7626
|
async getAllIssues(projectId, options = {}) {
|
|
6378
7627
|
const pageSize = options.pageSize || 100;
|
|
@@ -6505,7 +7754,7 @@ async function handleRedmineCheck(options) {
|
|
|
6505
7754
|
import { Command as Command31 } from "commander";
|
|
6506
7755
|
|
|
6507
7756
|
// src/sync-issue.ts
|
|
6508
|
-
import { resolve as
|
|
7757
|
+
import { resolve as resolve3, relative } from "path";
|
|
6509
7758
|
|
|
6510
7759
|
// src/mappers.ts
|
|
6511
7760
|
function mapIssueToFrontmatter(issue) {
|
|
@@ -6765,7 +8014,7 @@ async function syncIssue(issueId, config, options = {}) {
|
|
|
6765
8014
|
const response = await client.getIssue(issueId, include);
|
|
6766
8015
|
const issue = response.issue;
|
|
6767
8016
|
const filename = generateFilename(issue.id, issue.subject, config.filename);
|
|
6768
|
-
const filePath =
|
|
8017
|
+
const filePath = resolve3(outputDir, filename);
|
|
6769
8018
|
const relativePath = relative(process.cwd(), filePath);
|
|
6770
8019
|
const existingFile = await readMarkdownFile(filePath);
|
|
6771
8020
|
const existingIssueId = extractIssueIdFromFrontmatter(existingFile.frontmatter);
|
|
@@ -7048,7 +8297,7 @@ async function handleSyncProject(options) {
|
|
|
7048
8297
|
|
|
7049
8298
|
// src/commands/framework/info.ts
|
|
7050
8299
|
import { Command as Command33 } from "commander";
|
|
7051
|
-
import { promises as
|
|
8300
|
+
import { promises as fs9 } from "fs";
|
|
7052
8301
|
import { join as join5 } from "path";
|
|
7053
8302
|
import { homedir as homedir5 } from "os";
|
|
7054
8303
|
function createInfoCommand() {
|
|
@@ -7100,7 +8349,7 @@ function maskKey3(key) {
|
|
|
7100
8349
|
async function getProjectStatus2() {
|
|
7101
8350
|
const projectJai1 = join5(process.cwd(), ".jai1");
|
|
7102
8351
|
try {
|
|
7103
|
-
await
|
|
8352
|
+
await fs9.access(projectJai1);
|
|
7104
8353
|
return { exists: true, version: "Synced" };
|
|
7105
8354
|
} catch {
|
|
7106
8355
|
return { exists: false };
|
|
@@ -7290,9 +8539,9 @@ function createClearBackupsCommand() {
|
|
|
7290
8539
|
// src/commands/vscode/index.ts
|
|
7291
8540
|
import { Command as Command36 } from "commander";
|
|
7292
8541
|
import { checkbox as checkbox3, confirm as confirm8, select as select3 } from "@inquirer/prompts";
|
|
7293
|
-
import
|
|
7294
|
-
import
|
|
7295
|
-
import { existsSync as
|
|
8542
|
+
import fs10 from "fs/promises";
|
|
8543
|
+
import path6 from "path";
|
|
8544
|
+
import { existsSync as existsSync3 } from "fs";
|
|
7296
8545
|
var PERFORMANCE_GROUPS2 = {
|
|
7297
8546
|
telemetry: {
|
|
7298
8547
|
name: "Telemetry",
|
|
@@ -7511,8 +8760,8 @@ async function selectGroupsToApply2(action) {
|
|
|
7511
8760
|
}
|
|
7512
8761
|
}
|
|
7513
8762
|
async function applyGroups2(groupKeys, action) {
|
|
7514
|
-
const vscodeDir =
|
|
7515
|
-
const settingsPath =
|
|
8763
|
+
const vscodeDir = path6.join(process.cwd(), ".vscode");
|
|
8764
|
+
const settingsPath = path6.join(vscodeDir, "settings.json");
|
|
7516
8765
|
const invalidGroups = groupKeys.filter((key) => !PERFORMANCE_GROUPS2[key]);
|
|
7517
8766
|
if (invalidGroups.length > 0) {
|
|
7518
8767
|
console.log(`
|
|
@@ -7520,14 +8769,14 @@ async function applyGroups2(groupKeys, action) {
|
|
|
7520
8769
|
console.log(' \u{1F4A1} Ch\u1EA1y "jai1 vscode list" \u0111\u1EC3 xem danh s\xE1ch nh\xF3m c\xF3 s\u1EB5n.');
|
|
7521
8770
|
return;
|
|
7522
8771
|
}
|
|
7523
|
-
if (!
|
|
7524
|
-
await
|
|
8772
|
+
if (!existsSync3(vscodeDir)) {
|
|
8773
|
+
await fs10.mkdir(vscodeDir, { recursive: true });
|
|
7525
8774
|
console.log("\u{1F4C1} \u0110\xE3 t\u1EA1o th\u01B0 m\u1EE5c .vscode/");
|
|
7526
8775
|
}
|
|
7527
8776
|
let currentSettings = {};
|
|
7528
|
-
if (
|
|
8777
|
+
if (existsSync3(settingsPath)) {
|
|
7529
8778
|
try {
|
|
7530
|
-
const content = await
|
|
8779
|
+
const content = await fs10.readFile(settingsPath, "utf-8");
|
|
7531
8780
|
currentSettings = JSON.parse(content);
|
|
7532
8781
|
console.log("\u{1F4C4} \u0110\xE3 \u0111\u1ECDc c\xE0i \u0111\u1EB7t hi\u1EC7n t\u1EA1i t\u1EEB settings.json");
|
|
7533
8782
|
} catch {
|
|
@@ -7567,15 +8816,15 @@ async function applyGroups2(groupKeys, action) {
|
|
|
7567
8816
|
}
|
|
7568
8817
|
}
|
|
7569
8818
|
}
|
|
7570
|
-
await
|
|
8819
|
+
await fs10.writeFile(settingsPath, JSON.stringify(newSettings, null, 2));
|
|
7571
8820
|
console.log(`
|
|
7572
8821
|
\u2705 \u0110\xE3 c\u1EADp nh\u1EADt c\xE0i \u0111\u1EB7t VSCode t\u1EA1i: ${settingsPath}`);
|
|
7573
8822
|
console.log("\u{1F4A1} M\u1EB9o: Kh\u1EDFi \u0111\u1ED9ng l\u1EA1i VSCode \u0111\u1EC3 \xE1p d\u1EE5ng c\xE1c thay \u0111\u1ED5i.");
|
|
7574
8823
|
}
|
|
7575
8824
|
async function resetSettings2(groupKeys) {
|
|
7576
|
-
const vscodeDir =
|
|
7577
|
-
const settingsPath =
|
|
7578
|
-
if (!
|
|
8825
|
+
const vscodeDir = path6.join(process.cwd(), ".vscode");
|
|
8826
|
+
const settingsPath = path6.join(vscodeDir, "settings.json");
|
|
8827
|
+
if (!existsSync3(settingsPath)) {
|
|
7579
8828
|
console.log("\n\u26A0\uFE0F Kh\xF4ng t\xECm th\u1EA5y file settings.json");
|
|
7580
8829
|
return;
|
|
7581
8830
|
}
|
|
@@ -7588,7 +8837,7 @@ async function resetSettings2(groupKeys) {
|
|
|
7588
8837
|
return;
|
|
7589
8838
|
}
|
|
7590
8839
|
if (groupKeys.length === 0) {
|
|
7591
|
-
await
|
|
8840
|
+
await fs10.unlink(settingsPath);
|
|
7592
8841
|
console.log("\n\u2705 \u0110\xE3 x\xF3a file settings.json");
|
|
7593
8842
|
} else {
|
|
7594
8843
|
await applyGroups2(groupKeys, "disable");
|
|
@@ -7597,13 +8846,13 @@ async function resetSettings2(groupKeys) {
|
|
|
7597
8846
|
}
|
|
7598
8847
|
|
|
7599
8848
|
// src/commands/guide.ts
|
|
7600
|
-
import
|
|
8849
|
+
import React40 from "react";
|
|
7601
8850
|
import { render as render6 } from "ink";
|
|
7602
8851
|
import { Command as Command37 } from "commander";
|
|
7603
8852
|
function createGuideCommand() {
|
|
7604
8853
|
const cmd = new Command37("guide").description("Interactive guide center for Agentic Coding").option("--topic <topic>", "Open specific topic (intro, rules, workflows, prompts, skills)").action(async (options) => {
|
|
7605
8854
|
const { waitUntilExit } = render6(
|
|
7606
|
-
|
|
8855
|
+
React40.createElement(GuideApp, {
|
|
7607
8856
|
initialTopic: options.topic,
|
|
7608
8857
|
onExit: () => {
|
|
7609
8858
|
process.exit(0);
|
|
@@ -7616,7 +8865,7 @@ function createGuideCommand() {
|
|
|
7616
8865
|
}
|
|
7617
8866
|
|
|
7618
8867
|
// src/commands/context.ts
|
|
7619
|
-
import
|
|
8868
|
+
import React41 from "react";
|
|
7620
8869
|
import { render as render7 } from "ink";
|
|
7621
8870
|
import { Command as Command38 } from "commander";
|
|
7622
8871
|
function createContextCommand() {
|
|
@@ -7646,7 +8895,7 @@ function createContextCommand() {
|
|
|
7646
8895
|
return;
|
|
7647
8896
|
}
|
|
7648
8897
|
const { waitUntilExit } = render7(
|
|
7649
|
-
|
|
8898
|
+
React41.createElement(ContextApp, {
|
|
7650
8899
|
initialIDE,
|
|
7651
8900
|
initialType,
|
|
7652
8901
|
onExit: () => {
|