@jvittechs/jai1-cli 0.1.67 → 0.1.69
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 +1047 -70
- 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.69",
|
|
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,12 @@ 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
|
|
5725
|
-
import { Box as
|
|
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
5726
|
|
|
5727
5727
|
// src/ui/utils/views/PasswordView.tsx
|
|
5728
5728
|
import React27, { useState as useState14 } from "react";
|
|
@@ -5981,6 +5981,966 @@ var HashView = () => {
|
|
|
5981
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
5982
|
};
|
|
5983
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
|
+
|
|
5984
6944
|
// src/ui/utils/UtilsApp.tsx
|
|
5985
6945
|
var MENU_ITEMS2 = [
|
|
5986
6946
|
{ id: "password", icon: "\u{1F510}", label: "Password", description: "Generate secure passwords" },
|
|
@@ -5998,10 +6958,10 @@ var MENU_ITEMS2 = [
|
|
|
5998
6958
|
{ id: "markdown", icon: "\u{1F4C4}", label: "Markdown", description: "Preview markdown" }
|
|
5999
6959
|
];
|
|
6000
6960
|
var UtilsApp = ({ onExit }) => {
|
|
6001
|
-
const [selectedIndex, setSelectedIndex] =
|
|
6002
|
-
const [activeView, setActiveView] =
|
|
6961
|
+
const [selectedIndex, setSelectedIndex] = useState25(0);
|
|
6962
|
+
const [activeView, setActiveView] = useState25(null);
|
|
6003
6963
|
const { exit } = useApp5();
|
|
6004
|
-
|
|
6964
|
+
useInput23((input, key) => {
|
|
6005
6965
|
if (activeView) {
|
|
6006
6966
|
if (key.escape) {
|
|
6007
6967
|
setActiveView(null);
|
|
@@ -6019,8 +6979,8 @@ var UtilsApp = ({ onExit }) => {
|
|
|
6019
6979
|
exit();
|
|
6020
6980
|
}
|
|
6021
6981
|
});
|
|
6022
|
-
return /* @__PURE__ */
|
|
6023
|
-
|
|
6982
|
+
return /* @__PURE__ */ React38.createElement(Box28, { flexDirection: "column", width: "100%", height: "100%" }, /* @__PURE__ */ React38.createElement(
|
|
6983
|
+
Box28,
|
|
6024
6984
|
{
|
|
6025
6985
|
borderStyle: "single",
|
|
6026
6986
|
borderColor: "cyan",
|
|
@@ -6028,10 +6988,10 @@ var UtilsApp = ({ onExit }) => {
|
|
|
6028
6988
|
paddingY: 0,
|
|
6029
6989
|
marginBottom: 1
|
|
6030
6990
|
},
|
|
6031
|
-
/* @__PURE__ */
|
|
6032
|
-
/* @__PURE__ */
|
|
6033
|
-
), /* @__PURE__ */
|
|
6034
|
-
|
|
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,
|
|
6035
6995
|
{
|
|
6036
6996
|
flexDirection: "column",
|
|
6037
6997
|
width: 30,
|
|
@@ -6041,9 +7001,9 @@ var UtilsApp = ({ onExit }) => {
|
|
|
6041
7001
|
paddingY: 1,
|
|
6042
7002
|
marginRight: 1
|
|
6043
7003
|
},
|
|
6044
|
-
/* @__PURE__ */
|
|
6045
|
-
MENU_ITEMS2.map((item, index) => /* @__PURE__ */
|
|
6046
|
-
|
|
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,
|
|
6047
7007
|
{
|
|
6048
7008
|
color: selectedIndex === index && !activeView ? "green" : void 0,
|
|
6049
7009
|
bold: selectedIndex === index && !activeView,
|
|
@@ -6054,9 +7014,9 @@ var UtilsApp = ({ onExit }) => {
|
|
|
6054
7014
|
" ",
|
|
6055
7015
|
item.label
|
|
6056
7016
|
))),
|
|
6057
|
-
/* @__PURE__ */
|
|
6058
|
-
), /* @__PURE__ */
|
|
6059
|
-
|
|
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,
|
|
6060
7020
|
{
|
|
6061
7021
|
flexDirection: "column",
|
|
6062
7022
|
flexGrow: 1,
|
|
@@ -6065,21 +7025,21 @@ var UtilsApp = ({ onExit }) => {
|
|
|
6065
7025
|
paddingX: 2,
|
|
6066
7026
|
paddingY: 1
|
|
6067
7027
|
},
|
|
6068
|
-
activeView ? /* @__PURE__ */
|
|
6069
|
-
)), /* @__PURE__ */
|
|
6070
|
-
|
|
7028
|
+
activeView ? /* @__PURE__ */ React38.createElement(ActiveUtilityView, { utilityType: activeView }) : /* @__PURE__ */ React38.createElement(WelcomeView, { selectedItem: MENU_ITEMS2[selectedIndex] })
|
|
7029
|
+
)), /* @__PURE__ */ React38.createElement(
|
|
7030
|
+
Box28,
|
|
6071
7031
|
{
|
|
6072
7032
|
borderStyle: "single",
|
|
6073
7033
|
borderColor: "gray",
|
|
6074
7034
|
paddingX: 2,
|
|
6075
7035
|
marginTop: 1
|
|
6076
7036
|
},
|
|
6077
|
-
/* @__PURE__ */
|
|
7037
|
+
/* @__PURE__ */ React38.createElement(Text29, { dimColor: true }, "jai1-cli | Use arrow keys or j/k to navigate")
|
|
6078
7038
|
));
|
|
6079
7039
|
};
|
|
6080
7040
|
var WelcomeView = ({ selectedItem }) => {
|
|
6081
|
-
return /* @__PURE__ */
|
|
6082
|
-
|
|
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,
|
|
6083
7043
|
{
|
|
6084
7044
|
borderStyle: "single",
|
|
6085
7045
|
borderColor: "yellow",
|
|
@@ -6087,40 +7047,57 @@ var WelcomeView = ({ selectedItem }) => {
|
|
|
6087
7047
|
paddingY: 1,
|
|
6088
7048
|
marginBottom: 2
|
|
6089
7049
|
},
|
|
6090
|
-
/* @__PURE__ */
|
|
6091
|
-
), /* @__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.")));
|
|
6092
7052
|
};
|
|
6093
7053
|
var ActiveUtilityView = ({ utilityType }) => {
|
|
6094
7054
|
switch (utilityType) {
|
|
6095
7055
|
case "password":
|
|
6096
|
-
return /* @__PURE__ */
|
|
7056
|
+
return /* @__PURE__ */ React38.createElement(PasswordView, null);
|
|
6097
7057
|
case "uuid":
|
|
6098
|
-
return /* @__PURE__ */
|
|
7058
|
+
return /* @__PURE__ */ React38.createElement(UuidView, null);
|
|
6099
7059
|
case "hash":
|
|
6100
|
-
return /* @__PURE__ */
|
|
6101
|
-
|
|
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);
|
|
6102
7079
|
default:
|
|
6103
|
-
return /* @__PURE__ */
|
|
7080
|
+
return /* @__PURE__ */ React38.createElement(PlaceholderView, { utilityType });
|
|
6104
7081
|
}
|
|
6105
7082
|
};
|
|
6106
7083
|
var PlaceholderView = ({ utilityType }) => {
|
|
6107
7084
|
const item = MENU_ITEMS2.find((m) => m.id === utilityType);
|
|
6108
|
-
return /* @__PURE__ */
|
|
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.")));
|
|
6109
7086
|
};
|
|
6110
7087
|
|
|
6111
7088
|
// src/commands/utils/interactive.ts
|
|
6112
7089
|
async function runInteractiveMode() {
|
|
6113
|
-
return new Promise((
|
|
7090
|
+
return new Promise((resolve4) => {
|
|
6114
7091
|
const { unmount, waitUntilExit } = render5(
|
|
6115
|
-
|
|
7092
|
+
React39.createElement(UtilsApp, {
|
|
6116
7093
|
onExit: () => {
|
|
6117
7094
|
unmount();
|
|
6118
|
-
|
|
7095
|
+
resolve4();
|
|
6119
7096
|
}
|
|
6120
7097
|
})
|
|
6121
7098
|
);
|
|
6122
7099
|
waitUntilExit().then(() => {
|
|
6123
|
-
|
|
7100
|
+
resolve4();
|
|
6124
7101
|
});
|
|
6125
7102
|
});
|
|
6126
7103
|
}
|
|
@@ -6443,7 +7420,7 @@ import { Command as Command30 } from "commander";
|
|
|
6443
7420
|
|
|
6444
7421
|
// src/services/redmine-config.service.ts
|
|
6445
7422
|
import { readFile as readFile6 } from "fs/promises";
|
|
6446
|
-
import { resolve } from "path";
|
|
7423
|
+
import { resolve as resolve2 } from "path";
|
|
6447
7424
|
|
|
6448
7425
|
// src/types/redmine.types.ts
|
|
6449
7426
|
import { z } from "zod";
|
|
@@ -6494,7 +7471,7 @@ import { z as z2 } from "zod";
|
|
|
6494
7471
|
var RedmineConfigService = class {
|
|
6495
7472
|
configPath;
|
|
6496
7473
|
constructor(configPath) {
|
|
6497
|
-
this.configPath = configPath ??
|
|
7474
|
+
this.configPath = configPath ?? resolve2(process.cwd(), "redmine.config.yaml");
|
|
6498
7475
|
}
|
|
6499
7476
|
/**
|
|
6500
7477
|
* Load Redmine configuration from YAML file
|
|
@@ -6560,8 +7537,8 @@ var RedmineApiClient = class {
|
|
|
6560
7537
|
this.retryConfig = config.defaults.retry;
|
|
6561
7538
|
this.concurrencyLimit = pLimit2(config.defaults.concurrency);
|
|
6562
7539
|
}
|
|
6563
|
-
async request(
|
|
6564
|
-
const url = `${this.baseUrl}${
|
|
7540
|
+
async request(path7, options = {}) {
|
|
7541
|
+
const url = `${this.baseUrl}${path7}`;
|
|
6565
7542
|
const headers = {
|
|
6566
7543
|
"X-Redmine-API-Key": this.apiAccessToken,
|
|
6567
7544
|
"Content-Type": "application/json",
|
|
@@ -6622,8 +7599,8 @@ var RedmineApiClient = class {
|
|
|
6622
7599
|
if (include && include.length > 0) {
|
|
6623
7600
|
params.append("include", include.join(","));
|
|
6624
7601
|
}
|
|
6625
|
-
const
|
|
6626
|
-
return this.request(
|
|
7602
|
+
const path7 = `/issues/${issueId}.json${params.toString() ? `?${params.toString()}` : ""}`;
|
|
7603
|
+
return this.request(path7);
|
|
6627
7604
|
}
|
|
6628
7605
|
async getIssues(projectId, options = {}) {
|
|
6629
7606
|
const params = new URLSearchParams();
|
|
@@ -6643,8 +7620,8 @@ var RedmineApiClient = class {
|
|
|
6643
7620
|
if (options.updatedSince) {
|
|
6644
7621
|
params.append("updated_on", `>=${options.updatedSince}`);
|
|
6645
7622
|
}
|
|
6646
|
-
const
|
|
6647
|
-
return this.request(
|
|
7623
|
+
const path7 = `/issues.json?${params.toString()}`;
|
|
7624
|
+
return this.request(path7);
|
|
6648
7625
|
}
|
|
6649
7626
|
async getAllIssues(projectId, options = {}) {
|
|
6650
7627
|
const pageSize = options.pageSize || 100;
|
|
@@ -6777,7 +7754,7 @@ async function handleRedmineCheck(options) {
|
|
|
6777
7754
|
import { Command as Command31 } from "commander";
|
|
6778
7755
|
|
|
6779
7756
|
// src/sync-issue.ts
|
|
6780
|
-
import { resolve as
|
|
7757
|
+
import { resolve as resolve3, relative } from "path";
|
|
6781
7758
|
|
|
6782
7759
|
// src/mappers.ts
|
|
6783
7760
|
function mapIssueToFrontmatter(issue) {
|
|
@@ -7037,7 +8014,7 @@ async function syncIssue(issueId, config, options = {}) {
|
|
|
7037
8014
|
const response = await client.getIssue(issueId, include);
|
|
7038
8015
|
const issue = response.issue;
|
|
7039
8016
|
const filename = generateFilename(issue.id, issue.subject, config.filename);
|
|
7040
|
-
const filePath =
|
|
8017
|
+
const filePath = resolve3(outputDir, filename);
|
|
7041
8018
|
const relativePath = relative(process.cwd(), filePath);
|
|
7042
8019
|
const existingFile = await readMarkdownFile(filePath);
|
|
7043
8020
|
const existingIssueId = extractIssueIdFromFrontmatter(existingFile.frontmatter);
|
|
@@ -7320,7 +8297,7 @@ async function handleSyncProject(options) {
|
|
|
7320
8297
|
|
|
7321
8298
|
// src/commands/framework/info.ts
|
|
7322
8299
|
import { Command as Command33 } from "commander";
|
|
7323
|
-
import { promises as
|
|
8300
|
+
import { promises as fs9 } from "fs";
|
|
7324
8301
|
import { join as join5 } from "path";
|
|
7325
8302
|
import { homedir as homedir5 } from "os";
|
|
7326
8303
|
function createInfoCommand() {
|
|
@@ -7372,7 +8349,7 @@ function maskKey3(key) {
|
|
|
7372
8349
|
async function getProjectStatus2() {
|
|
7373
8350
|
const projectJai1 = join5(process.cwd(), ".jai1");
|
|
7374
8351
|
try {
|
|
7375
|
-
await
|
|
8352
|
+
await fs9.access(projectJai1);
|
|
7376
8353
|
return { exists: true, version: "Synced" };
|
|
7377
8354
|
} catch {
|
|
7378
8355
|
return { exists: false };
|
|
@@ -7562,9 +8539,9 @@ function createClearBackupsCommand() {
|
|
|
7562
8539
|
// src/commands/vscode/index.ts
|
|
7563
8540
|
import { Command as Command36 } from "commander";
|
|
7564
8541
|
import { checkbox as checkbox3, confirm as confirm8, select as select3 } from "@inquirer/prompts";
|
|
7565
|
-
import
|
|
7566
|
-
import
|
|
7567
|
-
import { existsSync as
|
|
8542
|
+
import fs10 from "fs/promises";
|
|
8543
|
+
import path6 from "path";
|
|
8544
|
+
import { existsSync as existsSync3 } from "fs";
|
|
7568
8545
|
var PERFORMANCE_GROUPS2 = {
|
|
7569
8546
|
telemetry: {
|
|
7570
8547
|
name: "Telemetry",
|
|
@@ -7783,8 +8760,8 @@ async function selectGroupsToApply2(action) {
|
|
|
7783
8760
|
}
|
|
7784
8761
|
}
|
|
7785
8762
|
async function applyGroups2(groupKeys, action) {
|
|
7786
|
-
const vscodeDir =
|
|
7787
|
-
const settingsPath =
|
|
8763
|
+
const vscodeDir = path6.join(process.cwd(), ".vscode");
|
|
8764
|
+
const settingsPath = path6.join(vscodeDir, "settings.json");
|
|
7788
8765
|
const invalidGroups = groupKeys.filter((key) => !PERFORMANCE_GROUPS2[key]);
|
|
7789
8766
|
if (invalidGroups.length > 0) {
|
|
7790
8767
|
console.log(`
|
|
@@ -7792,14 +8769,14 @@ async function applyGroups2(groupKeys, action) {
|
|
|
7792
8769
|
console.log(' \u{1F4A1} Ch\u1EA1y "jai1 vscode list" \u0111\u1EC3 xem danh s\xE1ch nh\xF3m c\xF3 s\u1EB5n.');
|
|
7793
8770
|
return;
|
|
7794
8771
|
}
|
|
7795
|
-
if (!
|
|
7796
|
-
await
|
|
8772
|
+
if (!existsSync3(vscodeDir)) {
|
|
8773
|
+
await fs10.mkdir(vscodeDir, { recursive: true });
|
|
7797
8774
|
console.log("\u{1F4C1} \u0110\xE3 t\u1EA1o th\u01B0 m\u1EE5c .vscode/");
|
|
7798
8775
|
}
|
|
7799
8776
|
let currentSettings = {};
|
|
7800
|
-
if (
|
|
8777
|
+
if (existsSync3(settingsPath)) {
|
|
7801
8778
|
try {
|
|
7802
|
-
const content = await
|
|
8779
|
+
const content = await fs10.readFile(settingsPath, "utf-8");
|
|
7803
8780
|
currentSettings = JSON.parse(content);
|
|
7804
8781
|
console.log("\u{1F4C4} \u0110\xE3 \u0111\u1ECDc c\xE0i \u0111\u1EB7t hi\u1EC7n t\u1EA1i t\u1EEB settings.json");
|
|
7805
8782
|
} catch {
|
|
@@ -7839,15 +8816,15 @@ async function applyGroups2(groupKeys, action) {
|
|
|
7839
8816
|
}
|
|
7840
8817
|
}
|
|
7841
8818
|
}
|
|
7842
|
-
await
|
|
8819
|
+
await fs10.writeFile(settingsPath, JSON.stringify(newSettings, null, 2));
|
|
7843
8820
|
console.log(`
|
|
7844
8821
|
\u2705 \u0110\xE3 c\u1EADp nh\u1EADt c\xE0i \u0111\u1EB7t VSCode t\u1EA1i: ${settingsPath}`);
|
|
7845
8822
|
console.log("\u{1F4A1} M\u1EB9o: Kh\u1EDFi \u0111\u1ED9ng l\u1EA1i VSCode \u0111\u1EC3 \xE1p d\u1EE5ng c\xE1c thay \u0111\u1ED5i.");
|
|
7846
8823
|
}
|
|
7847
8824
|
async function resetSettings2(groupKeys) {
|
|
7848
|
-
const vscodeDir =
|
|
7849
|
-
const settingsPath =
|
|
7850
|
-
if (!
|
|
8825
|
+
const vscodeDir = path6.join(process.cwd(), ".vscode");
|
|
8826
|
+
const settingsPath = path6.join(vscodeDir, "settings.json");
|
|
8827
|
+
if (!existsSync3(settingsPath)) {
|
|
7851
8828
|
console.log("\n\u26A0\uFE0F Kh\xF4ng t\xECm th\u1EA5y file settings.json");
|
|
7852
8829
|
return;
|
|
7853
8830
|
}
|
|
@@ -7860,7 +8837,7 @@ async function resetSettings2(groupKeys) {
|
|
|
7860
8837
|
return;
|
|
7861
8838
|
}
|
|
7862
8839
|
if (groupKeys.length === 0) {
|
|
7863
|
-
await
|
|
8840
|
+
await fs10.unlink(settingsPath);
|
|
7864
8841
|
console.log("\n\u2705 \u0110\xE3 x\xF3a file settings.json");
|
|
7865
8842
|
} else {
|
|
7866
8843
|
await applyGroups2(groupKeys, "disable");
|
|
@@ -7869,13 +8846,13 @@ async function resetSettings2(groupKeys) {
|
|
|
7869
8846
|
}
|
|
7870
8847
|
|
|
7871
8848
|
// src/commands/guide.ts
|
|
7872
|
-
import
|
|
8849
|
+
import React40 from "react";
|
|
7873
8850
|
import { render as render6 } from "ink";
|
|
7874
8851
|
import { Command as Command37 } from "commander";
|
|
7875
8852
|
function createGuideCommand() {
|
|
7876
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) => {
|
|
7877
8854
|
const { waitUntilExit } = render6(
|
|
7878
|
-
|
|
8855
|
+
React40.createElement(GuideApp, {
|
|
7879
8856
|
initialTopic: options.topic,
|
|
7880
8857
|
onExit: () => {
|
|
7881
8858
|
process.exit(0);
|
|
@@ -7888,7 +8865,7 @@ function createGuideCommand() {
|
|
|
7888
8865
|
}
|
|
7889
8866
|
|
|
7890
8867
|
// src/commands/context.ts
|
|
7891
|
-
import
|
|
8868
|
+
import React41 from "react";
|
|
7892
8869
|
import { render as render7 } from "ink";
|
|
7893
8870
|
import { Command as Command38 } from "commander";
|
|
7894
8871
|
function createContextCommand() {
|
|
@@ -7918,7 +8895,7 @@ function createContextCommand() {
|
|
|
7918
8895
|
return;
|
|
7919
8896
|
}
|
|
7920
8897
|
const { waitUntilExit } = render7(
|
|
7921
|
-
|
|
8898
|
+
React41.createElement(ContextApp, {
|
|
7922
8899
|
initialIDE,
|
|
7923
8900
|
initialType,
|
|
7924
8901
|
onExit: () => {
|