@hobui/viui-cli 0.0.6 → 0.0.7

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.
Files changed (240) hide show
  1. package/README.md +138 -139
  2. package/dist/adapters/adapter-registry.d.ts +12 -0
  3. package/dist/adapters/adapter-registry.d.ts.map +1 -0
  4. package/dist/adapters/adapter-registry.js +49 -0
  5. package/dist/adapters/adapter-types.d.ts +20 -0
  6. package/dist/adapters/adapter-types.d.ts.map +1 -0
  7. package/dist/adapters/adapter-types.js +1 -0
  8. package/dist/adapters/aider-adapter.d.ts +3 -0
  9. package/dist/adapters/aider-adapter.d.ts.map +1 -0
  10. package/dist/adapters/aider-adapter.js +8 -0
  11. package/dist/adapters/claude-adapter.d.ts +3 -0
  12. package/dist/adapters/claude-adapter.d.ts.map +1 -0
  13. package/dist/adapters/claude-adapter.js +15 -0
  14. package/dist/adapters/cline-adapter.d.ts +3 -0
  15. package/dist/adapters/cline-adapter.d.ts.map +1 -0
  16. package/dist/adapters/cline-adapter.js +8 -0
  17. package/dist/adapters/copilot-adapter.d.ts +5 -0
  18. package/dist/adapters/copilot-adapter.d.ts.map +1 -0
  19. package/dist/adapters/copilot-adapter.js +20 -0
  20. package/dist/adapters/cursor-adapter.d.ts +3 -0
  21. package/dist/adapters/cursor-adapter.d.ts.map +1 -0
  22. package/dist/adapters/cursor-adapter.js +18 -0
  23. package/dist/adapters/external/bolt-adapter.d.ts +3 -0
  24. package/dist/adapters/external/bolt-adapter.d.ts.map +1 -0
  25. package/dist/adapters/external/bolt-adapter.js +15 -0
  26. package/dist/adapters/external/chatgpt-adapter.d.ts +3 -0
  27. package/dist/adapters/external/chatgpt-adapter.d.ts.map +1 -0
  28. package/dist/adapters/external/chatgpt-adapter.js +14 -0
  29. package/dist/adapters/external/external-adapter-base.d.ts +15 -0
  30. package/dist/adapters/external/external-adapter-base.d.ts.map +1 -0
  31. package/dist/adapters/external/external-adapter-base.js +92 -0
  32. package/dist/adapters/external/gemini-adapter.d.ts +3 -0
  33. package/dist/adapters/external/gemini-adapter.d.ts.map +1 -0
  34. package/dist/adapters/external/gemini-adapter.js +14 -0
  35. package/dist/adapters/external/lovable-adapter.d.ts +3 -0
  36. package/dist/adapters/external/lovable-adapter.d.ts.map +1 -0
  37. package/dist/adapters/external/lovable-adapter.js +14 -0
  38. package/dist/adapters/external/v0-adapter.d.ts +3 -0
  39. package/dist/adapters/external/v0-adapter.d.ts.map +1 -0
  40. package/dist/adapters/external/v0-adapter.js +15 -0
  41. package/dist/adapters/windsurf-adapter.d.ts +3 -0
  42. package/dist/adapters/windsurf-adapter.d.ts.map +1 -0
  43. package/dist/adapters/windsurf-adapter.js +23 -0
  44. package/dist/assets/plugins/viui-conf/apply-theme-body.ts +23 -4
  45. package/dist/assets/plugins/viui-conf/defaults/README.md +2 -0
  46. package/dist/assets/plugins/viui-conf/defaults/app-bar.ts +1 -1
  47. package/dist/assets/plugins/viui-conf/defaults/buttons.ts +1 -1
  48. package/dist/assets/plugins/viui-conf/defaults/by-theme/minimalist-2.ts +1 -1
  49. package/dist/assets/plugins/viui-conf/defaults/cards.ts +1 -1
  50. package/dist/assets/plugins/viui-conf/defaults/expansion-panels.ts +16 -0
  51. package/dist/assets/plugins/viui-conf/defaults/index.ts +3 -0
  52. package/dist/assets/plugins/viui-conf/defaults/inputs.ts +11 -1
  53. package/dist/assets/plugins/viui-conf/design-tokens.ts +135 -0
  54. package/dist/assets/plugins/viui-conf/theme-base.ts +1 -1
  55. package/dist/assets/plugins/viui-conf/v-dark.ts +3 -5
  56. package/dist/assets/plugins/viui-conf/v-light.ts +3 -5
  57. package/dist/assets/plugins/vuetify.ts +36 -0
  58. package/dist/assets/prompt-data/components.json +106 -0
  59. package/dist/assets/prompt-data/tokens.json +83 -0
  60. package/dist/assets/themes/_bento-grid.scss +8 -0
  61. package/dist/assets/themes/_glassmorphism.scss +8 -0
  62. package/dist/assets/themes/_material.scss +8 -0
  63. package/dist/assets/themes/_minimalist-2.scss +375 -0
  64. package/dist/assets/themes/_minimalist.scss +9 -0
  65. package/dist/assets/themes/_neo-brutalism.scss +199 -0
  66. package/dist/assets/themes/bento-grid.scss +4 -0
  67. package/dist/assets/themes/glassmorphism.scss +4 -0
  68. package/dist/assets/themes/index.scss +11 -0
  69. package/dist/assets/themes/material.scss +4 -0
  70. package/dist/assets/themes/minimalist-2.scss +5 -0
  71. package/dist/assets/themes/minimalist.scss +4 -0
  72. package/dist/assets/themes/neo-brutalism.scss +5 -0
  73. package/dist/assets/viui-themes/_neo-brutalism.scss +70 -152
  74. package/dist/cli-paths.d.ts +7 -0
  75. package/dist/cli-paths.d.ts.map +1 -0
  76. package/dist/cli-paths.js +19 -0
  77. package/dist/cli.js +28 -578
  78. package/dist/cli.legacy.d.ts +3 -0
  79. package/dist/cli.legacy.d.ts.map +1 -0
  80. package/dist/cli.legacy.js +597 -0
  81. package/dist/commands/audit.d.ts +3 -0
  82. package/dist/commands/audit.d.ts.map +1 -0
  83. package/dist/commands/audit.js +152 -0
  84. package/dist/commands/config/config-export.d.ts +6 -0
  85. package/dist/commands/config/config-export.d.ts.map +1 -0
  86. package/dist/commands/config/config-export.js +23 -0
  87. package/dist/commands/config/config-health.d.ts +6 -0
  88. package/dist/commands/config/config-health.d.ts.map +1 -0
  89. package/dist/commands/config/config-health.js +42 -0
  90. package/dist/commands/config/config-import.d.ts +6 -0
  91. package/dist/commands/config/config-import.d.ts.map +1 -0
  92. package/dist/commands/config/config-import.js +63 -0
  93. package/dist/commands/config/config-rollback.d.ts +6 -0
  94. package/dist/commands/config/config-rollback.d.ts.map +1 -0
  95. package/dist/commands/config/config-rollback.js +47 -0
  96. package/dist/commands/config/config-setup.d.ts +6 -0
  97. package/dist/commands/config/config-setup.d.ts.map +1 -0
  98. package/dist/commands/config/config-setup.js +103 -0
  99. package/dist/commands/config/config-status.d.ts +6 -0
  100. package/dist/commands/config/config-status.d.ts.map +1 -0
  101. package/dist/commands/config/config-status.js +42 -0
  102. package/dist/commands/config/config-uninstall.d.ts +6 -0
  103. package/dist/commands/config/config-uninstall.d.ts.map +1 -0
  104. package/dist/commands/config/config-uninstall.js +74 -0
  105. package/dist/commands/config.d.ts +6 -0
  106. package/dist/commands/config.d.ts.map +1 -0
  107. package/dist/commands/config.js +19 -0
  108. package/dist/commands/docs.d.ts +3 -0
  109. package/dist/commands/docs.d.ts.map +1 -0
  110. package/dist/commands/docs.js +17 -0
  111. package/dist/commands/doctor.d.ts +3 -0
  112. package/dist/commands/doctor.d.ts.map +1 -0
  113. package/dist/commands/doctor.js +93 -0
  114. package/dist/commands/init.d.ts +3 -0
  115. package/dist/commands/init.d.ts.map +1 -0
  116. package/dist/commands/init.js +183 -0
  117. package/dist/commands/sync.d.ts +3 -0
  118. package/dist/commands/sync.d.ts.map +1 -0
  119. package/dist/commands/sync.js +73 -0
  120. package/dist/commands/theme.d.ts +3 -0
  121. package/dist/commands/theme.d.ts.map +1 -0
  122. package/dist/commands/theme.js +86 -0
  123. package/dist/commands/update.d.ts +3 -0
  124. package/dist/commands/update.d.ts.map +1 -0
  125. package/dist/commands/update.js +97 -0
  126. package/dist/prompts/prompt-builder.d.ts +4 -0
  127. package/dist/prompts/prompt-builder.d.ts.map +1 -0
  128. package/dist/prompts/prompt-builder.js +18 -0
  129. package/dist/prompts/prompt-data-loader.d.ts +11 -0
  130. package/dist/prompts/prompt-data-loader.d.ts.map +1 -0
  131. package/dist/prompts/prompt-data-loader.js +15 -0
  132. package/dist/prompts/prompt-sections/section-code-examples.d.ts +2 -0
  133. package/dist/prompts/prompt-sections/section-code-examples.d.ts.map +1 -0
  134. package/dist/prompts/prompt-sections/section-code-examples.js +36 -0
  135. package/dist/prompts/prompt-sections/section-color-tokens.d.ts +2 -0
  136. package/dist/prompts/prompt-sections/section-color-tokens.d.ts.map +1 -0
  137. package/dist/prompts/prompt-sections/section-color-tokens.js +19 -0
  138. package/dist/prompts/prompt-sections/section-component-map.d.ts +3 -0
  139. package/dist/prompts/prompt-sections/section-component-map.d.ts.map +1 -0
  140. package/dist/prompts/prompt-sections/section-component-map.js +12 -0
  141. package/dist/prompts/prompt-sections/section-typography-spacing.d.ts +2 -0
  142. package/dist/prompts/prompt-sections/section-typography-spacing.d.ts.map +1 -0
  143. package/dist/prompts/prompt-sections/section-typography-spacing.js +29 -0
  144. package/dist/services/backup-service.d.ts +7 -0
  145. package/dist/services/backup-service.d.ts.map +1 -0
  146. package/dist/services/backup-service.js +54 -0
  147. package/dist/services/config-service.d.ts +17 -0
  148. package/dist/services/config-service.d.ts.map +1 -0
  149. package/dist/services/config-service.js +64 -0
  150. package/dist/services/diff-engine.d.ts +13 -0
  151. package/dist/services/diff-engine.d.ts.map +1 -0
  152. package/dist/services/diff-engine.js +59 -0
  153. package/dist/services/ide-detector.d.ts +9 -0
  154. package/dist/services/ide-detector.d.ts.map +1 -0
  155. package/dist/services/ide-detector.js +113 -0
  156. package/dist/services/ide-detector.spec.d.ts +2 -0
  157. package/dist/services/ide-detector.spec.d.ts.map +1 -0
  158. package/dist/services/ide-detector.spec.js +108 -0
  159. package/dist/services/lock-file-service.d.ts +15 -0
  160. package/dist/services/lock-file-service.d.ts.map +1 -0
  161. package/dist/services/lock-file-service.js +74 -0
  162. package/dist/services/mcp-config-reader.d.ts +11 -0
  163. package/dist/services/mcp-config-reader.d.ts.map +1 -0
  164. package/dist/services/mcp-config-reader.js +40 -0
  165. package/dist/services/mcp-config-reader.spec.d.ts +2 -0
  166. package/dist/services/mcp-config-reader.spec.d.ts.map +1 -0
  167. package/dist/services/mcp-config-reader.spec.js +125 -0
  168. package/dist/services/mcp-config-writer.d.ts +11 -0
  169. package/dist/services/mcp-config-writer.d.ts.map +1 -0
  170. package/dist/services/mcp-config-writer.js +98 -0
  171. package/dist/services/mcp-config-writer.spec.d.ts +2 -0
  172. package/dist/services/mcp-config-writer.spec.d.ts.map +1 -0
  173. package/dist/services/mcp-config-writer.spec.js +162 -0
  174. package/dist/services/merge-engine.d.ts +12 -0
  175. package/dist/services/merge-engine.d.ts.map +1 -0
  176. package/dist/services/merge-engine.js +54 -0
  177. package/dist/services/vuetify-scaffold-service.d.ts +5 -0
  178. package/dist/services/vuetify-scaffold-service.d.ts.map +1 -0
  179. package/dist/services/vuetify-scaffold-service.js +67 -0
  180. package/dist/templates/vuetify-plugin.d.ts +90 -0
  181. package/dist/templates/vuetify-plugin.d.ts.map +1 -0
  182. package/dist/templates/vuetify-plugin.js +33 -0
  183. package/dist/types/command-types.d.ts +15 -0
  184. package/dist/types/command-types.d.ts.map +1 -0
  185. package/dist/types/command-types.js +2 -0
  186. package/dist/types/config-types.d.ts +29 -0
  187. package/dist/types/config-types.d.ts.map +1 -0
  188. package/dist/types/config-types.js +10 -0
  189. package/dist/types/ide-types.d.ts +29 -0
  190. package/dist/types/ide-types.d.ts.map +1 -0
  191. package/dist/types/ide-types.js +4 -0
  192. package/dist/types/lock-file-types.d.ts +27 -0
  193. package/dist/types/lock-file-types.d.ts.map +1 -0
  194. package/dist/types/lock-file-types.js +2 -0
  195. package/dist/utils/diff-display.d.ts +18 -0
  196. package/dist/utils/diff-display.d.ts.map +1 -0
  197. package/dist/utils/diff-display.js +61 -0
  198. package/dist/utils/fs-safe.d.ts +9 -0
  199. package/dist/utils/fs-safe.d.ts.map +1 -0
  200. package/dist/utils/fs-safe.js +44 -0
  201. package/dist/utils/logger.d.ts +14 -0
  202. package/dist/utils/logger.d.ts.map +1 -0
  203. package/dist/utils/logger.js +28 -0
  204. package/dist/utils/open-browser.d.ts +3 -0
  205. package/dist/utils/open-browser.d.ts.map +1 -0
  206. package/dist/utils/open-browser.js +13 -0
  207. package/package.json +11 -6
  208. package/dist/assets/cursor/.design-system-version +0 -1
  209. package/dist/assets/cursor/commands/audit-accessibility.md +0 -25
  210. package/dist/assets/cursor/commands/audit-ui.md +0 -35
  211. package/dist/assets/cursor/commands/component.md +0 -18
  212. package/dist/assets/cursor/commands/fix-storybook.md +0 -24
  213. package/dist/assets/cursor/commands/generate-component-from-figma.md +0 -26
  214. package/dist/assets/cursor/commands/generate-page-from-figma.md +0 -26
  215. package/dist/assets/cursor/plans/DESIGN_SYSTEM_PLAN.md +0 -177
  216. package/dist/assets/cursor/plans/PLANS_INDEX.md +0 -35
  217. package/dist/assets/cursor/rules/accessibility-contrast.mdc +0 -38
  218. package/dist/assets/cursor/rules/bem-class-style.mdc +0 -107
  219. package/dist/assets/cursor/rules/component-naming.mdc +0 -57
  220. package/dist/assets/cursor/rules/design-system-component-library.mdc +0 -59
  221. package/dist/assets/cursor/rules/design-system-workflow.mdc +0 -48
  222. package/dist/assets/cursor/rules/figma-mapping.mdc +0 -37
  223. package/dist/assets/cursor/rules/icons.mdc +0 -42
  224. package/dist/assets/cursor/rules/project-structure.mdc +0 -137
  225. package/dist/assets/cursor/rules/storybook-component-template.mdc +0 -103
  226. package/dist/assets/cursor/rules/storybook.mdc +0 -68
  227. package/dist/assets/cursor/rules/tokens.mdc +0 -32
  228. package/dist/assets/cursor/rules/viui-themes.mdc +0 -53
  229. package/dist/assets/cursor/rules/vuetify-layout.mdc +0 -52
  230. package/dist/assets/cursor/skills/accessibility.md +0 -75
  231. package/dist/assets/cursor/skills/design-system-thinking.md +0 -40
  232. package/dist/assets/cursor/skills/figma-interpretation.md +0 -38
  233. package/dist/assets/cursor/skills/vue-vuetify-design-system-architect.md +0 -60
  234. package/dist/assets/cursor/sync-manifest.json +0 -6
  235. package/dist/assets/viui-themes/bento-grid-global.scss +0 -5
  236. package/dist/assets/viui-themes/glassmorphism-global.scss +0 -5
  237. package/dist/assets/viui-themes/material-global.scss +0 -5
  238. package/dist/assets/viui-themes/minimalist-2-global.scss +0 -5
  239. package/dist/assets/viui-themes/minimalist-global.scss +0 -5
  240. package/dist/assets/viui-themes/neo-brutalism-global.scss +0 -5
