sh-ui-cli 0.114.0 → 0.116.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/bin/sh-ui.mjs +70 -3
- package/data/changelog/versions.json +26 -0
- package/data/registry/react/components/rich-text-editor/index.module.tsx +523 -171
- package/data/registry/react/components/rich-text-editor/index.tailwind.tsx +596 -70
- package/data/registry/react/components/rich-text-editor/index.tsx +523 -171
- package/data/registry/react/components/rich-text-editor/styles.css +103 -5
- package/data/registry/react/components/rich-text-editor/styles.module.css +103 -5
- package/data/registry/react/registry.json +319 -963
- package/data/registry/react/tokens-used.json +4 -1
- package/package.json +1 -1
- package/src/add.mjs +31 -1
- package/src/commands.mjs +6 -0
- package/src/create/generator.js +4 -0
- package/src/doctor.mjs +14 -0
- package/src/init.mjs +19 -0
- package/src/levenshtein.mjs +36 -0
- package/src/list.mjs +13 -0
- package/src/mcp.mjs +14 -0
- package/src/migrate-bundled.mjs +14 -0
- package/src/migrate-v065.mjs +14 -0
- package/src/remove.mjs +15 -0
- package/src/rename-app.mjs +15 -0
- package/src/theme-extract.mjs +13 -0
- package/src/tokens-cmd.mjs +12 -0
- package/src/upgrade-cli.mjs +13 -0
package/bin/sh-ui.mjs
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { init } from "../src/init.mjs";
|
|
2
|
+
import { init, HELP_TEXT as INIT_HELP } from "../src/init.mjs";
|
|
3
3
|
import { add } from "../src/add.mjs";
|
|
4
4
|
import { list } from "../src/list.mjs";
|
|
5
5
|
import { remove } from "../src/remove.mjs";
|
|
6
6
|
import { findShUiContext } from "../src/resolve-context.mjs";
|
|
7
|
+
import { suggest } from "../src/levenshtein.mjs";
|
|
8
|
+
import { KNOWN_COMMANDS } from "../src/commands.mjs";
|
|
7
9
|
|
|
8
10
|
const [, , cmd, ...rest] = process.argv;
|
|
9
11
|
|
|
@@ -36,6 +38,9 @@ const usage = `사용법:
|
|
|
36
38
|
sh-ui mcp MCP 서버(stdio) 시작 — IDE-내 AI용
|
|
37
39
|
sh-ui mcp init --client <name> IDE MCP 설정 파일에 sh-ui 엔트리 자동 추가
|
|
38
40
|
(claude-code | cursor | claude-desktop | codex)
|
|
41
|
+
|
|
42
|
+
각 명령의 상세 옵션은 \`sh-ui <command> --help\` 로 확인.
|
|
43
|
+
|
|
39
44
|
옵션:
|
|
40
45
|
--skip-install (add, rename-app) 외부 패키지 자동 설치 생략
|
|
41
46
|
--diff (add) 파일을 쓰지 않고 변경 내역만 출력
|
|
@@ -57,9 +62,18 @@ try {
|
|
|
57
62
|
break;
|
|
58
63
|
}
|
|
59
64
|
case "init":
|
|
65
|
+
if (rest.includes("--help") || rest.includes("-h")) {
|
|
66
|
+
console.log(INIT_HELP);
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
60
69
|
await init({ cwd: process.cwd(), args: rest });
|
|
61
70
|
break;
|
|
62
71
|
case "add": {
|
|
72
|
+
if (rest.includes("--help") || rest.includes("-h")) {
|
|
73
|
+
const { HELP_TEXT } = await import("../src/add.mjs");
|
|
74
|
+
console.log(HELP_TEXT);
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
63
77
|
const skipInstall = rest.includes("--skip-install");
|
|
64
78
|
const diffMode = rest.includes("--diff");
|
|
65
79
|
const force = rest.includes("--force");
|
|
@@ -107,11 +121,21 @@ try {
|
|
|
107
121
|
break;
|
|
108
122
|
}
|
|
109
123
|
case "list": {
|
|
124
|
+
if (rest.includes("--help") || rest.includes("-h")) {
|
|
125
|
+
const { HELP_TEXT } = await import("../src/list.mjs");
|
|
126
|
+
console.log(HELP_TEXT);
|
|
127
|
+
break;
|
|
128
|
+
}
|
|
110
129
|
const all = rest.includes("--all");
|
|
111
130
|
await list({ cwd: process.cwd(), all });
|
|
112
131
|
break;
|
|
113
132
|
}
|
|
114
133
|
case "doctor": {
|
|
134
|
+
if (rest.includes("--help") || rest.includes("-h")) {
|
|
135
|
+
const { HELP_TEXT } = await import("../src/doctor.mjs");
|
|
136
|
+
console.log(HELP_TEXT);
|
|
137
|
+
break;
|
|
138
|
+
}
|
|
115
139
|
const { doctor } = await import("../src/doctor.mjs");
|
|
116
140
|
const { existsSync, readdirSync } = await import("node:fs");
|
|
117
141
|
const { resolve } = await import("node:path");
|
|
@@ -157,12 +181,22 @@ try {
|
|
|
157
181
|
break;
|
|
158
182
|
}
|
|
159
183
|
case "upgrade-cli": {
|
|
184
|
+
if (rest.includes("--help") || rest.includes("-h")) {
|
|
185
|
+
const { HELP_TEXT } = await import("../src/upgrade-cli.mjs");
|
|
186
|
+
console.log(HELP_TEXT);
|
|
187
|
+
break;
|
|
188
|
+
}
|
|
160
189
|
const apply = rest.includes("--apply");
|
|
161
190
|
const { runUpgradeCli } = await import("../src/upgrade-cli.mjs");
|
|
162
191
|
await runUpgradeCli({ cwd: process.cwd(), apply });
|
|
163
192
|
break;
|
|
164
193
|
}
|
|
165
194
|
case "theme": {
|
|
195
|
+
if (rest.includes("--help") || rest.includes("-h")) {
|
|
196
|
+
const { HELP_TEXT } = await import("../src/theme-extract.mjs");
|
|
197
|
+
console.log(HELP_TEXT);
|
|
198
|
+
break;
|
|
199
|
+
}
|
|
166
200
|
const sub = rest[0];
|
|
167
201
|
const flags = rest.slice(1);
|
|
168
202
|
if (sub === "extract") {
|
|
@@ -177,6 +211,11 @@ try {
|
|
|
177
211
|
break;
|
|
178
212
|
}
|
|
179
213
|
case "tokens": {
|
|
214
|
+
if (rest.includes("--help") || rest.includes("-h")) {
|
|
215
|
+
const { HELP_TEXT } = await import("../src/tokens-cmd.mjs");
|
|
216
|
+
console.log(HELP_TEXT);
|
|
217
|
+
break;
|
|
218
|
+
}
|
|
180
219
|
// sh-ui tokens diff
|
|
181
220
|
// sh-ui tokens upgrade --apply | --replace
|
|
182
221
|
const sub = rest[0];
|
|
@@ -210,6 +249,12 @@ try {
|
|
|
210
249
|
case "mcp": {
|
|
211
250
|
// `sh-ui mcp init ...` → 설정 파일에 엔트리 추가
|
|
212
251
|
// `sh-ui mcp` → MCP 서버 시작
|
|
252
|
+
// 단, `sh-ui mcp --help` 는 mcp HELP_TEXT 출력 (mcp init 의 인자 처리는 mcp-init.mjs 가 담당).
|
|
253
|
+
if (rest[0] !== "init" && (rest.includes("--help") || rest.includes("-h"))) {
|
|
254
|
+
const { HELP_TEXT } = await import("../src/mcp.mjs");
|
|
255
|
+
console.log(HELP_TEXT);
|
|
256
|
+
break;
|
|
257
|
+
}
|
|
213
258
|
if (rest[0] === "init") {
|
|
214
259
|
const { mcpInit } = await import("../src/mcp-init.mjs");
|
|
215
260
|
await mcpInit({ cwd: process.cwd(), args: rest.slice(1) });
|
|
@@ -220,6 +265,11 @@ try {
|
|
|
220
265
|
break;
|
|
221
266
|
}
|
|
222
267
|
case "rename-app": {
|
|
268
|
+
if (rest.includes("--help") || rest.includes("-h")) {
|
|
269
|
+
const { HELP_TEXT } = await import("../src/rename-app.mjs");
|
|
270
|
+
console.log(HELP_TEXT);
|
|
271
|
+
break;
|
|
272
|
+
}
|
|
223
273
|
const yes = rest.includes("--yes");
|
|
224
274
|
const dryRun = rest.includes("--dry-run");
|
|
225
275
|
const skipInstall = rest.includes("--skip-install");
|
|
@@ -235,6 +285,11 @@ try {
|
|
|
235
285
|
break;
|
|
236
286
|
}
|
|
237
287
|
case "migrate": {
|
|
288
|
+
if (rest.includes("--help") || rest.includes("-h")) {
|
|
289
|
+
const { HELP_TEXT } = await import("../src/migrate-bundled.mjs");
|
|
290
|
+
console.log(HELP_TEXT);
|
|
291
|
+
break;
|
|
292
|
+
}
|
|
238
293
|
// sh-ui migrate bundled [--apply] [--bundle <path>]
|
|
239
294
|
const sub = rest[0];
|
|
240
295
|
const flags = rest.slice(1);
|
|
@@ -251,6 +306,11 @@ try {
|
|
|
251
306
|
break;
|
|
252
307
|
}
|
|
253
308
|
case "migrate-v065": {
|
|
309
|
+
if (rest.includes("--help") || rest.includes("-h")) {
|
|
310
|
+
const { HELP_TEXT } = await import("../src/migrate-v065.mjs");
|
|
311
|
+
console.log(HELP_TEXT);
|
|
312
|
+
break;
|
|
313
|
+
}
|
|
254
314
|
const apply = rest.includes("--apply");
|
|
255
315
|
const skipImportRewrite = rest.includes("--skip-import-rewrite");
|
|
256
316
|
const { migrateToV065 } = await import("../src/migrate-v065.mjs");
|
|
@@ -264,6 +324,11 @@ try {
|
|
|
264
324
|
}
|
|
265
325
|
case "remove":
|
|
266
326
|
case "rm": {
|
|
327
|
+
if (rest.includes("--help") || rest.includes("-h")) {
|
|
328
|
+
const { HELP_TEXT } = await import("../src/remove.mjs");
|
|
329
|
+
console.log(HELP_TEXT);
|
|
330
|
+
break;
|
|
331
|
+
}
|
|
267
332
|
const force = rest.includes("--force");
|
|
268
333
|
const dryRun = rest.includes("--dry-run");
|
|
269
334
|
const names = rest.filter((a) => !a.startsWith("--"));
|
|
@@ -280,10 +345,12 @@ try {
|
|
|
280
345
|
case "--help":
|
|
281
346
|
console.log(usage);
|
|
282
347
|
break;
|
|
283
|
-
default:
|
|
284
|
-
|
|
348
|
+
default: {
|
|
349
|
+
const hits = suggest(cmd, KNOWN_COMMANDS);
|
|
350
|
+
console.error(`알 수 없는 명령: ${cmd}` + (hits.length ? ` — 혹시 ${hits.join(", ")}?` : "") + "\n");
|
|
285
351
|
console.error(usage);
|
|
286
352
|
process.exit(1);
|
|
353
|
+
}
|
|
287
354
|
}
|
|
288
355
|
} catch (err) {
|
|
289
356
|
console.error(`✗ ${err.message}`);
|
|
@@ -2,6 +2,32 @@
|
|
|
2
2
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
3
|
"$description": "sh-ui 릴리즈 노트 단일 소스. docs(React)와 showcase(Flutter)가 함께 읽는다. 새 릴리즈마다 맨 앞에 추가.",
|
|
4
4
|
"versions": [
|
|
5
|
+
{
|
|
6
|
+
"version": "0.116.0",
|
|
7
|
+
"date": "2026-06-17",
|
|
8
|
+
"title": "CLI 발견성 — 서브명령 --help + 오타 추천",
|
|
9
|
+
"type": "minor",
|
|
10
|
+
"highlights": [
|
|
11
|
+
"모든 서브명령에 --help — init·add·remove·doctor·tokens·theme·migrate·rename-app·upgrade-cli·mcp 전용 도움말",
|
|
12
|
+
"did-you-mean — 없는 컴포넌트/명령 입력 시 가까운 후보를 '혹시 …?' 로 제안",
|
|
13
|
+
"의존성 없는 levenshtein 유틸 내장 (packages/cli/src/levenshtein.mjs)"
|
|
14
|
+
],
|
|
15
|
+
"url": "https://github.com/sanghyeonKim0201/sh-ui/releases/tag/v0.116.0"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"version": "0.115.0",
|
|
19
|
+
"date": "2026-06-01",
|
|
20
|
+
"title": "rich-text-editor — 밑줄·텍스트 컬러·인라인 링크 편집 + compact·focus 툴바 + i18n 라벨",
|
|
21
|
+
"type": "minor",
|
|
22
|
+
"highlights": [
|
|
23
|
+
"**밑줄 + 텍스트 컬러** — Underline 버튼(v3 StarterKit 내장)과 글자색 팔레트를 툴바에 추가. 색은 하드 hex 가 아니라 CSS 변수(`var(--sh-ui-rte-c-moss|red|orange|blue)`)로 저장돼 라이트/다크 테마를 추종한다. 변수 정의부는 `styles.css`/`styles.module.css`(plain·css-modules) 와 런타임 주입 스타일(tailwind) — 세 variant 모두 동일하게 동작. moss 는 accent 토큰과 맞춘 톤.",
|
|
24
|
+
"**인라인 링크 편집** — 기존 `window.prompt` 를 제거하고 툴바 아래로 펼쳐지는 인라인 입력 행으로 교체(URL 입력 + 적용/제거/취소 아이콘, Enter 적용·Esc 취소). 메일 클라이언트식 UX. 읽기 전용일 때만 링크가 클릭으로 열리고(`openOnClick`), 편집 중엔 이탈 방지.",
|
|
25
|
+
"**`compact` + `toolbarMode=\"focus\"`** — `compact` 는 핵심 버튼(굵게·기울임·밑줄·취소선·글자색·링크·목록)만 노출해 좁은 패널에 맞춘다. `toolbarMode=\"focus\"` 는 포커스 전 툴바를 숨겨 인라인 입력처럼 보이게 한다. 포커스 추적은 래퍼의 `focusin`/`focusout`(relatedTarget 가드)으로 처리 — 링크 입력·컬러 스와치로 포커스가 옮겨가도 패널이 닫히지 않는다.",
|
|
26
|
+
"**활성표시 반응성 + i18n** — 툴바를 `useEditorState` 로 트랜잭션마다 구독해 굵게/밑줄 등 활성 상태가 즉시 반영된다(v3 `useEditor` 는 기본적으로 트랜잭션마다 리렌더하지 않음). `labels` prop(`RichTextEditorLabels`)으로 모든 버튼 라벨/툴팁을 현지화 가능 — 누락 키는 영어 기본값으로 폴백.",
|
|
27
|
+
"**의존성** — `@tiptap/extension-text-style` 추가(`TextStyle` + `Color` 제공). 설치: `pnpm add @tiptap/extension-text-style`. 기존 RTE 사용처는 변경 없이 동작(신규 props 전부 optional)."
|
|
28
|
+
],
|
|
29
|
+
"url": "https://github.com/sanghyeonKim0201/sh-ui/releases/tag/v0.115.0"
|
|
30
|
+
},
|
|
5
31
|
{
|
|
6
32
|
"version": "0.114.0",
|
|
7
33
|
"date": "2026-05-27",
|