ccjk 2.6.2 → 3.0.3
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/chunks/agent.mjs +1412 -0
- package/dist/chunks/api.mjs +7 -7
- package/dist/chunks/auto-updater.mjs +9 -9
- package/dist/chunks/ccr.mjs +4 -4
- package/dist/chunks/ccu.mjs +1 -1
- package/dist/chunks/claude-code-incremental-manager.mjs +6 -6
- package/dist/chunks/codex.mjs +4 -4
- package/dist/chunks/commands2.mjs +5 -5
- package/dist/chunks/commit.mjs +2 -2
- package/dist/chunks/config-consolidator.mjs +2 -2
- package/dist/chunks/config-switch.mjs +6 -6
- package/dist/chunks/config.mjs +1 -1
- package/dist/chunks/config2.mjs +14 -14
- package/dist/chunks/doctor.mjs +4 -14
- package/dist/chunks/features.mjs +12 -12
- package/dist/chunks/help.mjs +35 -35
- package/dist/chunks/index.mjs +11 -11
- package/dist/chunks/init.mjs +21 -21
- package/dist/chunks/interview.mjs +33 -33
- package/dist/chunks/marketplace.mjs +8 -8
- package/dist/chunks/mcp.mjs +8 -8
- package/dist/chunks/menu.mjs +302 -293
- package/dist/chunks/notification.mjs +5 -5
- package/dist/chunks/onboarding.mjs +7 -7
- package/dist/chunks/package.mjs +1 -1
- package/dist/chunks/permission-manager.mjs +3 -3
- package/dist/chunks/plugin.mjs +24 -24
- package/dist/chunks/prompts.mjs +3 -3
- package/dist/chunks/providers.mjs +13 -13
- package/dist/chunks/session.mjs +17 -17
- package/dist/chunks/skill.mjs +304 -0
- package/dist/chunks/skills-sync.mjs +4 -4
- package/dist/chunks/skills.mjs +2 -2
- package/dist/chunks/team.mjs +1 -1
- package/dist/chunks/uninstall.mjs +8 -8
- package/dist/chunks/update.mjs +4 -4
- package/dist/chunks/upgrade-manager.mjs +3 -3
- package/dist/chunks/version-checker.mjs +6 -6
- package/dist/chunks/workflows.mjs +2 -2
- package/dist/cli.mjs +48 -0
- package/dist/i18n/locales/en/workspace.json +1 -0
- package/dist/i18n/locales/zh-CN/workspace.json +1 -0
- package/dist/index.d.mts +157 -14
- package/dist/index.d.ts +157 -14
- package/dist/index.mjs +4 -4
- package/dist/shared/{ccjk.rLRHmcqD.mjs → ccjk.BQzWKmC3.mjs} +3 -3
- package/dist/shared/{ccjk.uVUeWAt8.mjs → ccjk.BZT_f2go.mjs} +7 -7
- package/dist/shared/{ccjk.-FoZ3zat.mjs → ccjk.BlPCiSHj.mjs} +10 -10
- package/dist/shared/ccjk.DH6cOJsf.mjs +1674 -0
- package/dist/shared/{ccjk.tB4-Y4Qb.mjs → ccjk.DrMygfCF.mjs} +1 -1
- package/dist/shared/ccjk.tJ08-yZt.mjs +179 -0
- package/package.json +1 -1
- package/dist/shared/ccjk.BhKlRJ0h.mjs +0 -114
|
@@ -6,7 +6,7 @@ function handleExitPromptError(error) {
|
|
|
6
6
|
const isExitError = error instanceof Error && (error.name === "ExitPromptError" || error.message?.includes("ExitPromptError") || error.message?.includes("User force closed the prompt"));
|
|
7
7
|
if (isExitError) {
|
|
8
8
|
ensureI18nInitialized();
|
|
9
|
-
console.log(ansis.
|
|
9
|
+
console.log(ansis.green(`
|
|
10
10
|
${i18n.t("common:goodbye")}
|
|
11
11
|
`));
|
|
12
12
|
process__default.exit(0);
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import ansis from 'ansis';
|
|
2
|
+
import { homepage, version } from '../chunks/package.mjs';
|
|
3
|
+
import { ensureI18nInitialized, i18n } from '../chunks/index2.mjs';
|
|
4
|
+
|
|
5
|
+
const theme = {
|
|
6
|
+
// === Core Colors ===
|
|
7
|
+
/** Terminal green - main text color */
|
|
8
|
+
primary: ansis.hex("#00FF00"),
|
|
9
|
+
/** Bright white - emphasis and highlights */
|
|
10
|
+
secondary: ansis.white,
|
|
11
|
+
/** Dim green - subtle accents */
|
|
12
|
+
accent: ansis.hex("#00CC00"),
|
|
13
|
+
// === Semantic Colors ===
|
|
14
|
+
/** Success - bright green checkmark */
|
|
15
|
+
success: ansis.hex("#00FF7F"),
|
|
16
|
+
/** Warning - amber/yellow for caution */
|
|
17
|
+
warning: ansis.hex("#FFD700"),
|
|
18
|
+
/** Error - red for failures */
|
|
19
|
+
error: ansis.hex("#FF4444"),
|
|
20
|
+
/** Info - cyan for informational messages */
|
|
21
|
+
info: ansis.hex("#00FFFF"),
|
|
22
|
+
// === Text Styles ===
|
|
23
|
+
/** Muted text - gray for less important info */
|
|
24
|
+
muted: ansis.gray,
|
|
25
|
+
/** Bold text */
|
|
26
|
+
bold: ansis.bold,
|
|
27
|
+
/** Dim text - for background info */
|
|
28
|
+
dim: ansis.dim,
|
|
29
|
+
// === MUD-specific Styles ===
|
|
30
|
+
/** Command prompt style - bright green */
|
|
31
|
+
prompt: ansis.hex("#00FF00").bold,
|
|
32
|
+
/** System message - white */
|
|
33
|
+
system: ansis.white,
|
|
34
|
+
/** NPC/hint text - dim green */
|
|
35
|
+
hint: ansis.hex("#88CC88"),
|
|
36
|
+
/** Quest/task highlight - bright */
|
|
37
|
+
quest: ansis.hex("#00FF00").bold,
|
|
38
|
+
/** Item/feature name - white bold */
|
|
39
|
+
item: ansis.white.bold
|
|
40
|
+
};
|
|
41
|
+
const status = {
|
|
42
|
+
/** ✓ Success indicator */
|
|
43
|
+
ok: (text) => `${ansis.green("\u2713")} ${text}`,
|
|
44
|
+
/** ✗ Error indicator */
|
|
45
|
+
fail: (text) => `${ansis.red("\u2717")} ${text}`,
|
|
46
|
+
/** ⚠ Warning indicator */
|
|
47
|
+
warn: (text) => `${ansis.yellow("\u26A0")} ${text}`,
|
|
48
|
+
/** ℹ Info indicator */
|
|
49
|
+
info: (text) => `${ansis.cyan("\u2139")} ${text}`,
|
|
50
|
+
/** ○ Pending indicator */
|
|
51
|
+
wait: (text) => `${ansis.gray("\u25CB")} ${text}`,
|
|
52
|
+
/** ◐ In-progress indicator */
|
|
53
|
+
work: (text) => `${ansis.green("\u25D0")} ${text}`,
|
|
54
|
+
/** → Arrow indicator */
|
|
55
|
+
step: (text) => `${ansis.green("\u2192")} ${text}`,
|
|
56
|
+
/** • Bullet point */
|
|
57
|
+
dot: (text) => `${ansis.green("\u2022")} ${text}`
|
|
58
|
+
};
|
|
59
|
+
const box = {
|
|
60
|
+
single: { tl: "\u250C", tr: "\u2510", bl: "\u2514", br: "\u2518", h: "\u2500", v: "\u2502" },
|
|
61
|
+
double: { tl: "\u2554", tr: "\u2557", bl: "\u255A", br: "\u255D", h: "\u2550", v: "\u2551" },
|
|
62
|
+
rounded: { tl: "\u256D", tr: "\u256E", bl: "\u2570", br: "\u256F", h: "\u2500", v: "\u2502" },
|
|
63
|
+
heavy: { tl: "\u250F", tr: "\u2513", bl: "\u2517", br: "\u251B", h: "\u2501", v: "\u2503" }
|
|
64
|
+
};
|
|
65
|
+
function menuItem(key, label, desc) {
|
|
66
|
+
const keyPart = theme.primary.bold(`[${key}]`);
|
|
67
|
+
const labelPart = theme.secondary(label);
|
|
68
|
+
const descPart = desc ? theme.muted(` - ${desc}`) : "";
|
|
69
|
+
return ` ${keyPart} ${labelPart}${descPart}`;
|
|
70
|
+
}
|
|
71
|
+
function header(title, width = 50) {
|
|
72
|
+
const titleLen = title.length + 2;
|
|
73
|
+
const sideLen = Math.floor((width - titleLen) / 2);
|
|
74
|
+
const line = "\u2550".repeat(sideLen);
|
|
75
|
+
return theme.primary(`${line} ${theme.secondary.bold(title)} ${line}`);
|
|
76
|
+
}
|
|
77
|
+
function divider(width = 50, char = "\u2500") {
|
|
78
|
+
return theme.muted(char.repeat(width));
|
|
79
|
+
}
|
|
80
|
+
function progress(percent, width = 30) {
|
|
81
|
+
const filled = Math.round(percent / 100 * width);
|
|
82
|
+
const empty = width - filled;
|
|
83
|
+
const bar = theme.primary("\u2588".repeat(filled)) + theme.muted("\u2591".repeat(empty));
|
|
84
|
+
const pct = `${Math.round(percent)}%`.padStart(4);
|
|
85
|
+
return `[${bar}] ${theme.secondary(pct)}`;
|
|
86
|
+
}
|
|
87
|
+
function boxify(content, style = "double", title) {
|
|
88
|
+
const chars = box[style];
|
|
89
|
+
const lines = content.split("\n");
|
|
90
|
+
const getWidth = (s) => {
|
|
91
|
+
let w = 0;
|
|
92
|
+
for (const c of s) {
|
|
93
|
+
w += c.match(/[\u4E00-\u9FFF\uFF01-\uFF60\u3000-\u303F]/) ? 2 : 1;
|
|
94
|
+
}
|
|
95
|
+
return w;
|
|
96
|
+
};
|
|
97
|
+
const maxWidth = Math.max(
|
|
98
|
+
...lines.map(getWidth),
|
|
99
|
+
title ? getWidth(title) + 4 : 0
|
|
100
|
+
);
|
|
101
|
+
const paddedLines = lines.map((line) => {
|
|
102
|
+
const padding = maxWidth - getWidth(line);
|
|
103
|
+
return `${chars.v} ${line}${" ".repeat(padding)} ${chars.v}`;
|
|
104
|
+
});
|
|
105
|
+
let topBorder = `${chars.tl}${chars.h.repeat(maxWidth + 2)}${chars.tr}`;
|
|
106
|
+
if (title) {
|
|
107
|
+
const pad = Math.floor((maxWidth - getWidth(title)) / 2);
|
|
108
|
+
topBorder = `${chars.tl}${chars.h.repeat(pad)} ${title} ${chars.h.repeat(maxWidth - pad - getWidth(title))}${chars.tr}`;
|
|
109
|
+
}
|
|
110
|
+
const bottomBorder = `${chars.bl}${chars.h.repeat(maxWidth + 2)}${chars.br}`;
|
|
111
|
+
return theme.primary([topBorder, ...paddedLines, bottomBorder].join("\n"));
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function getDisplayWidth(str) {
|
|
115
|
+
let width = 0;
|
|
116
|
+
for (const char of str) {
|
|
117
|
+
if (char.match(/[\u4E00-\u9FFF\uFF01-\uFF60\u3000-\u303F]/)) {
|
|
118
|
+
width += 2;
|
|
119
|
+
} else {
|
|
120
|
+
width += 1;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return width;
|
|
124
|
+
}
|
|
125
|
+
function padToDisplayWidth(str, targetWidth) {
|
|
126
|
+
const currentWidth = getDisplayWidth(str);
|
|
127
|
+
const paddingNeeded = Math.max(0, targetWidth - currentWidth);
|
|
128
|
+
return str + " ".repeat(paddingNeeded);
|
|
129
|
+
}
|
|
130
|
+
function displayBanner(subtitle) {
|
|
131
|
+
ensureI18nInitialized();
|
|
132
|
+
const defaultSubtitle = i18n.t("cli:banner.subtitle");
|
|
133
|
+
const subtitleText = subtitle || defaultSubtitle;
|
|
134
|
+
const paddedSubtitle = padToDisplayWidth(subtitleText, 28);
|
|
135
|
+
console.log(
|
|
136
|
+
ansis.green.bold(`
|
|
137
|
+
\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
|
|
138
|
+
\u2551 \u2551
|
|
139
|
+
\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2557 \u2551
|
|
140
|
+
\u2551 \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2554\u255D \u2551
|
|
141
|
+
\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2554\u255D ${ansis.white.bold("JinKu")} \u2551
|
|
142
|
+
\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2588\u2588\u2557 ${ansis.gray(`v${version}`)}${" ".repeat(Math.max(0, 17 - version.length))}\u2551
|
|
143
|
+
\u2551 \u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u255A\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551 \u2588\u2588\u2557 \u2551
|
|
144
|
+
\u2551 \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D ${ansis.gray(paddedSubtitle)} \u2551
|
|
145
|
+
\u2551 \u2551
|
|
146
|
+
\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
|
|
147
|
+
`)
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
function displayBannerWithInfo(subtitle) {
|
|
151
|
+
displayBanner(subtitle);
|
|
152
|
+
console.log(ansis.gray(` ${ansis.green("ccjk")} - Advanced AI Development Assistant`));
|
|
153
|
+
console.log(ansis.gray(` ${ansis.green(homepage)}
|
|
154
|
+
`));
|
|
155
|
+
}
|
|
156
|
+
function renderProgressBar(pct, width = 30) {
|
|
157
|
+
const filled = Math.round(pct / 100 * width);
|
|
158
|
+
const empty = width - filled;
|
|
159
|
+
const bar = theme.primary("\u2588".repeat(filled)) + ansis.gray("\u2591".repeat(empty));
|
|
160
|
+
const percentage = `${Math.round(pct)}%`.padStart(4);
|
|
161
|
+
return `[${bar}] ${theme.secondary(percentage)}`;
|
|
162
|
+
}
|
|
163
|
+
function sectionDivider(title, width = 50) {
|
|
164
|
+
if (!title) {
|
|
165
|
+
return theme.primary("\u2550".repeat(width));
|
|
166
|
+
}
|
|
167
|
+
const padding = Math.floor((width - getDisplayWidth(title) - 2) / 2);
|
|
168
|
+
return theme.primary(`${"\u2550".repeat(padding)} ${ansis.white.bold(title)} ${"\u2550".repeat(width - padding - getDisplayWidth(title) - 2)}`);
|
|
169
|
+
}
|
|
170
|
+
const STATUS = {
|
|
171
|
+
success: status.ok,
|
|
172
|
+
error: status.fail,
|
|
173
|
+
warning: status.warn,
|
|
174
|
+
info: status.info,
|
|
175
|
+
pending: status.wait,
|
|
176
|
+
inProgress: status.work
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
export { STATUS as S, boxify as a, box as b, status as c, divider as d, padToDisplayWidth as e, displayBanner as f, getDisplayWidth as g, header as h, displayBannerWithInfo as i, menuItem as m, progress as p, renderProgressBar as r, sectionDivider as s, theme as t };
|
package/package.json
CHANGED
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
import ansis from 'ansis';
|
|
2
|
-
import { homepage, version } from '../chunks/package.mjs';
|
|
3
|
-
import { ensureI18nInitialized, i18n } from '../chunks/index2.mjs';
|
|
4
|
-
|
|
5
|
-
const COLORS = {
|
|
6
|
-
primary: ansis.hex("#00D4FF"),
|
|
7
|
-
// Cyan blue
|
|
8
|
-
secondary: ansis.hex("#00FF88"),
|
|
9
|
-
// Spring green
|
|
10
|
-
accent: ansis.hex("#FFD700"),
|
|
11
|
-
// Gold
|
|
12
|
-
warning: ansis.hex("#FFA500"),
|
|
13
|
-
// Orange
|
|
14
|
-
error: ansis.hex("#FF4444"),
|
|
15
|
-
// Red
|
|
16
|
-
success: ansis.hex("#00FF7F"),
|
|
17
|
-
// Green
|
|
18
|
-
muted: ansis.gray,
|
|
19
|
-
bold: ansis.bold
|
|
20
|
-
};
|
|
21
|
-
function getDisplayWidth(str) {
|
|
22
|
-
let width = 0;
|
|
23
|
-
for (const char of str) {
|
|
24
|
-
if (char.match(/[\u4E00-\u9FFF\uFF01-\uFF60\u3000-\u303F]/)) {
|
|
25
|
-
width += 2;
|
|
26
|
-
} else {
|
|
27
|
-
width += 1;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
return width;
|
|
31
|
-
}
|
|
32
|
-
function padToDisplayWidth(str, targetWidth) {
|
|
33
|
-
const currentWidth = getDisplayWidth(str);
|
|
34
|
-
const paddingNeeded = Math.max(0, targetWidth - currentWidth);
|
|
35
|
-
return str + " ".repeat(paddingNeeded);
|
|
36
|
-
}
|
|
37
|
-
function displayBanner(subtitle) {
|
|
38
|
-
ensureI18nInitialized();
|
|
39
|
-
const defaultSubtitle = i18n.t("cli:banner.subtitle");
|
|
40
|
-
const subtitleText = subtitle || defaultSubtitle;
|
|
41
|
-
const paddedSubtitle = padToDisplayWidth(subtitleText, 28);
|
|
42
|
-
console.log(
|
|
43
|
-
ansis.cyan.bold(`
|
|
44
|
-
\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
|
|
45
|
-
\u2551 \u2551
|
|
46
|
-
\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2557 \u2551
|
|
47
|
-
\u2551 \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2554\u255D \u2551
|
|
48
|
-
\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2554\u255D ${ansis.white.bold("JinKu")} \u2551
|
|
49
|
-
\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2588\u2588\u2557 ${ansis.gray(`v${version}`)}${" ".repeat(Math.max(0, 17 - version.length))}\u2551
|
|
50
|
-
\u2551 \u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u255A\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551 \u2588\u2588\u2557 \u2551
|
|
51
|
-
\u2551 \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D ${ansis.gray(paddedSubtitle)} \u2551
|
|
52
|
-
\u2551 \u2551
|
|
53
|
-
\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
|
|
54
|
-
`)
|
|
55
|
-
);
|
|
56
|
-
}
|
|
57
|
-
function displayBannerWithInfo(subtitle) {
|
|
58
|
-
displayBanner(subtitle);
|
|
59
|
-
console.log(ansis.gray(` ${ansis.cyan("ccjk")} - Advanced AI Development Assistant`));
|
|
60
|
-
console.log(ansis.gray(` ${ansis.cyan(homepage)}
|
|
61
|
-
`));
|
|
62
|
-
}
|
|
63
|
-
function renderProgressBar(progress, width = 30) {
|
|
64
|
-
const filled = Math.round(progress / 100 * width);
|
|
65
|
-
const empty = width - filled;
|
|
66
|
-
const bar = COLORS.primary("\u2588".repeat(filled)) + ansis.gray("\u2591".repeat(empty));
|
|
67
|
-
const percentage = `${Math.round(progress)}%`.padStart(4);
|
|
68
|
-
return `[${bar}] ${ansis.cyan(percentage)}`;
|
|
69
|
-
}
|
|
70
|
-
const BOX_CHARS = {
|
|
71
|
-
single: { tl: "\u250C", tr: "\u2510", bl: "\u2514", br: "\u2518", h: "\u2500", v: "\u2502" },
|
|
72
|
-
double: { tl: "\u2554", tr: "\u2557", bl: "\u255A", br: "\u255D", h: "\u2550", v: "\u2551" },
|
|
73
|
-
rounded: { tl: "\u256D", tr: "\u256E", bl: "\u2570", br: "\u256F", h: "\u2500", v: "\u2502" },
|
|
74
|
-
heavy: { tl: "\u250F", tr: "\u2513", bl: "\u2517", br: "\u251B", h: "\u2501", v: "\u2503" }
|
|
75
|
-
};
|
|
76
|
-
function boxify(content, style = "double", title) {
|
|
77
|
-
const chars = BOX_CHARS[style];
|
|
78
|
-
const lines = content.split("\n");
|
|
79
|
-
const maxWidth = Math.max(...lines.map(getDisplayWidth), title ? getDisplayWidth(title) + 4 : 0);
|
|
80
|
-
const paddedLines = lines.map((line) => {
|
|
81
|
-
const padding = maxWidth - getDisplayWidth(line);
|
|
82
|
-
return `${chars.v} ${line}${" ".repeat(padding)} ${chars.v}`;
|
|
83
|
-
});
|
|
84
|
-
let topBorder = `${chars.tl}${chars.h.repeat(maxWidth + 2)}${chars.tr}`;
|
|
85
|
-
if (title) {
|
|
86
|
-
const titlePadding = Math.floor((maxWidth - getDisplayWidth(title)) / 2);
|
|
87
|
-
topBorder = `${chars.tl}${chars.h.repeat(titlePadding)} ${title} ${chars.h.repeat(maxWidth - titlePadding - getDisplayWidth(title))}${chars.tr}`;
|
|
88
|
-
}
|
|
89
|
-
const bottomBorder = `${chars.bl}${chars.h.repeat(maxWidth + 2)}${chars.br}`;
|
|
90
|
-
return [topBorder, ...paddedLines, bottomBorder].join("\n");
|
|
91
|
-
}
|
|
92
|
-
function sectionDivider(title, width = 50) {
|
|
93
|
-
if (!title) {
|
|
94
|
-
return ansis.cyan("\u2550".repeat(width));
|
|
95
|
-
}
|
|
96
|
-
const padding = Math.floor((width - getDisplayWidth(title) - 2) / 2);
|
|
97
|
-
return ansis.cyan(`${"\u2550".repeat(padding)} ${ansis.white.bold(title)} ${"\u2550".repeat(width - padding - getDisplayWidth(title) - 2)}`);
|
|
98
|
-
}
|
|
99
|
-
const STATUS = {
|
|
100
|
-
success: (text) => `${ansis.green("\u2713")} ${text}`,
|
|
101
|
-
error: (text) => `${ansis.red("\u2717")} ${text}`,
|
|
102
|
-
warning: (text) => `${ansis.yellow("\u26A0")} ${text}`,
|
|
103
|
-
info: (text) => `${ansis.blue("\u2139")} ${text}`,
|
|
104
|
-
pending: (text) => `${ansis.gray("\u25CB")} ${text}`,
|
|
105
|
-
inProgress: (text) => `${ansis.cyan("\u25D0")} ${text}`
|
|
106
|
-
};
|
|
107
|
-
function menuItem(key, label, description) {
|
|
108
|
-
const keyPart = ansis.cyan.bold(`[${key}]`);
|
|
109
|
-
const labelPart = ansis.white(label);
|
|
110
|
-
const descPart = description ? ansis.gray(` - ${description}`) : "";
|
|
111
|
-
return ` ${keyPart} ${labelPart}${descPart}`;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
export { COLORS as C, STATUS as S, displayBannerWithInfo as a, boxify as b, displayBanner as d, getDisplayWidth as g, menuItem as m, padToDisplayWidth as p, renderProgressBar as r, sectionDivider as s };
|