sh-ui-cli 0.82.3 → 0.84.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.
@@ -2,6 +2,31 @@
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.84.0",
7
+ "date": "2026-05-13",
8
+ "title": "Sidebar — Brand 컴파운드 primitive (브랜드 카드 · 워크스페이스 스위처 · 유저 프로필)",
9
+ "type": "minor",
10
+ "highlights": [
11
+ "**`SidebarBrand` 컴파운드 primitive 신설 — 브랜드 카드 / 워크스페이스 스위처 / 유저 프로필 의 90% 를 커버** — `<SidebarHeader>` / `<SidebarFooter>` 안에서 매번 박던 패턴 (icon + title + subtitle + trailing chevron) 을 단일 합성으로. Card/Dialog 와 동일한 separate-exports 컨벤션.",
12
+ "**Exports (6개)**: `SidebarBrand` (행 wrapper, 내부 `data-when-collapsed=\"center\"` 자동 적용) · `SidebarBrandIcon` (항상 visible, collapsed 시 sole 요소) · `SidebarBrandText` (`data-when-collapsed=\"hide\"`) · `SidebarBrandTitle` (단일 줄 본문, truncate 내장) · `SidebarBrandSubtitle` (보조 줄, foreground-muted) · `SidebarBrandAction` (`data-when-collapsed=\"hide\"`, ml-auto trailing icon).",
13
+ "**v0.83.0 의 `data-when-collapsed` 컨벤션 내장** — 사용자가 attribute 박지 않아도 collapsible=\"icon\" 모드 전환 시 자동 적응. 인터랙티브 케이스는 `<DropdownMenuTrigger render={<button data-when-collapsed=\"strip-chrome\" />}>` 로 wrap.",
14
+ "**3 변종 모두 지원** — plain `styles.css` / module `styles.module.css` 에 룰 직접, tailwind 변종은 utility 클래스로 동등 스타일. 듀얼카피 (apps/docs) 동기화."
15
+ ],
16
+ "url": "https://github.com/sanghyeonKim0201/sh-ui/releases/tag/v0.84.0"
17
+ },
18
+ {
19
+ "version": "0.83.0",
20
+ "date": "2026-05-13",
21
+ "title": "Sidebar — data-when-collapsed 컨벤션 (custom JSX 의 collapsed/icon 자동 적응)",
22
+ "type": "minor",
23
+ "highlights": [
24
+ "**`<SidebarHeader>` / `<SidebarFooter>` 안 사용자 custom JSX 가 `collapsible=\"icon\"` 모드 전환 시 `useSidebar()` 훅 + 조건부 렌더 ceremony 없이 attribute 한 줄로 자동 적응** — 새 export 0개, 발견성 좋은 plain CSS 컨벤션. 값 (공백 구분 다중 토큰, `~=` 매처): `hide` (display:none) · `center` (가운데 정렬 + 좌우 padding 제거) · `strip-chrome` (border / background 투명). 워크스페이스 스위처 · 브랜드 카드 · 유저 프로필 등 admin/dashboard sidebar 의 흔한 패턴에 매번 박던 수동 처리 일소.",
25
+ "예시 — `<button data-when-collapsed=\"center strip-chrome\"> <Avatar /> <div data-when-collapsed=\"hide\">{name}</div> <ChevronsUpDown data-when-collapsed=\"hide\" /></button>` — collapsed 모드에선 Avatar 만 가운데 정렬돼 보이고 카드 chrome 사라짐.",
26
+ "**3 변종 모두 지원** — plain `styles.css` / module `styles.module.css` 에 직접 룰. tailwind 변종은 CSS import 없어 `SidebarProvider` mount 시 1회 head 에 `<style id=\"sh-ui-sidebar-helpers\">` inject (모듈 레벨 dedup). 사용자 코드는 변종 무관 동일 attribute 만 박으면 됨."
27
+ ],
28
+ "url": "https://github.com/sanghyeonKim0201/sh-ui/releases/tag/v0.83.0"
29
+ },
5
30
  {
6
31
  "version": "0.82.3",
7
32
  "date": "2026-05-13",
@@ -511,6 +511,66 @@ export function SidebarFooter({ className, ...props }: React.HTMLAttributes<HTML
511
511
  );
512
512
  }
