ubugeeei 1.1.0 → 3.0.0

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/README.md CHANGED
@@ -1,20 +1,86 @@
1
- <h2>ubugeeei</h2>
2
- <p>🇯🇵🗼 software engineer / 🦀彡..。o うに,禅/サムライ 🥷</p>
1
+ # UBUGEEEI(1)
3
2
 
4
- member of <a href="https://github.com/vuejs">@vuejs</a> (Official), <a href="https://github.com/vuejs-jp">@vuejs-jp</a> (Vue Fes Japan)<br>
5
-
6
- king of <a href="https://github.com/chibivue-land">@chibivue-land</a><br>
3
+ ## NAME
7
4
 
8
- working at <a href="https://github.com/mates-system" target="_blank">@mates-system</a><br>
5
+ `ubugeeei` - software engineer
9
6
 
10
- creator of <a href="https://github.com/chibivue-land/chibivue" target="_blank">chibivue</a>, <a href="https://github.com/ubugeeei/vize" target="_blank">vize</a>, <a href="https://github.com/ubugeeei/ox-content" target="_blank">ox-content</a>, <a href="https://github.com/ubugeeei/relanote" target="_blank">relanote</a><br>
11
-
12
- writing: <a href="https://wtrclred.io" target="_blank">wtrclred.io</a> (blog), <a href="https://github.com/ubugeei/reading-vuejs-core-vapor" target="_blank">reading-vuejs-core-vapor</a>,
7
+ ## SYNOPSIS
13
8
 
14
- ---
9
+ `npx ubugeeei`
15
10
 
16
- My Sponsors 💚\
17
- <img src="https://raw.githubusercontent.com/ubugeeei/sponsors/main/sponsors.png" width="320">
11
+ ## PROFILE
18
12
 
19
- please sponsoring me!
13
+ - もののけ王
14
+ - うにをくらえ ✹ 🦀 🦆 彡..。o
15
+ - Tokyo 🇯🇵
16
+ - 発言は全て現代アートだよ( ◠‿◠ )
20
17
 
