minhyuk 1.0.3 → 1.0.5
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/bin/cli.js +4 -2
- package/lib/data.js +5 -2
- package/lib/render.js +45 -1
- package/package.json +3 -3
package/bin/cli.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
const { spawn } = require("child_process");
|
|
5
5
|
const data = require("../lib/data");
|
|
6
|
-
const { c, accent, accent2, box } = require("../lib/render");
|
|
6
|
+
const { c, accent, accent2, box, banner } = require("../lib/render");
|
|
7
7
|
const pkg = require("../package.json");
|
|
8
8
|
|
|
9
9
|
// head 등으로 출력이 잘릴 때 발생하는 EPIPE를 조용히 무시
|
|
@@ -39,7 +39,7 @@ function showHome() {
|
|
|
39
39
|
const lines = [
|
|
40
40
|
`${c.bold(accent(data.name))} ${c.dim("(" + data.nameEn + ")")}`,
|
|
41
41
|
"",
|
|
42
|
-
c.white(
|
|
42
|
+
c.white("디자인 · 기술 · 사용자 경험이 만나는 지점에서"),
|
|
43
43
|
c.white("디지털 경험을 만드는 ") + c.bold("소프트웨어 개발자"),
|
|
44
44
|
"",
|
|
45
45
|
`${accent2("●")} ${c.bold(data.current.role)} ${c.dim("@")} ${data.current.company}`,
|
|
@@ -48,6 +48,8 @@ function showHome() {
|
|
|
48
48
|
`${c.dim("FOCUS")} ${data.focus.map((f) => c.cyan(f)).join(c.dim(" · "))}`,
|
|
49
49
|
];
|
|
50
50
|
out("");
|
|
51
|
+
banner().split("\n").forEach((l) => out(" " + l));
|
|
52
|
+
out("");
|
|
51
53
|
out(box(lines));
|
|
52
54
|
out("");
|
|
53
55
|
out(` ${c.dim("아래 명령으로 더 알아보세요")} ${c.dim("—")} ${c.bold("npx " + data.handle + " <옵션>")}`);
|
package/lib/data.js
CHANGED
|
@@ -9,7 +9,7 @@ module.exports = {
|
|
|
9
9
|
nameEn: "Min-hyuk Shin",
|
|
10
10
|
handle: "minhyuk",
|
|
11
11
|
birth: "1999.08.29",
|
|
12
|
-
location: "
|
|
12
|
+
location: "Daejeon, Korea",
|
|
13
13
|
tagline: "디자인 · 기술 · 사용자 경험이 만나는 지점에서 디지털 경험을 만드는 소프트웨어 개발자",
|
|
14
14
|
|
|
15
15
|
current: {
|
|
@@ -18,7 +18,7 @@ module.exports = {
|
|
|
18
18
|
period: "2026.03 — 현재",
|
|
19
19
|
},
|
|
20
20
|
|
|
21
|
-
focus: ["
|
|
21
|
+
focus: ["TypeScript", "Next.js", "PostgreSQL", "Supabase", "Vercel"],
|
|
22
22
|
|
|
23
23
|
// 외부 링크 (open 명령에서 브라우저로 열림)
|
|
24
24
|
links: {
|
|
@@ -31,6 +31,9 @@ module.exports = {
|
|
|
31
31
|
},
|
|
32
32
|
|
|
33
33
|
about: [
|
|
34
|
+
"패션디자인을 전공하고, 사용자 경험을 더 직접적으로 개선할 수 있는",
|
|
35
|
+
"소프트웨어 엔지니어에 매력을 느껴 개발자의 길을 선택했습니다.",
|
|
36
|
+
"",
|
|
34
37
|
"웹소설 AI 번역기, 웹 접근성 솔루션, 부트캠프 코드리뷰 멘토,",
|
|
35
38
|
"패션 이커머스(FILA), VC 투자 운영 B2B SaaS, B2B AX SaaS까지",
|
|
36
39
|
"다양한 경험을 쌓아왔고, 지금은 AI로 언어와 기술의 장벽을 허물며",
|
package/lib/render.js
CHANGED
|
@@ -32,6 +32,50 @@ const rgb = (r, g, b) => (s) =>
|
|
|
32
32
|
const accent = rgb(124, 92, 255); // violet
|
|
33
33
|
const accent2 = rgb(45, 212, 191); // teal
|
|
34
34
|
|
|
35
|
+
// 한 줄에 가로 방향 그라데이션 적용 (violet → teal)
|
|
36
|
+
function gradientLine(line, from, to) {
|
|
37
|
+
if (!useColor) return line;
|
|
38
|
+
const chars = [...line];
|
|
39
|
+
const n = chars.length;
|
|
40
|
+
let outStr = "";
|
|
41
|
+
chars.forEach((ch, i) => {
|
|
42
|
+
if (ch === " ") {
|
|
43
|
+
outStr += ch;
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const t = n <= 1 ? 0 : i / (n - 1);
|
|
47
|
+
const r = Math.round(from[0] + (to[0] - from[0]) * t);
|
|
48
|
+
const g = Math.round(from[1] + (to[1] - from[1]) * t);
|
|
49
|
+
const b = Math.round(from[2] + (to[2] - from[2]) * t);
|
|
50
|
+
outStr += `\x1b[38;2;${r};${g};${b}m${ch}`;
|
|
51
|
+
});
|
|
52
|
+
return outStr + "\x1b[39m";
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// MINHYUK 터미널 아트 배너 (ANSI Shadow 스타일)
|
|
56
|
+
const BANNER_LINES = [
|
|
57
|
+
"███╗ ███╗██╗███╗ ██╗██╗ ██╗██╗ ██╗██╗ ██╗██╗ ██╗",
|
|
58
|
+
"████╗ ████║██║████╗ ██║██║ ██║╚██╗ ██╔╝██║ ██║██║ ██╔╝",
|
|
59
|
+
"██╔████╔██║██║██╔██╗ ██║███████║ ╚████╔╝ ██║ ██║█████╔╝ ",
|
|
60
|
+
"██║╚██╔╝██║██║██║╚██╗██║██╔══██║ ╚██╔╝ ██║ ██║██╔═██╗ ",
|
|
61
|
+
"██║ ╚═╝ ██║██║██║ ╚████║██║ ██║ ██║ ╚██████╔╝██║ ██╗",
|
|
62
|
+
"╚═╝ ╚═╝╚═╝╚═╝ ╚═══╝╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝",
|
|
63
|
+
];
|
|
64
|
+
|
|
65
|
+
const BANNER_WIDTH = Math.max(...BANNER_LINES.map((l) => [...l].length));
|
|
66
|
+
|
|
67
|
+
// 배너 문자열 반환. 터미널이 좁으면 간단한 폴백 텍스트로 대체.
|
|
68
|
+
function banner() {
|
|
69
|
+
const cols =
|
|
70
|
+
process.stdout.columns || parseInt(process.env.COLUMNS, 10) || 80;
|
|
71
|
+
if (cols < BANNER_WIDTH + 2) {
|
|
72
|
+
return accent(c.bold("M I N H Y U K"));
|
|
73
|
+
}
|
|
74
|
+
const from = [124, 92, 255]; // violet
|
|
75
|
+
const to = [45, 212, 191]; // teal
|
|
76
|
+
return BANNER_LINES.map((l) => gradientLine(l, from, to)).join("\n");
|
|
77
|
+
}
|
|
78
|
+
|
|
35
79
|
// ANSI 코드를 제외한 실제 출력 폭 계산 (한글=2칸)
|
|
36
80
|
function visibleWidth(str) {
|
|
37
81
|
const clean = str.replace(/\[[0-9;]*m/g, "");
|
|
@@ -68,4 +112,4 @@ function box(lines, opts = {}) {
|
|
|
68
112
|
return [top, ...body, bot].join("\n");
|
|
69
113
|
}
|
|
70
114
|
|
|
71
|
-
module.exports = { c, accent, accent2, box, visibleWidth };
|
|
115
|
+
module.exports = { c, accent, accent2, box, visibleWidth, banner };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "minhyuk",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.5",
|
|
4
4
|
"description": "신민혁(Min-hyuk Shin)을 터미널에서 만나보세요 — npx minhyuk",
|
|
5
5
|
"bin": {
|
|
6
6
|
"minhyuk": "bin/cli.js"
|
|
@@ -28,10 +28,10 @@
|
|
|
28
28
|
"homepage": "https://min-hyuk.com",
|
|
29
29
|
"repository": {
|
|
30
30
|
"type": "git",
|
|
31
|
-
"url": "git+https://github.com/shin-minhyuk/minhyuk.git"
|
|
31
|
+
"url": "git+https://github.com/shin-minhyuk/minhyuk-cli.git"
|
|
32
32
|
},
|
|
33
33
|
"bugs": {
|
|
34
|
-
"url": "https://github.com/shin-minhyuk/minhyuk/issues"
|
|
34
|
+
"url": "https://github.com/shin-minhyuk/minhyuk-cli/issues"
|
|
35
35
|
},
|
|
36
36
|
"engines": {
|
|
37
37
|
"node": ">=14"
|