513
513
 
514
+ /* ───────────── Brand (compound primitive, v0.84.0+) ─────────────
515
+ * data-when-collapsed 컨벤션 내장. plain 변종 주석 참고. */
516
+
517
+ export function SidebarBrand({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
518
+ return (
519
+ <div
520
+ data-when-collapsed="center"
521
+ className={cn(styles.sidebar__brand, className)}
522
+ {...props}
523
+ />
524
+ );
525
+ }
526
+
527
+ export function SidebarBrandIcon({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
528
+ return (
529
+ <div
530
+ className={cn(styles.sidebar__brand_icon, className)}
531
+ {...props}
532
+ />
533
+ );
534
+ }
535
+
536
+ export function SidebarBrandText({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
537
+ return (
538
+ <div
539
+ data-when-collapsed="hide"
540
+ className={cn(styles.sidebar__brand_text, className)}
541
+ {...props}
542
+ />
543
+ );
544
+ }
545
+
546
+ export function SidebarBrandTitle({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
547
+ return (
548
+ <div
549
+ className={cn(styles.sidebar__brand_title, className)}
550
+ {...props}
551
+ />
552
+ );
553
+ }
554
+
555
+ export function SidebarBrandSubtitle({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
556
+ return (
557
+ <div
558
+ className={cn(styles.sidebar__brand_subtitle, className)}
559
+ {...props}
560
+ />
561
+ );
562
+ }
563
+
564
+ export function SidebarBrandAction({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
565
+ return (
566
+ <div
567
+ data-when-collapsed="hide"
568
+ className={cn(styles.sidebar__brand_action, className)}
569
+ {...props}
570
+ />
571
+ );
572
+ }
573
+
514
574
  /** Sidebar의 스크롤 영역. 메뉴/그룹 목록을 둔다. */
515
575
  export function SidebarContent({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
516
576
  return (
@@ -10,6 +10,29 @@ const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7;
10
10
  const SIDEBAR_KEYBOARD_SHORTCUT = "b";
11
11
  const MOBILE_BREAKPOINT = 768;
12
12
 
13
+ /**
14
+ * v0.83.0+ — `data-when-collapsed` 컨벤션을 위한 CSS 룰 inject.
15
+ *
16
+ * plain/module 변종은 styles.css/.module.css 가 import 되며 자동으로 룰이 깔리는데,
17
+ * tailwind 변종은 별도 CSS import 가 없으므로 SidebarProvider mount 시 한 번만 head
18
+ * 에 <style> 박는다. id="sh-ui-sidebar-helpers" 로 중복 inject 방지.
19
+ *
20
+ * 토큰: hide(display:none) · center(가운데 정렬 + 좌우 padding 0) · strip-chrome
21
+ * (border/bg 투명). `~=` 매처로 공백 구분 다중 토큰 지원.
22
+ */
23
+ const SIDEBAR_HELPER_STYLE_ID = "sh-ui-sidebar-helpers";
24
+ const SIDEBAR_HELPER_CSS = `[data-state="collapsed"][data-collapsible="icon"] [data-when-collapsed~="hide"]{display:none}[data-state="collapsed"][data-collapsible="icon"] [data-when-collapsed~="center"]{justify-content:center;padding-left:0;padding-right:0}[data-state="collapsed"][data-collapsible="icon"] [data-when-collapsed~="strip-chrome"]{border-color:transparent;background-color:transparent}`;
25
+ function useSidebarHelperStyles() {
26
+ React.useEffect(() => {
27
+ if (typeof document === "undefined") return;
28
+ if (document.getElementById(SIDEBAR_HELPER_STYLE_ID)) return;
29
+ const style = document.createElement("style");
30
+ style.id = SIDEBAR_HELPER_STYLE_ID;
31
+ style.textContent = SIDEBAR_HELPER_CSS;
32
+ document.head.appendChild(style);
33
+ }, []);
34
+ }
35
+
13
36
  const FOCUSABLE_SELECTOR =
14
37
  'a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex="-1"])';
15
38
 
@@ -77,6 +100,7 @@ export interface SidebarProviderProps extends React.HTMLAttributes<HTMLDivElemen
77
100
  export function SidebarProvider({
78
101
  defaultOpen = true, open: openProp, onOpenChange: setOpenProp, className, style, children, embedded, ...props
79
102
  }: SidebarProviderProps) {
103
+ useSidebarHelperStyles();
80
104
  const isMobile = useIsMobile();
81
105
  const [openMobile, setOpenMobile] = React.useState(false);
82
106
  const [_open, _setOpen] = React.useState(defaultOpen);
@@ -328,6 +352,66 @@ export function SidebarFooter({ className, ...props }: React.HTMLAttributes<HTML
328
352
  return <div className={cn("flex flex-col gap-[var(--space-2)] p-[var(--space-2)] overflow-hidden", className)} {...props} />;
329
353
  }
330
354
 
355
+ /* ───────────── Brand (compound primitive, v0.84.0+) ─────────────
356
+ * data-when-collapsed 컨벤션 내장. plain 변종 주석 참고. */
357
+
358
+ export function SidebarBrand({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
359
+ return (
360
+ <div
361
+ data-when-collapsed="center"
362
+ className={cn("flex flex-row items-center gap-[var(--space-2)] px-[var(--space-2)] py-[var(--space-2)] rounded-[var(--radius)] min-w-0", className)}
363
+ {...props}
364
+ />
365
+ );
366
+ }
367
+
368
+ export function SidebarBrandIcon({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
369
+ return (
370
+ <div
371
+ className={cn("flex items-center justify-center shrink-0 size-8 rounded-[calc(var(--radius)-2px)]", className)}
372
+ {...props}
373
+ />
374
+ );
375
+ }
376
+
377
+ export function SidebarBrandText({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
378
+ return (
379
+ <div
380
+ data-when-collapsed="hide"
381
+ className={cn("flex flex-col flex-1 min-w-0 gap-0", className)}
382
+ {...props}
383
+ />
384
+ );
385
+ }
386
+
387
+ export function SidebarBrandTitle({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
388
+ return (
389
+ <div
390
+ className={cn("text-[length:var(--text-sm)] font-[var(--weight-medium)] leading-tight truncate text-[color:var(--sidebar-fg)]", className)}
391
+ {...props}
392
+ />
393
+ );
394
+ }
395
+
396
+ export function SidebarBrandSubtitle({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
397
+ return (
398
+ <div
399
+ className={cn("text-[length:var(--text-xs)] leading-tight truncate text-[color:var(--foreground-muted)]", className)}
400
+ {...props}
401
+ />
402
+ );
403
+ }
404
+
405
+ export function SidebarBrandAction({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
406
+ return (
407
+ <div
408
+ data-when-collapsed="hide"
409
+ className={cn("ml-auto shrink-0 flex items-center justify-center", className)}
410
+ {...props}
411
+ />
412
+ );
413
+ }
414
+
331
415
  export function SidebarContent({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
332
416
  return <div className={cn("flex flex-col flex-1 min-h-0 overflow-y-auto gap-0", className)} {...props} />;
333
417
  }
@@ -521,6 +521,92 @@ export function SidebarFooter({ className, ...props }: React.HTMLAttributes<HTML
521
521
  );
522
522
  }
523
523
 
524
+ /* ───────────── Brand (compound primitive, v0.84.0+) ─────────────
525
+ * SidebarHeader / SidebarFooter 의 흔한 패턴 (브랜드 카드 · 워크스페이스 스위처 ·
526
+ * 유저 프로필) 의 90% 를 커버. data-when-collapsed 컨벤션을 내장해 사용자가
527
+ * attribute 박지 않아도 collapsed/icon 모드 자동 적응.
528
+ *
529
+ * 정적 예시:
530
+ * <SidebarBrand>
531
+ * <SidebarBrandIcon><Logo /></SidebarBrandIcon>
532
+ * <SidebarBrandText>
533
+ * <SidebarBrandTitle>Atlas</SidebarBrandTitle>
534
+ * <SidebarBrandSubtitle>workspace</SidebarBrandSubtitle>
535
+ * </SidebarBrandText>
536
+ * </SidebarBrand>
537
+ *
538
+ * 인터랙티브 (워크스페이스 스위처):
539
+ * <DropdownMenu>
540
+ * <DropdownMenuTrigger render={<button data-when-collapsed='strip-chrome' />}>
541
+ * <SidebarBrand>...</SidebarBrand>
542
+ * </DropdownMenuTrigger>
543
+ * ...
544
+ * </DropdownMenu>
545
+ */
546
+
547
+ /** 브랜드 행 wrapper. collapsed 일 땐 가운데 정렬 + 좌우 padding 0 (data-when-collapsed=center 내장). */
548
+ export function SidebarBrand({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
549
+ return (
550
+ <div
551
+ data-when-collapsed="center"
552
+ className={cn("sh-ui-sidebar__brand", className)}
553
+ {...props}
554
+ />
555
+ );
556
+ }
557
+
558
+ /** 항상 visible 한 아이콘 슬롯. collapsed 일 땐 SidebarBrand 의 유일한 요소. */
559
+ export function SidebarBrandIcon({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
560
+ return (
561
+ <div
562
+ className={cn("sh-ui-sidebar__brand-icon", className)}
563
+ {...props}
564
+ />
565
+ );
566
+ }
567
+
568
+ /** 텍스트 컨테이너. collapsed 일 땐 hidden (data-when-collapsed=hide 내장). */
569
+ export function SidebarBrandText({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
570
+ return (
571
+ <div
572
+ data-when-collapsed="hide"
573
+ className={cn("sh-ui-sidebar__brand-text", className)}
574
+ {...props}
575
+ />
576
+ );
577
+ }
578
+
579
+ /** 단일 줄 본문 (편의) — sh-ui-sidebar__brand-title 클래스만 박는다. */
580
+ export function SidebarBrandTitle({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
581
+ return (
582
+ <div
583
+ className={cn("sh-ui-sidebar__brand-title", className)}
584
+ {...props}
585
+ />
586
+ );
587
+ }
588
+
589
+ /** 보조 줄 — sh-ui-sidebar__brand-subtitle. text-foreground-muted + text-xs. */
590
+ export function SidebarBrandSubtitle({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
591
+ return (
592
+ <div
593
+ className={cn("sh-ui-sidebar__brand-subtitle", className)}
594
+ {...props}
595
+ />
596
+ );
597
+ }
598
+
599
+ /** Trailing icon (드롭다운 chevron 등). collapsed 일 땐 hidden. */
600
+ export function SidebarBrandAction({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
601
+ return (
602
+ <div
603
+ data-when-collapsed="hide"
604
+ className={cn("sh-ui-sidebar__brand-action", className)}
605
+ {...props}
606
+ />
607
+ );
608
+ }
609
+
524
610
  /** Sidebar의 스크롤 영역. 메뉴/그룹 목록을 둔다. */
525
611
  export function SidebarContent({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
526
612
  return (
@@ -288,6 +288,87 @@
288
288
  border-bottom: 1px solid var(--sidebar-border);
289
289
  }
290
290
 
291
+ /* ───────────── data-when-collapsed 컨벤션 (v0.83.0+) ─────────────
292
+ * SidebarHeader / SidebarFooter 안의 사용자 custom JSX (WorkspaceSwitcher,
293
+ * 브랜드 카드, 유저 프로필 등) 가 collapsible="icon" 모드 전환 시 자동
294
+ * 적응하도록 일반 attribute 컨벤션 제공. 사용자가 useSidebar() 훅 + 조건부
295
+ * 렌더 ceremony 없이 attribute 한 줄로 처리.
296
+ *
297
+ * 사용:
298
+ * <button data-when-collapsed="center strip-chrome">
299
+ * <Avatar />
300
+ * <div data-when-collapsed="hide">{name}</div>
301
+ * <ChevronsUpDown data-when-collapsed="hide" />
302
+ * </button>
303
+ *
304
+ * 값(공백 구분 토큰 — `~=` 매처):
305
+ * hide — collapsed/icon 모드에서 display:none
306
+ * center — 가로 가운데 정렬 + 좌우 padding 제거
307
+ * strip-chrome — border / background 투명화 (카드 chrome 제거) */
308
+ .sh-ui-sidebar[data-state="collapsed"][data-collapsible="icon"] [data-when-collapsed~="hide"] {
309
+ display: none;
310
+ }
311
+ .sh-ui-sidebar[data-state="collapsed"][data-collapsible="icon"] [data-when-collapsed~="center"] {
312
+ justify-content: center;
313
+ padding-left: 0;
314
+ padding-right: 0;
315
+ }
316
+ .sh-ui-sidebar[data-state="collapsed"][data-collapsible="icon"] [data-when-collapsed~="strip-chrome"] {
317
+ border-color: transparent;
318
+ background-color: transparent;
319
+ }
320
+
321
+ /* ───────────── Brand (compound primitive, v0.84.0+) ───────────── */
322
+ .sh-ui-sidebar__brand {
323
+ display: flex;
324
+ flex-direction: row;
325
+ align-items: center;
326
+ gap: var(--space-2);
327
+ padding: var(--space-2);
328
+ border-radius: var(--radius);
329
+ min-width: 0;
330
+ }
331
+ .sh-ui-sidebar__brand-icon {
332
+ display: flex;
333
+ align-items: center;
334
+ justify-content: center;
335
+ flex-shrink: 0;
336
+ width: 2rem;
337
+ height: 2rem;
338
+ border-radius: calc(var(--radius) - 2px);
339
+ }
340
+ .sh-ui-sidebar__brand-text {
341
+ display: flex;
342
+ flex-direction: column;
343
+ flex: 1 1 0%;
344
+ min-width: 0;
345
+ gap: 0;
346
+ }
347
+ .sh-ui-sidebar__brand-title {
348
+ font-size: var(--text-sm);
349
+ font-weight: var(--weight-medium);
350
+ line-height: 1.25;
351
+ color: var(--sidebar-fg);
352
+ white-space: nowrap;
353
+ overflow: hidden;
354
+ text-overflow: ellipsis;
355
+ }
356
+ .sh-ui-sidebar__brand-subtitle {
357
+ font-size: var(--text-xs);
358
+ line-height: 1.25;
359
+ color: var(--foreground-muted);
360
+ white-space: nowrap;
361
+ overflow: hidden;
362
+ text-overflow: ellipsis;
363
+ }
364
+ .sh-ui-sidebar__brand-action {
365
+ margin-left: auto;
366
+ flex-shrink: 0;
367
+ display: flex;
368
+ align-items: center;
369
+ justify-content: center;
370
+ }
371
+
291
372
  .sh-ui-sidebar__content {
292
373
  display: flex;
293
374
  flex-direction: column;
@@ -285,6 +285,73 @@
285
285
  border-bottom: 1px solid var(--sidebar-border);
286
286
  }
287
287
 
288
+ /* data-when-collapsed 컨벤션 (v0.83.0+) — 사용자 custom JSX (WorkspaceSwitcher 등) 가
289
+ * collapsible="icon" 모드 전환 시 자동 적응. 값: hide / center / strip-chrome.
290
+ * 자세한 설명은 plain 변종 styles.css 참고. */
291
+ .sidebar[data-state="collapsed"][data-collapsible="icon"] [data-when-collapsed~="hide"] {
292
+ display: none;
293
+ }
294
+ .sidebar[data-state="collapsed"][data-collapsible="icon"] [data-when-collapsed~="center"] {
295
+ justify-content: center;
296
+ padding-left: 0;
297
+ padding-right: 0;
298
+ }
299
+ .sidebar[data-state="collapsed"][data-collapsible="icon"] [data-when-collapsed~="strip-chrome"] {
300
+ border-color: transparent;
301
+ background-color: transparent;
302
+ }
303
+
304
+ /* ───────────── Brand (compound primitive, v0.84.0+) ───────────── */
305
+ .sidebar__brand {
306
+ display: flex;
307
+ flex-direction: row;
308
+ align-items: center;
309
+ gap: var(--space-2);
310
+ padding: var(--space-2);
311
+ border-radius: var(--radius);
312
+ min-width: 0;
313
+ }
314
+ .sidebar__brand_icon {
315
+ display: flex;
316
+ align-items: center;
317
+ justify-content: center;
318
+ flex-shrink: 0;
319
+ width: 2rem;
320
+ height: 2rem;
321
+ border-radius: calc(var(--radius) - 2px);
322
+ }
323
+ .sidebar__brand_text {
324
+ display: flex;
325
+ flex-direction: column;
326
+ flex: 1 1 0%;
327
+ min-width: 0;
328
+ gap: 0;
329
+ }
330
+ .sidebar__brand_title {
331
+ font-size: var(--text-sm);
332
+ font-weight: var(--weight-medium);
333
+ line-height: 1.25;
334
+ color: var(--sidebar-fg);
335
+ white-space: nowrap;
336
+ overflow: hidden;
337
+ text-overflow: ellipsis;
338
+ }
339
+ .sidebar__brand_subtitle {
340
+ font-size: var(--text-xs);
341
+ line-height: 1.25;
342
+ color: var(--foreground-muted);
343
+ white-space: nowrap;
344
+ overflow: hidden;
345
+ text-overflow: ellipsis;
346
+ }
347
+ .sidebar__brand_action {
348
+ margin-left: auto;
349
+ flex-shrink: 0;
350
+ display: flex;
351
+ align-items: center;
352
+ justify-content: center;
353
+ }
354
+
288
355
  .sidebar__content {
289
356
  display: flex;
290
357
  flex-direction: column;
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$description": "컴포넌트별 토큰 의존성 (var(--*) 추출). build-registry-tokens.mjs 가 자동 생성.",
3
- "$generated": "2026-05-12T23:53:11.079Z",
3
+ "$generated": "2026-05-13T03:22:30.348Z",
4
4
  "components": {
5
5
  "button": {
6
6
  "plain": [
@@ -678,6 +678,7 @@
678
678
  "--duration-fast",
679
679
  "--duration-slow",
680
680
  "--foreground",
681
+ "--foreground-muted",
681
682
  "--opacity-disabled",
682
683
  "--radius",
683
684
  "--shadow-xl",
@@ -688,6 +689,7 @@
688
689
  "--text-lg",
689
690
  "--text-sm",
690
691
  "--text-xs",
692
+ "--weight-medium",
691
693
  "--z-modal",
692
694
  "--z-overlay"
693
695
  ],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sh-ui-cli",
3
- "version": "0.82.3",
3
+ "version": "0.84.0",
4
4
  "description": "sh-ui CLI — 프로젝트 스캐폴드(create) + 컴포넌트 추가(add/list/remove) + IDE-내 AI용 MCP 서버",
5
5
  "license": "MIT",
6
6
  "repository": {