package/README.md CHANGED
@@ -1,139 +1,138 @@
1
- # @hobui/viui-cli
2
-
3
-
4
- CLI to sync i-design-system `.cursor` (rules, skills, commands, plans) into consumer repos. Use this so Cursor/AI in the consumer repo follows the same design system rules, tokens, and BEM conventions.
5
-
6
- **Scope:** Published as `@hobui/viui-cli`. Consumer installs with `pnpm add @hobui/viui-cli`.
7
-
8
- ## One-command UX (recommended)
9
-
10
- At the consumer repo root, run:
11
-
12
- ```bash
13
- pnpm add @hobui/viui-cli
14
- ```
15
-
16
- After install, **postinstall** runs an interactive **setup wizard** (only when the terminal is interactive — not in CI):
17
-
18
- 1. **Step 1:** Init `.cursor` (rules, plans) and `src/plugins/viui-conf`, or sync if already present.
19
- 2. **Step 2:** Optionally install `@viui/web` for Vi* components (`pnpm add @viui/web`).
20
- 3. **Step 3:** Optionally add a postinstall script to auto-sync on future `pnpm install`.
21
-
22
- No need to run `viui-cli init` or `pnpm add @viui/web` separately. To run the wizard again: `pnpm exec viui-cli setup` (use `-y` to skip prompts).
23
-
24
- ## Commands
25
-
26
- | Command | Description |
27
- | --------- | ----------- |
28
- | `setup` | Interactive wizard: init/sync .cursor, install @viui/web, optional postinstall. Runs automatically after `pnpm add @hobui/viui-cli` (postinstall). |
29
- | `init` | Create `.cursor/` at repo root and copy rules, skills, commands (and optionally plans). Run once when onboarding. |
30
- | `sync` | Update existing `.cursor/` from the design system (overwrite). Use after design system updates. |
31
- | `version` | Print CLI version and, if present, the synced design system version (from `.cursor/.design-system-version`). |
32
-
33
- ## Usage at consumer repo
34
-
35
- **From npm (after publish) — one command:**
36
-
37
- ```bash
38
- pnpm add @hobui/viui-cli
39
- # then follow the setup wizard (Y/n per step)
40
- ```
41
-
42
- **Manual steps (if you skip the wizard):**
43
-
44
- ```bash
45
- pnpm add -D @hobui/viui-cli
46
- pnpm exec viui-cli init
47
- pnpm add @viui/web
48
- ```
49
-
50
- **Local development (from i-design-system monorepo):**
51
-
52
- 1. Build the CLI from i-design-system root or `packages/cli`:
53
-
54
- ```bash
55
- pnpm build:cli
56
- # or: cd packages/cli && pnpm build
57
- ```
58
-
59
- 2. From the consumer repo root (e.g. kpi-5):
60
-
61
- ```bash
62
- node path/to/i-design-system/packages/cli/dist/cli.js init
63
- # or: pnpm exec --prefix path/to/i-design-system/packages/cli @hobui/viui-cli init
64
- ```
65
-
66
- Always run `init` or `sync` from the **consumer repo root** (CWD = root). If you run from another folder (e.g. i-design-system), the wrong `.cursor` will be updated. The CLI logs `Syncing .cursor at: <path>` so you can confirm the target.
67
-
68
- **Auto-sync after install:** If the consumer has `@hobui/viui-cli` as a dependency (e.g. `"@hobui/viui-cli": "file:../../i-design-system/packages/cli"`), add a script so `.cursor` is synced automatically after each `pnpm install`:
69
-
70
- ```json
71
- "scripts": {
72
- "postinstall": "pnpm exec viui-cli sync"
73
- }
74
- ```
75
-
76
- Run `setup:ds` (or `pnpm exec viui-cli init`) once when first onboarding the repo; after that, `postinstall` keeps `.cursor` in sync when dependencies are installed.
77
-
78
- ## Init options
79
-
80
- | Option | Description |
81
- | ------------ | ----------- |
82
- | `-y`, `--yes` | Skip confirmation (no prompt). |
83
- | `--dry-run` | Only print what would be copied; do not write files. |
84
- | `--no-plans` | Do not sync `.cursor/plans`. |
85
-
86
- ## Sync options
87
-
88
- Sync overwrites existing files from the design system bundle and **removes** any file or folder in your `.cursor/` that is not in the bundle (so your `.cursor/` mirrors the bundle; files excluded via `.cursorignore` at build time will be removed on sync).
89
-
90
- | Option | Description |
91
- | ------------------ | ----------- |
92
- | `--dry-run` | Only print what would be overwritten. |
93
- | `--backup` | Backup existing files before overwrite (`.backup.<timestamp>`). |
94
- | `--rules-only` | Sync only `.cursor/rules`. |
95
- | `--skills-only` | Sync only `.cursor/skills`. |
96
- | `--commands-only` | Sync only `.cursor/commands`. |
97
-
98
- ## What gets synced
99
-
100
- - **rules** Design system rules (tokens, BEM, component naming, Storybook, etc.).
101
- - **skills** — Cursor skills for design system and accessibility.
102
- - **commands** Cursor commands (e.g. audit, generate from Figma).
103
- - **plans** — Optional plan docs (e.g. KPI template); use `--no-plans` on init to skip.
104
-
105
- After init/sync, `.cursor/.design-system-version` contains the design system version (from i-design-system at CLI build time).
106
-
107
- **For AI-generated code (Cursor / AI Agent):** Synced rules apply to **codegen** in the consumer repo. When generating Vue, Storybook or UI code, the agent must: (1) use **Vi\*** components from `@viui/web` (ViButton, ViInput, ViCard, ViMenu, ViButtonToggle, …) instead of raw Vuetify where available; (2) use **Tabler Icons** (`@tabler/icons-vue`) as the default icon set; (3) follow `.cursor/rules/storybook.mdc` (title, CSF3, vi-ui in stories) and `.cursor/rules/icons.mdc`. See also AGENTS.md in the design system repo (§ Codegen / AI Agent, § Rules 3 and 7) and `.cursor/plans/icons_free_sources.plan.md` if plans were synced.
108
-
109
- **viui-conf:** Init and sync also copy the design system's **Vuetify config folder** (theme-base, v-light, v-dark, defaults) to **`src/plugins/viui-conf/`** in the consumer repo. The file **`vuetify.ts`** is **not** synced — you keep your own `src/plugins/vuetify.ts` and import from `./viui-conf` (e.g. `import { defaults } from './viui-conf/defaults'`, `import LightTheme from './viui-conf/v-light'`). See [packages/docs/consumer-update.md](../docs/consumer-update.md) (§4).
110
-
111
- **viui-themes (SCSS):** Init and sync also copy **design style themes** (neo-brutalism, material, minimalist, etc.) to **`src/assets/styles/viui-themes/`** and create **`src/assets/styles/viui-themes-entry.scss`**. If the consumer has **`src/assets/styles/main.scss`**, the CLI adds an import for `viui-themes-entry` so theme SCSS is loaded automatically. Set `VITE_VIUI_THEME=neo-brutalism` (or another theme id) in `.env` and add `body.classList.add('design-style-neo-brutalism')` (or the matching class) in your app so the theme styles apply globally. See `src/plugins/viui-conf/defaults/README.md` after sync.
112
-
113
- ### Excluding files when building the CLI (`.cursorignore`)
114
-
115
- In **packages/cli**, the file **`.cursorignore`** is read by the copy script when building the CLI. Paths matching its patterns are not copied from i-design-system `.cursor/` into `dist/assets/cursor/`, so they are not synced to consumers. One pattern per line; lines starting with `#` and empty lines are ignored. Supported patterns:
116
-
117
- - **`filename`** skip any file or folder with this name (e.g. `KPI_COMPONENT_TEMPLATE.md`).
118
- - **`*.ext`** skip any file whose name ends with `.ext` (e.g. `*.plan.md`, `*.log`).
119
- - **`category/path`** — skip the path under that category (e.g. `plans/CLI_BUILD.plan.md`).
120
-
121
- Edit `packages/cli/.cursorignore` and run `pnpm build` in packages/cli (or `pnpm build:cli` from root) for changes to take effect.
122
-
123
- ## Design system package
124
-
125
- To use components in the consumer app, install the design system package:
126
-
127
- ```bash
128
- pnpm add @viui/web
129
- ```
130
-
131
- Then import components: `import { ViButton, ViInput, ... } from '@viui/web'`. See [CLI_BUILD.plan.md](../../.cursor/plans/CLI_BUILD.plan.md) and root README for full setup.
132
-
133
- ## Build
134
-
135
- ```bash
136
- pnpm build
137
- ```
138
-
139
- Runs `tsc` and copies `.cursor` from repo root into `dist/assets/cursor/`, and writes `.design-system-version` from root `package.json`. Published package includes `dist/` so `npx @hobui/viui-cli init` works without the source repo.
1
+ # @hobui/viui-cli
2
+
3
+ CLI cho iNET Design System — quản lý themes, tokens, và config trong consumer projects.
4
+
5
+ **Package:** `@hobui/viui-cli` | **Binary:** `viui`
6
+
7
+ ## Cài đặt
8
+
9
+ ```bash
10
+ pnpm add -D @hobui/viui-cli
11
+ # hoặc global:
12
+ npm link # từ packages/cli/
13
+ ```
14
+
15
+ ## Commands
16
+
17
+ | Command | Mô tả |
18
+ |---------|-------|
19
+ | `viui init` | Tạo `viui.config.ts` + `.viui-lock.json`, chọn theme (6 themes), style format |
20
+ | `viui sync` | Sync themes/tokens SCSS từ CLI bundle vào consumer project |
21
+ | `viui update` | Check npm registry cho updates, apply + tự prompt sync |
22
+ | `viui theme list` | Liệt themes khả dụng, đánh dấu active |
23
+ | `viui theme switch <name>` | Chuyển theme, update config + lock file |
24
+ | `viui theme preview <name>` | Xem CSS custom properties của theme |
25
+ | `viui doctor` | Health check: config, tokens, themes, lock file integrity |
26
+ | `viui docs` | Mở Storybook docs trong browser |
27
+ | `viui docs --api` | Mở VitePress API docs |
28
+ | `viui audit` | Audit component usage: Vi* adoption, icon patterns, accessibility |
29
+
30
+ ## Quick Start
31
+
32
+ ```bash
33
+ # 1. Init project
34
+ viui init
35
+
36
+ # 2. Theo hướng dẫn setup:
37
+ # pnpm add @hobui/viui vuetify @mdi/font @tabler/icons-vue
38
+
39
+ # 3. Sync theme files
40
+ viui sync --apply
41
+
42
+ # 4. Check health
43
+ viui doctor
44
+ ```
45
+
46
+ ## Config File
47
+
48
+ `viui init` tạo `viui.config.ts`:
49
+
50
+ ```typescript
51
+ import type { ViuiConfig } from '@hobui/viui-cli'
52
+
53
+ export default {
54
+ theme: 'minimalist-2',
55
+ tokens: '@hobui/tokens',
56
+ styleImport: 'scss',
57
+ outputDir: 'src/assets/styles/viui/',
58
+ vuetifyIntegration: true,
59
+ } satisfies ViuiConfig
60
+ ```
61
+
62
+ ## Themes
63
+
64
+ 6 themes khả dụng:
65
+
66
+ | Theme | Style |
67
+ |-------|-------|
68
+ | `neo-brutalism` | Bold, chunky borders, high contrast |
69
+ | `minimalist-2` | Stripe-like, clean, subtle (iNET DNA) |
70
+ | `material` | Material Design 3 |
71
+ | `minimalist` | Ultra-minimal |
72
+ | `glassmorphism` | Frosted glass effects |
73
+ | `bento-grid` | Grid-based layout |
74
+
75
+ ## Icons
76
+
77
+ Hỗ trợ 2 icon sets qua Vuetify:
78
+
79
+ ```vue
80
+ <!-- MDI (font-based) -->
81
+ <v-icon icon="mdi-home" />
82
+
83
+ <!-- Tabler (SVG, khuyến nghị) -->
84
+ <v-icon icon="tabler:home" />
85
+ ```
86
+
87
+ Cấu hình Tabler trong `vuetify.ts`:
88
+
89
+ ```typescript
90
+ import { tabler } from '@hobui/viui/iconsets/tabler'
91
+ import { mdi } from 'vuetify/iconsets/mdi'
92
+
93
+ createVuetify({
94
+ icons: { defaultSet: 'mdi', sets: { mdi, tabler } }
95
+ })
96
+ ```
97
+
98
+ ## Init Options
99
+
100
+ | Option | tả |
101
+ |--------|-------|
102
+ | `--dry-run` | Chỉ hiển thị, không ghi file |
103
+
104
+ ## Sync Options
105
+
106
+ | Option | Mô tả |
107
+ |--------|-------|
108
+ | `--diff` | Chỉ hiện diff, không apply |
109
+ | `--dry-run` | Simulate, không ghi file |
110
+ | `--apply` | Apply changes |
111
+
112
+ ## Update Options
113
+
114
+ | Option | Mô tả |
115
+ |--------|-------|
116
+ | `--diff` | Chỉ hiện available updates |
117
+ | `--dry-run` | Simulate update |
118
+ | `--apply` | Apply updates + prompt sync |
119
+
120
+ ## Build
121
+
122
+ ```bash
123
+ cd packages/cli
124
+ pnpm build
125
+ ```
126
+
127
+ Chạy `tsc` + `copy-assets.mjs` (copy viui-conf + themes SCSS vào `dist/assets/`).
128
+
129
+ ## Local Development
130
+
131
+ ```bash
132
+ # Build + link global
133
+ cd packages/cli && pnpm build && npm link
134
+
135
+ # Tại consumer project
136
+ npm link @hobui/viui-cli
137
+ viui init
138
+ ```
@@ -0,0 +1,12 @@
1
+ import type { AiAdapter } from './adapter-types.js';
2
+ /** Auto-detect AI systems by checking for their config directories/files */
3
+ export declare function detectAiSystems(projectRoot: string): AiAdapter[];
4
+ /** Get adapter by name (for --targets override) */
5
+ export declare function getAdapterByName(name: string): AiAdapter | undefined;
6
+ /** Get all registered adapters */
7
+ export declare function getAllAdapters(): AiAdapter[];
8
+ /** Get only internal adapters */
9
+ export declare function getInternalAdapters(): AiAdapter[];
10
+ /** Get only external adapters */
11
+ export declare function getExternalAdapters(): AiAdapter[];
12
+ //# sourceMappingURL=adapter-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter-registry.d.ts","sourceRoot":"","sources":["../../src/adapters/adapter-registry.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAgCnD,4EAA4E;AAC5E,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,EAAE,CAMhE;AAED,mDAAmD;AACnD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAEpE;AAED,kCAAkC;AAClC,wBAAgB,cAAc,IAAI,SAAS,EAAE,CAE5C;AAED,iCAAiC;AACjC,wBAAgB,mBAAmB,IAAI,SAAS,EAAE,CAEjD;AAED,iCAAiC;AACjC,wBAAgB,mBAAmB,IAAI,SAAS,EAAE,CAEjD"}
@@ -0,0 +1,49 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { claudeAdapter } from './claude-adapter.js';
4
+ import { cursorAdapter } from './cursor-adapter.js';
5
+ import { windsurfAdapter } from './windsurf-adapter.js';
6
+ import { copilotAdapter } from './copilot-adapter.js';
7
+ import { clineAdapter } from './cline-adapter.js';
8
+ import { aiderAdapter } from './aider-adapter.js';
9
+ import { v0Adapter } from './external/v0-adapter.js';
10
+ import { geminiAdapter } from './external/gemini-adapter.js';
11
+ import { chatgptAdapter } from './external/chatgpt-adapter.js';
12
+ import { boltAdapter } from './external/bolt-adapter.js';
13
+ import { lovableAdapter } from './external/lovable-adapter.js';
14
+ const INTERNAL_ADAPTERS = [
15
+ claudeAdapter,
16
+ cursorAdapter,
17
+ windsurfAdapter,
18
+ copilotAdapter,
19
+ clineAdapter,
20
+ aiderAdapter,
21
+ ];
22
+ const EXTERNAL_ADAPTERS = [
23
+ v0Adapter,
24
+ geminiAdapter,
25
+ chatgptAdapter,
26
+ boltAdapter,
27
+ lovableAdapter,
28
+ ];
29
+ const ALL_ADAPTERS = [...INTERNAL_ADAPTERS, ...EXTERNAL_ADAPTERS];
30
+ /** Auto-detect AI systems by checking for their config directories/files */
31
+ export function detectAiSystems(projectRoot) {
32
+ return INTERNAL_ADAPTERS.filter(adapter => adapter.detectDirs.some(dir => fs.existsSync(path.join(projectRoot, dir))));
33
+ }
34
+ /** Get adapter by name (for --targets override) */
35
+ export function getAdapterByName(name) {
36
+ return ALL_ADAPTERS.find(a => a.name.toLowerCase() === name.toLowerCase());
37
+ }
38
+ /** Get all registered adapters */
39
+ export function getAllAdapters() {
40
+ return ALL_ADAPTERS;
41
+ }
42
+ /** Get only internal adapters */
43
+ export function getInternalAdapters() {
44
+ return INTERNAL_ADAPTERS;
45
+ }
46
+ /** Get only external adapters */
47
+ export function getExternalAdapters() {
48
+ return EXTERNAL_ADAPTERS;
49
+ }
@@ -0,0 +1,20 @@
1
+ export interface PromptMeta {
2
+ theme: string;
3
+ version: string;
4
+ generatedAt: string;
5
+ }
6
+ export interface AiAdapter {
7
+ /** Display name: "Claude Code", "Cursor", etc. */
8
+ name: string;
9
+ /** 'internal' (auto-detect) or 'external' (manual) */
10
+ category?: 'internal' | 'external';
11
+ /** Directories to check for detection */
12
+ detectDirs: string[];
13
+ /** Output path relative to project root */
14
+ outputPath: string;
15
+ /** Transform canonical markdown to system-specific format */
16
+ transform(markdown: string, meta: PromptMeta): string;
17
+ /** Max output size in chars (optional) */
18
+ maxChars?: number;
19
+ }
20
+ //# sourceMappingURL=adapter-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter-types.d.ts","sourceRoot":"","sources":["../../src/adapters/adapter-types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,SAAS;IACxB,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAA;IACZ,sDAAsD;IACtD,QAAQ,CAAC,EAAE,UAAU,GAAG,UAAU,CAAA;IAClC,yCAAyC;IACzC,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,2CAA2C;IAC3C,UAAU,EAAE,MAAM,CAAA;IAClB,6DAA6D;IAC7D,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,MAAM,CAAA;IACrD,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,3 @@
1
+ import type { AiAdapter } from './adapter-types.js';
2
+ export declare const aiderAdapter: AiAdapter;
3
+ //# sourceMappingURL=aider-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aider-adapter.d.ts","sourceRoot":"","sources":["../../src/adapters/aider-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAEnD,eAAO,MAAM,YAAY,EAAE,SAO1B,CAAA"}
@@ -0,0 +1,8 @@
1
+ export const aiderAdapter = {
2
+ name: 'Aider',
3
+ detectDirs: ['.aider.conf.yml'],
4
+ outputPath: 'CONVENTIONS.md',
5
+ transform(markdown) {
6
+ return markdown;
7
+ },
8
+ };
@@ -0,0 +1,3 @@
1
+ import type { AiAdapter } from './adapter-types.js';
2
+ export declare const claudeAdapter: AiAdapter;
3
+ //# sourceMappingURL=claude-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-adapter.d.ts","sourceRoot":"","sources":["../../src/adapters/claude-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAEnD,eAAO,MAAM,aAAa,EAAE,SAc3B,CAAA"}
@@ -0,0 +1,15 @@
1
+ export const claudeAdapter = {
2
+ name: 'Claude Code',
3
+ detectDirs: ['.claude'],
4
+ outputPath: '.claude/rules/viui-design-system.md',
5
+ transform(markdown) {
6
+ const frontmatter = [
7
+ '---',
8
+ 'paths:',
9
+ ' - "src/**"',
10
+ '---',
11
+ '',
12
+ ].join('\n');
13
+ return frontmatter + markdown;
14
+ },
15
+ };
@@ -0,0 +1,3 @@
1
+ import type { AiAdapter } from './adapter-types.js';
2
+ export declare const clineAdapter: AiAdapter;
3
+ //# sourceMappingURL=cline-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cline-adapter.d.ts","sourceRoot":"","sources":["../../src/adapters/cline-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAEnD,eAAO,MAAM,YAAY,EAAE,SAO1B,CAAA"}
@@ -0,0 +1,8 @@
1
+ export const clineAdapter = {
2
+ name: 'Cline',
3
+ detectDirs: ['.clinerules'],
4
+ outputPath: '.clinerules/viui-design-system.md',
5
+ transform(markdown) {
6
+ return markdown;
7
+ },
8
+ };
@@ -0,0 +1,5 @@
1
+ import type { AiAdapter } from './adapter-types.js';
2
+ export declare const copilotAdapter: AiAdapter;
3
+ /** Insert or replace VIUI block in existing copilot-instructions.md content */
4
+ export declare function mergeWithExisting(existing: string, newBlock: string): string;
5
+ //# sourceMappingURL=copilot-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"copilot-adapter.d.ts","sourceRoot":"","sources":["../../src/adapters/copilot-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAKnD,eAAO,MAAM,cAAc,EAAE,SAO5B,CAAA;AAED,+EAA+E;AAC/E,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAU5E"}
@@ -0,0 +1,20 @@
1
+ const MARKER_START = '<!-- VIUI:START -->';
2
+ const MARKER_END = '<!-- VIUI:END -->';
3
+ export const copilotAdapter = {
4
+ name: 'GitHub Copilot',
5
+ detectDirs: ['.github'],
6
+ outputPath: '.github/copilot-instructions.md',
7
+ transform(markdown) {
8
+ return `${MARKER_START}\n${markdown}\n${MARKER_END}\n`;
9
+ },
10
+ };
11
+ /** Insert or replace VIUI block in existing copilot-instructions.md content */
12
+ export function mergeWithExisting(existing, newBlock) {
13
+ const startIdx = existing.indexOf(MARKER_START);
14
+ const endIdx = existing.indexOf(MARKER_END);
15
+ if (startIdx !== -1 && endIdx !== -1) {
16
+ return existing.slice(0, startIdx) + newBlock.trimEnd() + '\n' + existing.slice(endIdx + MARKER_END.length);
17
+ }
18
+ // Append if no existing markers
19
+ return existing.trimEnd() + '\n\n' + newBlock;
20
+ }
@@ -0,0 +1,3 @@
1
+ import type { AiAdapter } from './adapter-types.js';
2
+ export declare const cursorAdapter: AiAdapter;
3
+ //# sourceMappingURL=cursor-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor-adapter.d.ts","sourceRoot":"","sources":["../../src/adapters/cursor-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAc,MAAM,oBAAoB,CAAA;AAE/D,eAAO,MAAM,aAAa,EAAE,SAiB3B,CAAA"}
@@ -0,0 +1,18 @@
1
+ export const cursorAdapter = {
2
+ name: 'Cursor',
3
+ detectDirs: ['.cursor'],
4
+ outputPath: '.cursor/rules/viui-design-system.mdc',
5
+ transform(markdown, meta) {
6
+ const frontmatter = [
7
+ '---',
8
+ `description: "iNET Design System rules — ViUI v${meta.version}"`,
9
+ 'globs:',
10
+ ' - "src/**/*.vue"',
11
+ ' - "src/**/*.ts"',
12
+ 'alwaysApply: true',
13
+ '---',
14
+ '',
15
+ ].join('\n');
16
+ return frontmatter + markdown;
17
+ },
18
+ };
@@ -0,0 +1,3 @@
1
+ import type { AiAdapter } from '../adapter-types.js';
2
+ export declare const boltAdapter: AiAdapter;
3
+ //# sourceMappingURL=bolt-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bolt-adapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/external/bolt-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAc,MAAM,qBAAqB,CAAA;AAGhE,eAAO,MAAM,WAAW,EAAE,SAazB,CAAA"}
@@ -0,0 +1,15 @@
1
+ import { stripImportPaths, replaceColorsWithFormat, COLORS_TABLE, mapComponents, trimToLimit } from './external-adapter-base.js';
2
+ export const boltAdapter = {
3
+ name: 'bolt',
4
+ category: 'external',
5
+ detectDirs: [],
6
+ outputPath: '.viui/prompts/bolt/design-system.txt',
7
+ maxChars: 4000,
8
+ transform(markdown, meta) {
9
+ let result = stripImportPaths(markdown);
10
+ result = replaceColorsWithFormat(result, COLORS_TABLE);
11
+ result = mapComponents(result, 'html');
12
+ result = trimToLimit(result, 4000);
13
+ return `# iNET Design System (v${meta.version})\n\n` + result;
14
+ },
15
+ };
@@ -0,0 +1,3 @@
1
+ import type { AiAdapter } from '../adapter-types.js';
2
+ export declare const chatgptAdapter: AiAdapter;
3
+ //# sourceMappingURL=chatgpt-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chatgpt-adapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/external/chatgpt-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAc,MAAM,qBAAqB,CAAA;AAGhE,eAAO,MAAM,cAAc,EAAE,SAY5B,CAAA"}
@@ -0,0 +1,14 @@
1
+ import { stripImportPaths, replaceColorsWithFormat, CSS_VARS_BLOCK, trimToLimit } from './external-adapter-base.js';
2
+ export const chatgptAdapter = {
3
+ name: 'ChatGPT',
4
+ category: 'external',
5
+ detectDirs: [],
6
+ outputPath: '.viui/prompts/chatgpt/design-system.txt',
7
+ maxChars: 6000,
8
+ transform(markdown, meta) {
9
+ let result = stripImportPaths(markdown);
10
+ result = replaceColorsWithFormat(result, CSS_VARS_BLOCK);
11
+ result = trimToLimit(result, 6000);
12
+ return `# iNET Design System (v${meta.version})\n\n` + result;
13
+ },
14
+ };
@@ -0,0 +1,15 @@
1
+ /** Strip import lines referencing internal paths */
2
+ export declare function stripImportPaths(md: string): string;
3
+ /** Compact color table (12 rows) — extracted from COLORS_JSON */
4
+ export declare const COLORS_TABLE = "| Token | Light | Dark |\n|---|---|---|\n| primary | #024799 | #619ee9 |\n| accent | #cc0e0e | #ed7b7b |\n| neutral-bg | #F4F7FA | #0D1117 |\n| neutral-text | #0F1E2D | #E6EDF3 |\n| neutral-border | #D0DAE6 | #21262D |\n| success | #0E9F6E | #34D399 |\n| warning | #D47B0A | #FBBF24 |\n| error | #B91C1C | #F87171 |\n| info | #8abdef | #619ee9 |\n| surface-bg | #FFFFFF | #121212 |\n| surface-card | #FFFFFF | #2a2a2a |\n| surface-elev | #FFFFFF | #1e1e1e |";
5
+ /** CSS vars block for embedded use */
6
+ export declare const CSS_VARS_BLOCK = ":root {\n --color-primary: #024799;\n --color-accent: #cc0e0e;\n --neutral-bg: #F4F7FA;\n --neutral-text: #0F1E2D;\n --neutral-border: #D0DAE6;\n --color-success: #0E9F6E;\n --color-warning: #D47B0A;\n --color-error: #B91C1C;\n --color-info: #8abdef;\n}\n.dark {\n --color-primary: #619ee9;\n --color-accent: #ed7b7b;\n --neutral-bg: #0D1117;\n --neutral-text: #E6EDF3;\n --neutral-border: #21262D;\n --color-success: #34D399;\n --color-warning: #FBBF24;\n --color-error: #F87171;\n --color-info: #619ee9;\n}";
7
+ /** Tailwind extend config */
8
+ export declare const TAILWIND_CONFIG = "extend: {\n colors: {\n 'primary': '#024799',\n 'accent': '#cc0e0e',\n 'neutral-bg': '#F4F7FA',\n 'neutral-text': '#0F1E2D',\n 'success': '#0E9F6E',\n 'warning': '#D47B0A',\n 'error': '#B91C1C',\n 'info': '#8abdef'\n }\n}";
9
+ /** Replace full color JSON blob with a compact replacement */
10
+ export declare function replaceColorsWithFormat(md: string, replacement: string): string;
11
+ /** Map Vi* component names to target equivalent */
12
+ export declare function mapComponents(md: string, target: 'shadcn' | 'html'): string;
13
+ /** Trim text to maxChars at last newline */
14
+ export declare function trimToLimit(text: string, maxChars: number): string;
15
+ //# sourceMappingURL=external-adapter-base.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"external-adapter-base.d.ts","sourceRoot":"","sources":["../../../src/adapters/external/external-adapter-base.ts"],"names":[],"mappings":"AAAA,oDAAoD;AACpD,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAInD;AAED,iEAAiE;AACjE,eAAO,MAAM,YAAY,8cAaY,CAAA;AAErC,sCAAsC;AACtC,eAAO,MAAM,cAAc,mhBAqBzB,CAAA;AAEF,6BAA6B;AAC7B,eAAO,MAAM,eAAe,4PAW1B,CAAA;AAEF,8DAA8D;AAC9D,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAK/E;AAkBD,mDAAmD;AACnD,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAG,MAAM,GAAG,MAAM,CAO3E;AAED,4CAA4C;AAC5C,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAKlE"}