18
+ ## ROLES
19
+
20
+ - [Vue.js](https://vuejs.org/about/team.html) Core Team
21
+ - [Vue.js Japan User Group](https://github.com/vuejs-jp) Core Staff
22
+ - [Vite+](https://github.com/voidzero-dev/vite-plus) Core Contributor
23
+ - [株式会社メイツ](https://github.com/mates-inc) Chief Engineer
24
+
25
+ ## INTERESTS
26
+
27
+ - Web Frontend, Vue, Design, Art, Rust, Performance Tuning
28
+ - Programming Languages, Language Processors, OS and Browser Systems Programming
29
+ - Engineering Philosophy, OSS, Jazz, Twitter
30
+
31
+ ## TASK SURFACE
32
+
33
+ Tasks / recent work / PR requests
34
+
35
+ - vault: [taskgraph/public-vault](https://github.com/ubugeeei-taskgraph/public-vault)
36
+
37
+ ## CREATOR OF
38
+
39
+ - [chibivue](https://github.com/chibivue-land/chibivue): a minimal Vue.js implementation and online book for learning Vue.js step by step
40
+ - [Vize](https://github.com/ubugeeei/vize): compiler, linter, typechecker, formatter, story system, and lsp for Vue.js in Rust
41
+ - [Ox Content](https://github.com/ubugeeei/ox-content): framework-agnostic documentation tooling with a high-performance Markdown parser in Rust
42
+ - [ubugeeei/start](https://github.com/ubugeeei/start): opinionated defaults and engineering rules for AI-assisted project creation
43
+ - [ubugeeei/style-guide.vue](https://github.com/ubugeeei/style-guide.vue): my personal Vue style guide and engineering preferences
44
+ - [ubugeeei/origin](https://github.com/ubugeeei/origin): an opinionated personal macOS workstation configuration built with Nix, nix-darwin, and Home Manager
45
+ - [ubugeeei-taskgraph](https://github.com/ubugeeei-taskgraph): a task management system with a public vault, shared config, and a PR-based request surface
46
+ - [reading-vuejs-core-vapor](https://github.com/ubugeeei/reading-vuejs-core-vapor): a book for reading and understanding the Vue Vapor implementation
47
+ - [fwgsl](https://github.com/ubugeeei/fwgsl): a pure functional language for WebGPU that compiles to WGSL
48
+ - [relanote](https://github.com/ubugeeei/relanote): a music programming language based on relative intervals
49
+ - [Vapor Moon](https://github.com/ubugeeei/vapor-moon): a MoonBit-first SFC toolchain with Vue-like authoring and direct DOM / SSR output
50
+ - [Mbt on Rails](https://github.com/ubugeeei/mbt-on-rails): a MoonBit-first, Rails-inspired framework skeleton
51
+
52
+ ## SELECTED POSTS
53
+
54
+ 1. [Characterize Vue.js](https://wtrclred.io/en/posts/07)
55
+ 2. [React is React, just.](https://wtrclred.io/en/posts/01)
56
+ 3. [React is React, just. Part 2](https://wtrclred.io/en/posts/08)
57
+ 4. [What is Vue.js? It's just a language lol](https://wtrclred.io/en/posts/05)
58
+ 5. [Vue.js is not Easy. It is Approachable.](https://wtrclred.io/en/posts/06)
59
+ 6. [Signals and Signals. And Retained UI.](https://wtrclred.io/en/posts/12)
60
+
61
+ ## CONTRIBUTING TO
62
+
63
+ - [Vite+](https://github.com/voidzero-dev/vite-plus)
64
+ - [vite-task](https://github.com/voidzero-dev/vite-task)
65
+ - [oxc](https://github.com/oxc-project/oxc)
66
+
67
+ ## SPACES
68
+
69
+ - king: [chibivue.land](https://chibivue.land)
70
+ - blog: [wtrclred.io](https://wtrclred.io)
71
+
72
+ ## LINKS
73
+
74
+ - github: [ubugeeei](https://github.com/ubugeeei)
75
+ - twitter: [ubugeeei](https://x.com/ubugeeei)
76
+ - discord: [ubugeeei](https://discord.com/users/ubugeeei)
77
+ - sponsor: [sponsors/ubugeeei](https://github.com/sponsors/ubugeeei)
78
+
79
+ ## EX
80
+
81
+ - [vuejs/vue-vapor](https://github.com/vuejs/vue-vapor)
82
+ - [vuejs-jp/vuefes-2025-website](https://github.com/vuejs-jp/vuefes-2025-website)
83
+
84
+ ## SUPPORT
85
+
86
+ ![Sponsors](https://github.com/ubugeeei/sponsors/blob/main/sponsors-transparent.png?raw=true)
package/dist/cli.mjs ADDED
@@ -0,0 +1,400 @@
1
+ #!/usr/bin/env node
2
+ //#region src/content.ts
3
+ const messages = {
4
+ en: {
5
+ name: "ubugeeei",
6
+ nickname: "もののけ王",
7
+ tagline: "うにをくらえ",
8
+ location: "Tokyo 🇯🇵",
9
+ quote: "発言は全て現代アートだよ( ◠‿◠ )",
10
+ taskSurface: "Tasks / recent work / PR requests",
11
+ uni: "✹ 🦀 🦆 彡..。o",
12
+ interests: [
13
+ "Web Frontend",
14
+ "Vue",
15
+ "Design",
16
+ "Art",
17
+ "Rust",
18
+ "Performance Tuning",
19
+ "Programming Languages",
20
+ "Language Processors",
21
+ "OS and Browser Systems Programming",
22
+ "Engineering Philosophy",
23
+ "OSS",
24
+ "Jazz",
25
+ "Twitter"
26
+ ],
27
+ creator: "Creator of",
28
+ contribute: "Contributing to",
29
+ selectedPosts: "Selected Posts"
30
+ },
31
+ ja: {
32
+ name: "ubugeeei",
33
+ nickname: "もののけ王",
34
+ tagline: "うにをくらえ",
35
+ location: "Tokyo 🇯🇵",
36
+ quote: "発言は全て現代アートだよ( ◠‿◠ )",
37
+ taskSurface: "Tasks / recent work / PR requests",
38
+ uni: "✹ 🦀 🦆 彡..。o",
39
+ interests: [
40
+ "Web Frontend",
41
+ "Vue",
42
+ "Design",
43
+ "Art",
44
+ "Rust",
45
+ "Performance Tuning",
46
+ "Programming Languages",
47
+ "Language Processors",
48
+ "OS and Browser Systems Programming",
49
+ "Engineering Philosophy",
50
+ "OSS",
51
+ "Jazz",
52
+ "Twitter"
53
+ ],
54
+ creator: "Creator of",
55
+ contribute: "Contributing to",
56
+ selectedPosts: "Selected Posts"
57
+ }
58
+ };
59
+ function detectLocale() {
60
+ const args = process.argv.slice(2);
61
+ if (args.includes("--ja") || args.includes("-j") || args.includes("--japanese")) return "ja";
62
+ if (args.includes("--en") || args.includes("-e") || args.includes("--english")) return "en";
63
+ if ((process.env.LANG || process.env.LANGUAGE || process.env.LC_ALL || "").toLowerCase().startsWith("ja")) return "ja";
64
+ return "en";
65
+ }
66
+ const projects = [
67
+ {
68
+ name: "chibivue",
69
+ url: "https://github.com/chibivue-land/chibivue",
70
+ description: "A minimal Vue.js implementation and online book for learning Vue.js step by step."
71
+ },
72
+ {
73
+ name: "Vize",
74
+ url: "https://github.com/ubugeeei/vize",
75
+ description: "Compiler, linter, typechecker, formatter, story system, and lsp for Vue.js in Rust."
76
+ },
77
+ {
78
+ name: "Ox Content",
79
+ url: "https://github.com/ubugeeei/ox-content",
80
+ description: "Framework-agnostic documentation tooling with a high-performance Markdown parser in Rust."
81
+ },
82
+ {
83
+ name: "ubugeeei/start",
84
+ url: "https://github.com/ubugeeei/start",
85
+ description: "Opinionated defaults and engineering rules for AI-assisted project creation."
86
+ },
87
+ {
88
+ name: "ubugeeei/style-guide.vue",
89
+ url: "https://github.com/ubugeeei/style-guide.vue",
90
+ description: "My personal Vue style guide and engineering preferences."
91
+ },
92
+ {
93
+ name: "ubugeeei/origin",
94
+ url: "https://github.com/ubugeeei/origin",
95
+ description: "An opinionated personal macOS workstation configuration built with Nix, nix-darwin, and Home Manager."
96
+ },
97
+ {
98
+ name: "ubugeeei-taskgraph",
99
+ url: "https://github.com/ubugeeei-taskgraph",
100
+ description: "A task management system with a public vault, shared config, and a PR-based request surface."
101
+ },
102
+ {
103
+ name: "reading-vuejs-core-vapor",
104
+ url: "https://github.com/ubugeeei/reading-vuejs-core-vapor",
105
+ description: "A book for reading and understanding the Vue Vapor implementation."
106
+ },
107
+ {
108
+ name: "fwgsl",
109
+ url: "https://github.com/ubugeeei/fwgsl",
110
+ description: "A pure functional language for WebGPU that compiles to WGSL."
111
+ },
112
+ {
113
+ name: "relanote",
114
+ url: "https://github.com/ubugeeei/relanote",
115
+ description: "A music programming language based on relative intervals."
116
+ },
117
+ {
118
+ name: "Vapor Moon",
119
+ url: "https://github.com/ubugeeei/vapor-moon",
120
+ description: "A MoonBit-first SFC toolchain with Vue-like authoring and direct DOM / SSR output."
121
+ },
122
+ {
123
+ name: "Mbt on Rails",
124
+ url: "https://github.com/ubugeeei/mbt-on-rails",
125
+ description: "A MoonBit-first, Rails-inspired framework skeleton."
126
+ }
127
+ ];
128
+ const blogPosts = [
129
+ {
130
+ title: "Characterize Vue.js",
131
+ url: "https://wtrclred.io/en/posts/07"
132
+ },
133
+ {
134
+ title: "React is React, just.",
135
+ url: "https://wtrclred.io/en/posts/01"
136
+ },
137
+ {
138
+ title: "React is React, just. Part 2",
139
+ url: "https://wtrclred.io/en/posts/08"
140
+ },
141
+ {
142
+ title: "What is Vue.js? It's just a language lol",
143
+ url: "https://wtrclred.io/en/posts/05"
144
+ },
145
+ {
146
+ title: "Vue.js is not Easy. It is Approachable.",
147
+ url: "https://wtrclred.io/en/posts/06"
148
+ },
149
+ {
150
+ title: "Signals and Signals. And Retained UI.",
151
+ url: "https://wtrclred.io/en/posts/12"
152
+ }
153
+ ];
154
+ const contributes = [
155
+ {
156
+ name: "Vite+",
157
+ url: "https://github.com/voidzero-dev/vite-plus"
158
+ },
159
+ {
160
+ name: "vite-task",
161
+ url: "https://github.com/voidzero-dev/vite-task"
162
+ },
163
+ {
164
+ name: "oxc",
165
+ url: "https://github.com/oxc-project/oxc"
166
+ }
167
+ ];
168
+ const OSC = "\x1B]";
169
+ const BEL = "\x07";
170
+ const rgb = (r, g, b) => `[38;2;${r};${g};${b}m`;
171
+ rgb(66, 184, 131), rgb(52, 152, 108), rgb(100, 207, 159), rgb(0, 200, 220), rgb(255, 160, 70), rgb(255, 100, 150), rgb(180, 120, 255), rgb(255, 215, 0), rgb(255, 255, 255), rgb(150, 150, 150), rgb(80, 80, 80), rgb(66, 184, 131);
172
+ rgb(66, 184, 131), rgb(60, 170, 140), rgb(50, 160, 160), rgb(40, 150, 180), rgb(30, 140, 200), rgb(20, 130, 220), rgb(80, 120, 240), rgb(140, 110, 255);
173
+ function link(url, text) {
174
+ return `${OSC}8;;${url}${BEL}${text}${OSC}8;;${BEL}`;
175
+ }
176
+ //#endregion
177
+ //#region src/layout.ts
178
+ const ESC_CHAR = String.fromCharCode(27);
179
+ const BEL_CHAR = String.fromCharCode(7);
180
+ `${ESC_CHAR}`, `${BEL_CHAR}`;
181
+ const ansiPattern = new RegExp(`${ESC_CHAR}\\[[0-9;]*m|${ESC_CHAR}\\]8;;[^${BEL_CHAR}]*${BEL_CHAR}`, "g");
182
+ const graphemeSegmenter = new Intl.Segmenter("en", { granularity: "grapheme" });
183
+ function isZeroWidthCodePoint(code) {
184
+ return code === 8205 || code >= 768 && code <= 879 || code >= 65024 && code <= 65039 || code >= 917760 && code <= 917999;
185
+ }
186
+ function isRegionalIndicator(code) {
187
+ return code >= 127462 && code <= 127487;
188
+ }
189
+ function isEmojiCodePoint(code) {
190
+ return code >= 126976 && code <= 129791 || code >= 9728 && code <= 9983 || code >= 9984 && code <= 10175;
191
+ }
192
+ function isWideCodePoint(code) {
193
+ return code >= 4352 && code <= 4447 || code >= 11904 && code <= 40959 || code >= 44032 && code <= 55215 || code >= 63744 && code <= 64255 || code >= 65040 && code <= 65055 || code >= 65072 && code <= 65135 || code >= 65280 && code <= 65376 || code >= 65504 && code <= 65510 || code >= 131072 && code <= 196607;
194
+ }
195
+ function isTerminalWideSymbol(code) {
196
+ return code === 8226 || code === 8255 || code === 9696 || code === 10041;
197
+ }
198
+ function getGraphemeWidth(segment) {
199
+ const codePoints = Array.from(segment, (char) => char.codePointAt(0) || 0);
200
+ const visible = codePoints.filter((code) => !isZeroWidthCodePoint(code));
201
+ if (visible.length === 0) return 0;
202
+ if (visible.every(isRegionalIndicator)) return 4;
203
+ if (codePoints.some(isEmojiCodePoint)) return 2;
204
+ if (visible.some(isWideCodePoint)) return 2;
205
+ if (visible.some(isTerminalWideSymbol)) return 2;
206
+ return 1;
207
+ }
208
+ function pushTextTokens(tokens, text, widthFn = getGraphemeWidth) {
209
+ for (const { segment } of graphemeSegmenter.segment(text)) tokens.push({
210
+ type: "grapheme",
211
+ value: segment,
212
+ width: widthFn(segment)
213
+ });
214
+ }
215
+ function tokenizeDisplayString(str, widthFn = getGraphemeWidth) {
216
+ const tokens = [];
217
+ let lastIndex = 0;
218
+ for (const match of str.matchAll(ansiPattern)) {
219
+ const index = match.index ?? 0;
220
+ if (index > lastIndex) pushTextTokens(tokens, str.slice(lastIndex, index), widthFn);
221
+ tokens.push({
222
+ type: "ansi",
223
+ value: match[0]
224
+ });
225
+ lastIndex = index + match[0].length;
226
+ }
227
+ if (lastIndex < str.length) pushTextTokens(tokens, str.slice(lastIndex), widthFn);
228
+ return tokens;
229
+ }
230
+ function getDisplayWidthWith(str, widthFn = getGraphemeWidth) {
231
+ let width = 0;
232
+ for (const token of tokenizeDisplayString(str, widthFn)) if (token.type === "grapheme") width += token.width;
233
+ return width;
234
+ }
235
+ function getDisplayWidth(str) {
236
+ return getDisplayWidthWith(str);
237
+ }
238
+ function clamp(value, min, max) {
239
+ return Math.max(min, Math.min(max, value));
240
+ }
241
+ const INNER_WIDTH = clamp((process.stdout.columns ?? 92) - 2, 78, 100) - 2 - 1 - 2;
242
+ const RIGHT_COLUMN_WIDTH = clamp(Math.floor(INNER_WIDTH * .38), 32, 38);
243
+ INNER_WIDTH - 3 - RIGHT_COLUMN_WIDTH;
244
+ function wrapText(text, maxWidth) {
245
+ return wrapTextWith(text, maxWidth);
246
+ }
247
+ function wrapTextWith(text, maxWidth, widthFn = getGraphemeWidth) {
248
+ const words = text.split(" ");
249
+ const lines = [];
250
+ let current = "";
251
+ for (const word of words) {
252
+ const candidate = current ? `${current} ${word}` : word;
253
+ if (getDisplayWidthWith(candidate, widthFn) <= maxWidth) {
254
+ current = candidate;
255
+ continue;
256
+ }
257
+ if (current) lines.push(current);
258
+ if (getDisplayWidthWith(word, widthFn) <= maxWidth) {
259
+ current = word;
260
+ continue;
261
+ }
262
+ let chunk = "";
263
+ for (const char of word) {
264
+ const chunkCandidate = chunk + char;
265
+ if (getDisplayWidthWith(chunkCandidate, widthFn) <= maxWidth) {
266
+ chunk = chunkCandidate;
267
+ continue;
268
+ }
269
+ if (chunk) lines.push(chunk);
270
+ chunk = char;
271
+ }
272
+ current = chunk;
273
+ }
274
+ if (current) lines.push(current);
275
+ return lines;
276
+ }
277
+ function wrapItems(items, maxWidth, separator = " • ") {
278
+ const lines = [];
279
+ let current = "";
280
+ for (const item of items) {
281
+ const candidate = current ? `${current}${separator}${item}` : item;
282
+ if (getDisplayWidth(candidate) <= maxWidth) {
283
+ current = candidate;
284
+ continue;
285
+ }
286
+ if (current) lines.push(current);
287
+ current = item;
288
+ }
289
+ if (current) lines.push(current);
290
+ return lines;
291
+ }
292
+ //#endregion
293
+ //#region src/render.ts
294
+ const PAGE_WIDTH = Math.min(process.stdout.columns ?? 80, 80);
295
+ const INDENT = " ";
296
+ const BODY_WIDTH = Math.max(56, PAGE_WIDTH - getDisplayWidth(INDENT));
297
+ const MARK = "UBUGEEEI(1)";
298
+ const spaces = [{
299
+ label: "king",
300
+ text: "chibivue.land",
301
+ url: "https://chibivue.land"
302
+ }, {
303
+ label: "blog",
304
+ text: "wtrclred.io",
305
+ url: "https://wtrclred.io"
306
+ }];
307
+ const links = [
308
+ {
309
+ label: "github",
310
+ text: "ubugeeei",
311
+ url: "https://github.com/ubugeeei"
312
+ },
313
+ {
314
+ label: "twitter",
315
+ text: "ubugeeei",
316
+ url: "https://x.com/ubugeeei"
317
+ },
318
+ {
319
+ label: "discord",
320
+ text: "ubugeeei",
321
+ url: "https://discord.com/users/ubugeeei"
322
+ },
323
+ {
324
+ label: "sponsor",
325
+ text: "sponsors/ubugeeei",
326
+ url: "https://github.com/sponsors/ubugeeei"
327
+ }
328
+ ];
329
+ const examples = [{
330
+ text: "vuejs/vue-vapor",
331
+ url: "https://github.com/vuejs/vue-vapor"
332
+ }, {
333
+ text: "vuejs-jp/vuefes-2025-website",
334
+ url: "https://github.com/vuejs-jp/vuefes-2025-website"
335
+ }];
336
+ function formatHeader() {
337
+ const gap = Math.max(2, PAGE_WIDTH - getDisplayWidth(MARK) * 2);
338
+ return `${MARK}${" ".repeat(gap)}${MARK}`;
339
+ }
340
+ function formatSection(title, lines) {
341
+ return [
342
+ title,
343
+ ...lines,
344
+ ""
345
+ ];
346
+ }
347
+ function wrapIndented(text, indent = INDENT, width = BODY_WIDTH) {
348
+ return wrapText(text, width).map((line) => `${indent}${line}`);
349
+ }
350
+ function formatProject(project) {
351
+ return [`${INDENT}${link(project.url, project.name)}`, ...wrapIndented(project.description, `${INDENT}${INDENT}`)];
352
+ }
353
+ function formatPost(post, index) {
354
+ const lead = `${index + 1}. `;
355
+ return wrapText(post.title, BODY_WIDTH - getDisplayWidth(lead)).map((line, lineIndex) => lineIndex === 0 ? `${INDENT}${lead}${link(post.url, line)}` : `${INDENT}${" ".repeat(getDisplayWidth(lead))}${link(post.url, line)}`);
356
+ }
357
+ function formatContribution(item) {
358
+ return [`${INDENT}${link(item.url, item.name)}`];
359
+ }
360
+ function formatLabeledLink(label, text, url) {
361
+ return [`${INDENT}${label.padEnd(10)}${link(url, text)}`];
362
+ }
363
+ function renderProfile(locale) {
364
+ const t = messages[locale];
365
+ const roleLines = [
366
+ `${INDENT}${link("https://vuejs.org/about/team.html", "Vue.js")} Core Team`,
367
+ `${INDENT}${link("https://github.com/vuejs-jp", "Vue.js Japan User Group")} Core Staff`,
368
+ `${INDENT}${link("https://github.com/voidzero-dev/vite-plus", "Vite+")} Core Contributor`,
369
+ `${INDENT}${link("https://github.com/mates-inc", "株式会社メイツ")} Chief Engineer`
370
+ ];
371
+ const interestLines = wrapItems(t.interests, BODY_WIDTH, ", ").map((line) => `${INDENT}${line}`);
372
+ return [
373
+ formatHeader(),
374
+ "",
375
+ ...formatSection("NAME", [`${INDENT}ubugeeei - software engineer`]),
376
+ ...formatSection("SYNOPSIS", [`${INDENT}npx ubugeeei`]),
377
+ ...formatSection("PROFILE", [
378
+ `${INDENT}${t.nickname}`,
379
+ `${INDENT}${t.tagline} ${t.uni}`,
380
+ `${INDENT}${t.location}`,
381
+ `${INDENT}${t.quote}`
382
+ ]),
383
+ ...formatSection("ROLES", roleLines),
384
+ ...formatSection("INTERESTS", interestLines),
385
+ ...formatSection("TASK SURFACE", [...wrapIndented(t.taskSurface), ...formatLabeledLink("vault", "taskgraph/public-vault", "https://github.com/ubugeeei-taskgraph/public-vault")]),
386
+ ...formatSection("CREATOR OF", projects.flatMap(formatProject)),
387
+ ...formatSection("SELECTED POSTS", blogPosts.flatMap(formatPost)),
388
+ ...formatSection("CONTRIBUTING TO", contributes.flatMap(formatContribution)),
389
+ ...formatSection("SPACES", spaces.flatMap((item) => formatLabeledLink(item.label, item.text, item.url))),
390
+ ...formatSection("LINKS", links.flatMap((item) => formatLabeledLink(item.label, item.text, item.url))),
391
+ ...formatSection("EX", examples.map((item) => `${INDENT}${link(item.url, item.text)}`)),
392
+ formatHeader(),
393
+ ""
394
+ ].join("\n");
395
+ }
396
+ //#endregion
397
+ //#region src/cli.ts
398
+ console.log(renderProfile(detectLocale()));
399
+ //#endregion
400
+ export {};
package/package.json CHANGED
@@ -1,47 +1,42 @@
1
1
  {
2
2
  "name": "ubugeeei",
3
- "version": "1.1.0",
3
+ "version": "3.0.0",
4
4
  "description": "Hi! I'm ubugeeei, Vue.js team member, author of chibivue and vize",
5
- "type": "module",
6
- "main": "index.js",
7
- "bin": {
8
- "ubugeeei": "dist/cli.js"
9
- },
10
- "exports": {
11
- ".": "./index.js"
12
- },
13
- "scripts": {
14
- "build": "rolldown bin/cli.ts -d dist --platform node",
15
- "dev": "node --experimental-strip-types --no-warnings bin/cli.ts"
16
- },
17
5
  "keywords": [
18
- "cli",
19
6
  "card",
7
+ "chibivue",
8
+ "cli",
20
9
  "npx",
21
- "vue",
22
- "chibivue"
10
+ "vue"
23
11
  ],
24
- "author": "ubugeeei",
25
- "license": "MIT",
26
12
  "homepage": "https://wtrclred.io",
13
+ "bugs": {
14
+ "url": "https://github.com/ubugeeei/ubugeeei/issues"
15
+ },
16
+ "license": "MIT",
17
+ "author": "ubugeeei",
27
18
  "repository": {
28
19
  "type": "git",
29
20
  "url": "git+https://github.com/ubugeeei/ubugeeei.git"
30
21
  },
31
- "bugs": {
32
- "url": "https://github.com/ubugeeei/ubugeeei/issues"
33
- },
34
22
  "funding": "https://github.com/sponsors/ubugeeei",
35
- "engines": {
36
- "node": ">=22.6.0"
23
+ "bin": {
24
+ "ubugeeei": "dist/cli.mjs"
37
25
  },
26
+ "files": [
27
+ "dist"
28
+ ],
29
+ "type": "module",
38
30
  "devDependencies": {
39
- "@types/node": "^22.0.0",
40
- "rolldown": "^1.0.0-beta.60",
41
- "typescript": "^5.0.0"
31
+ "@types/node": "^24.0.0",
32
+ "typescript": "^5.0.0",
33
+ "vite-plus": "^0.1.14"
42
34
  },
43
- "files": [
44
- "dist",
45
- "assets"
46
- ]
47
- }
35
+ "engines": {
36
+ "node": ">=24.0.0"
37
+ },
38
+ "scripts": {
39
+ "dev": "node dist/cli.mjs",
40
+ "watch": "vp pack --watch"
41
+ }
42
+ }
package/assets/avatar.png DELETED
Binary file
package/dist/cli.js DELETED
@@ -1,174 +0,0 @@
1
- #!/usr/bin/env node
2
- //#region bin/cli.ts
3
- const ESC = "\x1B";
4
- const OSC = "\x1B]";
5
- const BEL = "\x07";
6
- const RESET = `${ESC}[0m`;
7
- const BOLD = `${ESC}[1m`;
8
- const rgb = (r, g, b) => `${ESC}[38;2;${r};${g};${b}m`;
9
- const COLORS = {
10
- black: rgb(0, 0, 0),
11
- dark: rgb(40, 40, 40),
12
- gray: rgb(100, 100, 100),
13
- light: rgb(160, 160, 160),
14
- border: rgb(80, 80, 80)
15
- };
16
- const link = (url, text) => `${OSC}8;;${url}${BEL}${text}${OSC}8;;${BEL}`;
17
- const messages = {
18
- en: {
19
- greeting: "Hi there!",
20
- name: "ubugeeei",
21
- nickname: "もののけ王",
22
- tagline: "うにをくらえ 🦀彡..。o",
23
- interests: "Jazz, Art, Compiler, Vue",
24
- memberOf: "Member of",
25
- author: "Author of",
26
- kingOf: "King of",
27
- chiefEngineerOf: "Chief Engineer of",
28
- contribute: "Contribute",
29
- blog: "Blog",
30
- github: "GitHub",
31
- twitter: "Twitter",
32
- discord: "Discord",
33
- sponsor: "Sponsor"
34
- },
35
- ja: {
36
- greeting: "ごきげんよう!",
37
- name: "ubugeeei",
38
- nickname: "もののけ王",
39
- tagline: "うにをくらえ 🦀彡..。o",
40
- interests: "Jazz, Art, Compiler, Vue",
41
- memberOf: "Member of",
42
- author: "作者",
43
- kingOf: "King of",
44
- chiefEngineerOf: "Chief Engineer of",
45
- contribute: "Contribute",
46
- blog: "Blog",
47
- github: "GitHub",
48
- twitter: "Twitter",
49
- discord: "Discord",
50
- sponsor: "Sponsor"
51
- }
52
- };
53
- function detectLocale() {
54
- const args = process.argv.slice(2);
55
- if (args.includes("--ja") || args.includes("-j") || args.includes("--japanese")) return "ja";
56
- if (args.includes("--en") || args.includes("-e") || args.includes("--english")) return "en";
57
- if ((process.env.LANG || process.env.LANGUAGE || process.env.LC_ALL || "").toLowerCase().startsWith("ja")) return "ja";
58
- return "en";
59
- }
60
- const projects = [
61
- {
62
- name: "chibivue",
63
- url: "https://github.com/chibivue-land/chibivue"
64
- },
65
- {
66
- name: "reading-vuejs-core-vapor",
67
- url: "https://github.com/ubugeeei/reading-vuejs-core-vapor"
68
- },
69
- {
70
- name: "vize",
71
- url: "https://github.com/ubugeeei/vize"
72
- },
73
- {
74
- name: "ox-content",
75
- url: "https://github.com/ubugeeei/ox-content"
76
- },
77
- {
78
- name: "relanote",
79
- url: "https://github.com/ubugeeei/relanote"
80
- },
81
- {
82
- name: "learn.nuxt.com (ja)",
83
- url: "https://github.com/nuxt/learn.nuxt.com"
84
- },
85
- {
86
- name: "jp-vue-companies",
87
- url: "https://github.com/chibivue-land/japanese-companies-using-vuejs"
88
- }
89
- ];
90
- const contributes = [
91
- {
92
- name: "vuejs (mainly vapor)",
93
- url: "https://github.com/vuejs/core"
94
- },
95
- {
96
- name: "oxc",
97
- url: "https://github.com/oxc-project/oxc"
98
- },
99
- {
100
- name: "vuefes",
101
- url: "https://github.com/vuejs-jp/vuefes-2025"
102
- }
103
- ];
104
- function getDisplayWidth(str) {
105
- const clean = str.replace(/\x1b\[[0-9;]*m|\x1b\]8;;[^\x07]*\x07/g, "");
106
- let width = 0;
107
- for (const char of clean) {
108
- const code = char.codePointAt(0) || 0;
109
- if (code >= 4352 && code <= 4447 || code >= 11904 && code <= 40959 || code >= 44032 && code <= 55203 || code >= 63744 && code <= 64255 || code >= 65040 && code <= 65055 || code >= 65072 && code <= 65135 || code >= 65280 && code <= 65376 || code >= 65504 && code <= 65510 || code >= 127744 && code <= 129535 || code >= 131072 && code <= 196607) width += 2;
110
- else width += 1;
111
- }
112
- return width;
113
- }
114
- function padRight(str, targetWidth) {
115
- const padding = targetWidth - getDisplayWidth(str);
116
- return str + " ".repeat(Math.max(0, padding));
117
- }
118
- const WIDTH = 58;
119
- const INNER_WIDTH = WIDTH - 4;
120
- function createLine(content) {
121
- const border = COLORS.border;
122
- return `${border}│${RESET} ${padRight(content, INNER_WIDTH)} ${border}│${RESET}`;
123
- }
124
- function main() {
125
- const t = messages[detectLocale()];
126
- const border = COLORS.border;
127
- const topBorder = `${border}┌${"─".repeat(WIDTH - 2)}┐${RESET}`;
128
- const bottomBorder = `${border}└${"─".repeat(WIDTH - 2)}┘${RESET}`;
129
- const projectLinks = projects.map((p) => link(p.url, COLORS.dark + p.name + RESET));
130
- const contributeLinks = contributes.map((p) => link(p.url, COLORS.dark + p.name + RESET));
131
- const lines = [
132
- "",
133
- topBorder,
134
- createLine(""),
135
- createLine(`${BOLD}${COLORS.black}${t.name}${RESET} ${COLORS.gray}(${t.nickname})${RESET}`),
136
- createLine(`${COLORS.light}${t.tagline}${RESET}`),
137
- createLine(""),
138
- createLine(`${COLORS.gray}Fav:${RESET}`),
139
- createLine(`${COLORS.light}${t.interests}${RESET}`),
140
- createLine(""),
141
- createLine(`${COLORS.gray}${t.memberOf}:${RESET}`),
142
- createLine(`${link("https://vuejs.org", COLORS.dark + "Vue" + RESET)} ${link("https://vuejs-jp.org", COLORS.dark + "Vue.js JP" + RESET)}`),
143
- createLine(""),
144
- createLine(`${COLORS.gray}${t.kingOf}:${RESET}`),
145
- createLine(`${link("https://chibivue.land", COLORS.dark + "chibivue.land" + RESET)}`),
146
- createLine(""),
147
- createLine(`${COLORS.gray}${t.chiefEngineerOf}:${RESET}`),
148
- createLine(`${link("https://github.com/mates-system", COLORS.dark + "@mates-system" + RESET)}`),
149
- createLine(""),
150
- createLine(`${COLORS.gray}${t.author}:${RESET}`),
151
- createLine(`${projectLinks.slice(0, 2).join(", ")}`),
152
- createLine(`${projectLinks.slice(2, 5).join(", ")}`),
153
- createLine(`${projectLinks.slice(5).join(", ")}`),
154
- createLine(""),
155
- createLine(`${COLORS.gray}${t.contribute}:${RESET}`),
156
- createLine(`${contributeLinks.join(", ")}`),
157
- createLine(""),
158
- createLine(`${COLORS.gray}${t.blog}:${RESET}`),
159
- createLine(`${link("https://wtrclred.io", COLORS.dark + "wtrclred.io" + RESET)}`),
160
- createLine(""),
161
- createLine(`${COLORS.gray}GitHub:${RESET} ${link("https://github.com/ubugeeei", COLORS.dark + "github.com/ubugeeei" + RESET)}`),
162
- createLine(`${COLORS.gray}Twitter:${RESET} ${link("https://x.com/ubugeeei", COLORS.dark + "@ubugeeei" + RESET)}`),
163
- createLine(`${COLORS.gray}Discord:${RESET} ${link("https://discord.com/users/ubugeeei", COLORS.dark + "ubugeeei" + RESET)}`),
164
- createLine(`${COLORS.gray}Sponsor:${RESET} ${link("https://github.com/sponsors/ubugeeei", COLORS.dark + "github.com/sponsors/ubugeeei" + RESET)}`),
165
- createLine(""),
166
- bottomBorder,
167
- ""
168
- ];
169
- console.log(lines.join("\n"));
170
- }
171
- main();
172
-
173
- //#endregion
174
- export { };
package/index.js DELETED
@@ -1,2 +0,0 @@
1
- // This package is a CLI tool. Run with: npx ubugeeei
2
- export default {};