@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
@@ -0,0 +1,19 @@
1
+ import { registerSetupSubcommand } from './config/config-setup.js';
2
+ import { registerStatusSubcommand } from './config/config-status.js';
3
+ import { registerHealthSubcommand } from './config/config-health.js';
4
+ import { registerUninstallSubcommand } from './config/config-uninstall.js';
5
+ import { registerRollbackSubcommand } from './config/config-rollback.js';
6
+ import { registerExportSubcommand } from './config/config-export.js';
7
+ import { registerImportSubcommand } from './config/config-import.js';
8
+ export function registerConfigCommand(program) {
9
+ const configCmd = program
10
+ .command('config')
11
+ .description('Quản lý cấu hình MCP server cho IDE');
12
+ registerSetupSubcommand(configCmd);
13
+ registerStatusSubcommand(configCmd);
14
+ registerHealthSubcommand(configCmd);
15
+ registerUninstallSubcommand(configCmd);
16
+ registerRollbackSubcommand(configCmd);
17
+ registerExportSubcommand(configCmd);
18
+ registerImportSubcommand(configCmd);
19
+ }
@@ -0,0 +1,3 @@
1
+ import type { Command } from 'commander';
2
+ export declare function registerDocsCommand(program: Command): void;
3
+ //# sourceMappingURL=docs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docs.d.ts","sourceRoot":"","sources":["../../src/commands/docs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAOxC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAY1D"}
@@ -0,0 +1,17 @@
1
+ import { logger } from '../utils/logger.js';
2
+ import { openBrowser } from '../utils/open-browser.js';
3
+ const STORYBOOK_URL = 'https://inet-design-system.pages.dev';
4
+ const VITEPRESS_URL = 'https://inet-design-system-docs.pages.dev';
5
+ export function registerDocsCommand(program) {
6
+ program
7
+ .command('docs')
8
+ .description('Open design system documentation in browser')
9
+ .option('--api', 'Open API docs (VitePress) instead of Storybook')
10
+ .option('--guide', 'Open VitePress guide docs')
11
+ .action((opts) => {
12
+ const url = (opts.api || opts.guide) ? VITEPRESS_URL : STORYBOOK_URL;
13
+ const label = (opts.api || opts.guide) ? 'Guide docs' : 'Storybook';
14
+ logger.info(`Opening ${label}: ${url}`);
15
+ openBrowser(url);
16
+ });
17
+ }
@@ -0,0 +1,3 @@
1
+ import type { Command } from 'commander';
2
+ export declare function registerDoctorCommand(program: Command): void;
3
+ //# sourceMappingURL=doctor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAoFxC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAyB5D"}
@@ -0,0 +1,93 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import chalk from 'chalk';
4
+ import { logger } from '../utils/logger.js';
5
+ import { configExists, readConfig } from '../services/config-service.js';
6
+ import { readLockFile } from '../services/lock-file-service.js';
7
+ /** Run all health checks and return results */
8
+ function runChecks(cwd) {
9
+ const results = [];
10
+ // 1. viui.config.ts exists and valid
11
+ const hasConfig = configExists(cwd);
12
+ const config = hasConfig ? readConfig(cwd) : null;
13
+ results.push({
14
+ name: 'viui.config.ts',
15
+ pass: hasConfig && config !== null,
16
+ detail: hasConfig ? 'Found and parseable' : 'Missing — run `viui init`',
17
+ });
18
+ // 2. @hobui/tokens installed
19
+ const tokensPath = path.join(cwd, 'node_modules', '@hobui', 'tokens');
20
+ const hasTokens = fs.existsSync(tokensPath);
21
+ results.push({
22
+ name: '@hobui/tokens',
23
+ pass: hasTokens,
24
+ detail: hasTokens ? 'Installed' : 'Not installed — run `npm install @hobui/tokens`',
25
+ });
26
+ // 3. Theme files present
27
+ const outputDir = config?.outputDir ?? 'src/assets/styles/viui/';
28
+ const hasThemes = fs.existsSync(path.join(cwd, outputDir));
29
+ results.push({
30
+ name: 'Theme files',
31
+ pass: hasThemes,
32
+ detail: hasThemes ? `Found at ${outputDir}` : `Missing at ${outputDir} — run \`viui sync --apply\``,
33
+ });
34
+ // 4. .viui-lock.json exists
35
+ const lockFile = readLockFile(cwd);
36
+ results.push({
37
+ name: '.viui-lock.json',
38
+ pass: lockFile !== null,
39
+ detail: lockFile ? `Version ${lockFile.metadata.cliVersion}` : 'Missing — run `viui init`',
40
+ });
41
+ // 5. SCSS/CSS imports in main stylesheet
42
+ const mainScss = path.join(cwd, 'src', 'assets', 'styles', 'main.scss');
43
+ const hasMainScss = fs.existsSync(mainScss);
44
+ let hasTokenImport = false;
45
+ if (hasMainScss) {
46
+ const content = fs.readFileSync(mainScss, 'utf8');
47
+ hasTokenImport = content.includes('viui') || content.includes('tokens');
48
+ }
49
+ results.push({
50
+ name: 'Main stylesheet imports',
51
+ pass: hasMainScss && hasTokenImport,
52
+ detail: !hasMainScss ? 'main.scss not found' : hasTokenImport ? 'Token/theme imports found' : 'Missing viui imports in main.scss',
53
+ });
54
+ // 6. Vuetify theme uses tokens
55
+ const vuetifyPath = path.join(cwd, 'src', 'plugins', 'vuetify.ts');
56
+ const hasVuetify = fs.existsSync(vuetifyPath);
57
+ let hasViuiConf = false;
58
+ if (hasVuetify) {
59
+ const content = fs.readFileSync(vuetifyPath, 'utf8');
60
+ hasViuiConf = content.includes('viui-conf') || content.includes('apply-theme-body');
61
+ }
62
+ results.push({
63
+ name: 'Vuetify integration',
64
+ pass: !hasVuetify || hasViuiConf,
65
+ detail: !hasVuetify ? 'No Vuetify detected (OK)' : hasViuiConf ? 'viui-conf configured' : 'Missing viui-conf import in vuetify.ts',
66
+ });
67
+ return results;
68
+ }
69
+ export function registerDoctorCommand(program) {
70
+ program
71
+ .command('doctor')
72
+ .description('Diagnose viui configuration and dependencies')
73
+ .action(() => {
74
+ const cwd = process.cwd();
75
+ logger.header('viui doctor — Health Check\n');
76
+ const results = runChecks(cwd);
77
+ let allPass = true;
78
+ for (const r of results) {
79
+ const icon = r.pass ? chalk.green('✓') : chalk.red('✗');
80
+ console.log(` ${icon} ${r.name}: ${r.detail}`);
81
+ if (!r.pass)
82
+ allPass = false;
83
+ }
84
+ logger.br();
85
+ if (allPass) {
86
+ logger.success('All checks passed!');
87
+ }
88
+ else {
89
+ logger.warn('Some checks failed. Fix the issues above.');
90
+ process.exitCode = 1;
91
+ }
92
+ });
93
+ }
@@ -0,0 +1,3 @@
1
+ import type { Command } from 'commander';
2
+ export declare function registerInitCommand(program: Command): void;
3
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AA6ExC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA0H1D"}
@@ -0,0 +1,183 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import readline from 'node:readline/promises';
4
+ import { logger } from '../utils/logger.js';
5
+ import { ensureDir, copyDirRecursive } from '../utils/fs-safe.js';
6
+ import { AVAILABLE_THEMES } from '../types/config-types.js';
7
+ import { DEFAULT_CONFIG, writeConfig, configExists } from '../services/config-service.js';
8
+ import { createLockFile, writeLockFile } from '../services/lock-file-service.js';
9
+ import { getCliVersion, getAssetsDir } from '../cli-paths.js';
10
+ import { scaffoldVuetifyPlugin, patchMainEntry } from '../services/vuetify-scaffold-service.js';
11
+ import { detectAiSystems, getAdapterByName } from '../adapters/adapter-registry.js';
12
+ import { loadPromptData } from '../prompts/prompt-data-loader.js';
13
+ import { buildCanonicalPrompt } from '../prompts/prompt-builder.js';
14
+ import { writeFileSafe } from '../utils/fs-safe.js';
15
+ import { mergeWithExisting } from '../adapters/copilot-adapter.js';
16
+ /** Detect project framework from package.json */
17
+ function detectFramework(cwd) {
18
+ const pkgPath = path.join(cwd, 'package.json');
19
+ if (!fs.existsSync(pkgPath))
20
+ return 'unknown';
21
+ const raw = fs.readFileSync(pkgPath, 'utf8');
22
+ if (raw.includes('"nuxt"'))
23
+ return 'nuxt';
24
+ if (raw.includes('"vue"'))
25
+ return 'vue';
26
+ return 'unknown';
27
+ }
28
+ /** Copy viui-conf plugin assets to consumer project */
29
+ function copyViuiConf(cwd, assetsDir) {
30
+ const viuiConfSrc = path.join(assetsDir, 'plugins', 'viui-conf');
31
+ if (!fs.existsSync(viuiConfSrc))
32
+ return;
33
+ const viuiConfDest = path.join(cwd, 'src', 'plugins', 'viui-conf');
34
+ ensureDir(path.dirname(viuiConfDest));
35
+ copyDirRecursive(viuiConfSrc, viuiConfDest);
36
+ logger.success('Synced viui-conf to src/plugins/viui-conf');
37
+ }
38
+ /** Copy theme SCSS files to consumer outputDir */
39
+ function copyThemeFiles(cwd, assetsDir, outputDir) {
40
+ const themesSrc = path.join(assetsDir, 'themes');
41
+ if (!fs.existsSync(themesSrc)) {
42
+ logger.warn('Theme assets not found in CLI bundle');
43
+ return;
44
+ }
45
+ const themesDest = path.join(cwd, outputDir);
46
+ ensureDir(themesDest);
47
+ copyDirRecursive(themesSrc, themesDest);
48
+ logger.success(`Copied themes to ${outputDir}`);
49
+ }
50
+ /** Print setup instructions for consumer after init */
51
+ function printSetupInstructions() {
52
+ logger.br();
53
+ logger.header('Setup instructions:');
54
+ console.log(`
55
+ 1. Install dependencies:
56
+ pnpm add vuetify @mdi/font
57
+
58
+ 2. (Optional) For Tabler icons:
59
+ pnpm add @tabler/icons-vue
60
+ Then add tabler iconset to src/plugins/vuetify.ts
61
+
62
+ 3. viui-cli has auto-configured:
63
+ - src/plugins/viui-conf/ (theme config, defaults, tokens)
64
+ - src/plugins/vuetify.ts (Vuetify plugin with defaults + themes)
65
+ - main.ts patched with: import { vuetify } + app.use(vuetify)
66
+
67
+ 4. Customize theme:
68
+ - Edit src/plugins/viui-conf/v-light.ts / v-dark.ts
69
+ - Set VITE_VIUI_THEME env var to switch design style
70
+
71
+ 5. Use Vi* components:
72
+ import { ViButton, ViInput } from '@hobui/viui'
73
+ `);
74
+ }
75
+ export function registerInitCommand(program) {
76
+ program
77
+ .command('init')
78
+ .description('Initialize viui design system in this project')
79
+ .option('--dry-run', 'Show what would be created without writing')
80
+ .action(async (opts) => {
81
+ const cwd = process.cwd();
82
+ const assetsDir = getAssetsDir();
83
+ if (configExists(cwd) && !opts.dryRun) {
84
+ logger.warn('viui.config.ts already exists. Use `viui sync` to update.');
85
+ return;
86
+ }
87
+ const framework = detectFramework(cwd);
88
+ logger.info(`Detected framework: ${framework}`);
89
+ // Interactive prompts
90
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
91
+ try {
92
+ // Theme selection
93
+ logger.br();
94
+ logger.header('Choose a theme:');
95
+ AVAILABLE_THEMES.forEach((t, i) => console.log(` ${i + 1}) ${t}`));
96
+ const themeAnswer = await rl.question(`\nTheme (1-${AVAILABLE_THEMES.length}, default 1): `);
97
+ const themeIndex = Math.max(0, Math.min(AVAILABLE_THEMES.length - 1, parseInt(themeAnswer || '1', 10) - 1));
98
+ const theme = AVAILABLE_THEMES[themeIndex];
99
+ // Style import format
100
+ const styleAnswer = await rl.question('Style format (scss/css, default scss): ');
101
+ const styleImport = (styleAnswer.trim() || 'scss') === 'css' ? 'css' : 'scss';
102
+ const config = { ...DEFAULT_CONFIG, theme, styleImport };
103
+ if (opts.dryRun) {
104
+ logger.info('Dry run — would create:');
105
+ console.log(' viui.config.ts');
106
+ console.log(' .viui-lock.json');
107
+ console.log(` ${config.outputDir} (theme files)`);
108
+ if (config.vuetifyIntegration) {
109
+ console.log(' src/plugins/viui-conf/');
110
+ console.log(' src/plugins/vuetify.ts');
111
+ console.log(' main.ts (will be patched)');
112
+ }
113
+ const detectedAi = detectAiSystems(cwd);
114
+ if (detectedAi.length > 0) {
115
+ console.log('\n AI prompts (auto-detected):');
116
+ detectedAi.forEach(a => console.log(` ${a.outputPath} (${a.name})`));
117
+ }
118
+ return;
119
+ }
120
+ // Write config
121
+ writeConfig(cwd, config);
122
+ // Copy theme files
123
+ if (fs.existsSync(assetsDir)) {
124
+ copyThemeFiles(cwd, assetsDir, config.outputDir);
125
+ if (config.vuetifyIntegration) {
126
+ copyViuiConf(cwd, assetsDir);
127
+ }
128
+ }
129
+ // Create lock file
130
+ const lockFile = createLockFile(getCliVersion(), theme, styleImport);
131
+ writeLockFile(cwd, lockFile);
132
+ // Scaffold vuetify plugin + patch main.ts entry
133
+ if (config.vuetifyIntegration) {
134
+ scaffoldVuetifyPlugin(cwd, assetsDir);
135
+ patchMainEntry(cwd);
136
+ }
137
+ // Generate AI prompts
138
+ try {
139
+ if (config.prompts?.enabled !== false) {
140
+ const adapters = config.prompts?.targets
141
+ ? config.prompts.targets.map(getAdapterByName).filter((a) => !!a)
142
+ : detectAiSystems(cwd);
143
+ if (adapters.length > 0) {
144
+ const data = loadPromptData(config.prompts);
145
+ const meta = {
146
+ theme,
147
+ version: getCliVersion(),
148
+ generatedAt: new Date().toISOString().split('T')[0],
149
+ };
150
+ const markdown = buildCanonicalPrompt(data, meta, config.prompts?.extraRules);
151
+ for (const adapter of adapters) {
152
+ let output = adapter.transform(markdown, meta);
153
+ const outputPath = path.join(cwd, adapter.outputPath);
154
+ // Merge with existing content for shared files (e.g. copilot-instructions.md)
155
+ if (adapter.name === 'GitHub Copilot' && fs.existsSync(outputPath)) {
156
+ const existing = fs.readFileSync(outputPath, 'utf8');
157
+ output = mergeWithExisting(existing, output);
158
+ }
159
+ ensureDir(path.dirname(outputPath));
160
+ writeFileSafe(outputPath, output);
161
+ logger.success(`AI prompt: ${adapter.outputPath} (${adapter.name})`);
162
+ }
163
+ }
164
+ else {
165
+ logger.dim('No AI systems detected — skipping prompt generation');
166
+ logger.dim('Tip: create .claude/ or .cursor/ directory and run viui sync');
167
+ }
168
+ }
169
+ }
170
+ catch (err) {
171
+ logger.warn(`Prompt generation failed: ${err.message}`);
172
+ logger.dim('You can retry with viui sync');
173
+ }
174
+ logger.br();
175
+ logger.success(`Initialized viui with theme: ${theme}`);
176
+ printSetupInstructions();
177
+ logger.dim('Next: run `viui doctor` to verify setup');
178
+ }
179
+ finally {
180
+ rl.close();
181
+ }
182
+ });
183
+ }
@@ -0,0 +1,3 @@
1
+ import type { Command } from 'commander';
2
+ export declare function registerSyncCommand(program: Command): void;
3
+ //# sourceMappingURL=sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/commands/sync.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAYxC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA0E1D"}
@@ -0,0 +1,73 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { logger } from '../utils/logger.js';
4
+ import { copyDirRecursive } from '../utils/fs-safe.js';
5
+ import { printDiff, printDiffSummary, generateDiffLines } from '../utils/diff-display.js';
6
+ import { diffDirectories, readFileOrEmpty } from '../services/diff-engine.js';
7
+ import { createBackup } from '../services/backup-service.js';
8
+ import { readLockFile, writeLockFile } from '../services/lock-file-service.js';
9
+ import { readConfig } from '../services/config-service.js';
10
+ import { getAssetsDir } from '../cli-paths.js';
11
+ export function registerSyncCommand(program) {
12
+ program
13
+ .command('sync')
14
+ .description('Sync themes and tokens from design system registry')
15
+ .option('--diff', 'Show diff only, do not apply')
16
+ .option('--dry-run', 'Simulate without writing files')
17
+ .option('--apply', 'Apply changes after preview')
18
+ .action(async (opts) => {
19
+ const cwd = process.cwd();
20
+ const config = readConfig(cwd);
21
+ if (!config) {
22
+ logger.error('viui.config.ts not found. Run `viui init` first.');
23
+ process.exitCode = 1;
24
+ return;
25
+ }
26
+ const assetsDir = getAssetsDir();
27
+ const themesSrc = path.join(assetsDir, 'themes');
28
+ const themesDest = path.join(cwd, config.outputDir);
29
+ if (!fs.existsSync(themesSrc)) {
30
+ logger.error('Theme assets not found in CLI bundle.');
31
+ process.exitCode = 1;
32
+ return;
33
+ }
34
+ // Show diff between source and local
35
+ const diff = diffDirectories(themesSrc, themesDest);
36
+ const totalChanges = diff.added.length + diff.modified.length + diff.removed.length;
37
+ if (totalChanges === 0) {
38
+ logger.success('Everything up to date.');
39
+ return;
40
+ }
41
+ // Show file-level diff for modified files
42
+ for (const file of diff.modified) {
43
+ const oldContent = readFileOrEmpty(path.join(themesDest, file));
44
+ const newContent = readFileOrEmpty(path.join(themesSrc, file));
45
+ const lines = generateDiffLines(oldContent, newContent);
46
+ printDiff(file, lines);
47
+ }
48
+ printDiffSummary({
49
+ added: diff.added.length,
50
+ modified: diff.modified.length,
51
+ removed: diff.removed.length,
52
+ });
53
+ if (opts.diff || opts.dryRun) {
54
+ logger.dim('Dry run — no changes applied. Use --apply to apply.');
55
+ return;
56
+ }
57
+ if (!opts.apply) {
58
+ logger.dim('Preview only. Use --apply to apply changes.');
59
+ return;
60
+ }
61
+ // Backup current files before overwrite
62
+ createBackup(cwd, config.outputDir);
63
+ // Apply: copy source themes to local
64
+ copyDirRecursive(themesSrc, themesDest);
65
+ logger.success(`Synced themes to ${config.outputDir}`);
66
+ // Update lock file
67
+ const lockFile = readLockFile(cwd);
68
+ if (lockFile) {
69
+ lockFile.metadata.generatedAt = new Date().toISOString();
70
+ writeLockFile(cwd, lockFile);
71
+ }
72
+ });
73
+ }
@@ -0,0 +1,3 @@
1
+ import type { Command } from 'commander';
2
+ export declare function registerThemeCommand(program: Command): void;
3
+ //# sourceMappingURL=theme.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../../src/commands/theme.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAkBxC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAgF3D"}
@@ -0,0 +1,86 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import chalk from 'chalk';
4
+ import { logger } from '../utils/logger.js';
5
+ import { AVAILABLE_THEMES } from '../types/config-types.js';
6
+ import { readConfig } from '../services/config-service.js';
7
+ import { readLockFile, writeLockFile } from '../services/lock-file-service.js';
8
+ import { getAssetsDir } from '../cli-paths.js';
9
+ /** Read theme SCSS and extract CSS custom properties for preview */
10
+ function extractThemeVars(themePath) {
11
+ if (!fs.existsSync(themePath))
12
+ return [];
13
+ const content = fs.readFileSync(themePath, 'utf8');
14
+ const vars = content.match(/--[\w-]+:\s*[^;]+/g) ?? [];
15
+ return vars.slice(0, 15); // Show first 15 vars
16
+ }
17
+ export function registerThemeCommand(program) {
18
+ const theme = program
19
+ .command('theme')
20
+ .description('List, switch, or preview themes');
21
+ theme
22
+ .command('list')
23
+ .description('Show available themes')
24
+ .action(() => {
25
+ const cwd = process.cwd();
26
+ const config = readConfig(cwd);
27
+ const activeTheme = config?.theme ?? '';
28
+ logger.header('Available themes:');
29
+ for (const t of AVAILABLE_THEMES) {
30
+ const marker = t === activeTheme ? chalk.green(' (active)') : '';
31
+ console.log(` - ${t}${marker}`);
32
+ }
33
+ });
34
+ theme
35
+ .command('switch <name>')
36
+ .description('Switch to a different theme')
37
+ .action((name) => {
38
+ const cwd = process.cwd();
39
+ if (!AVAILABLE_THEMES.includes(name)) {
40
+ logger.error(`Unknown theme: ${name}. Available: ${AVAILABLE_THEMES.join(', ')}`);
41
+ process.exitCode = 1;
42
+ return;
43
+ }
44
+ // Update viui.config.ts
45
+ const configPath = path.join(cwd, 'viui.config.ts');
46
+ if (!fs.existsSync(configPath)) {
47
+ logger.error('viui.config.ts not found. Run `viui init` first.');
48
+ process.exitCode = 1;
49
+ return;
50
+ }
51
+ let content = fs.readFileSync(configPath, 'utf8');
52
+ content = content.replace(/theme:\s*['"][^'"]+['"]/, `theme: '${name}'`);
53
+ fs.writeFileSync(configPath, content, 'utf8');
54
+ // Update lock file
55
+ const lockFile = readLockFile(cwd);
56
+ if (lockFile) {
57
+ lockFile.config.theme = name;
58
+ writeLockFile(cwd, lockFile);
59
+ }
60
+ logger.success(`Switched to theme: ${name}`);
61
+ });
62
+ theme
63
+ .command('preview <name>')
64
+ .description('Preview theme CSS variables in terminal')
65
+ .action((name) => {
66
+ const assetsDir = getAssetsDir();
67
+ const themePath = path.join(assetsDir, 'themes', `_${name}.scss`);
68
+ if (!fs.existsSync(themePath)) {
69
+ logger.error(`Theme file not found: ${name}`);
70
+ process.exitCode = 1;
71
+ return;
72
+ }
73
+ logger.header(`Theme preview: ${name}`);
74
+ const vars = extractThemeVars(themePath);
75
+ if (vars.length === 0) {
76
+ logger.dim(' No CSS variables found in theme file');
77
+ return;
78
+ }
79
+ for (const v of vars) {
80
+ console.log(chalk.dim(` ${v}`));
81
+ }
82
+ if (vars.length >= 15) {
83
+ logger.dim(' ... (truncated)');
84
+ }
85
+ });
86
+ }
@@ -0,0 +1,3 @@
1
+ import type { Command } from 'commander';
2
+ export declare function registerUpdateCommand(program: Command): void;
3
+ //# sourceMappingURL=update.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAkBxC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA2F5D"}
@@ -0,0 +1,97 @@
1
+ import { execFileSync } from 'node:child_process';
2
+ import readline from 'node:readline/promises';
3
+ import { logger } from '../utils/logger.js';
4
+ import { readConfig } from '../services/config-service.js';
5
+ import { readLockFile, writeLockFile } from '../services/lock-file-service.js';
6
+ import { createBackup } from '../services/backup-service.js';
7
+ /** Fetch latest version from npm registry (safe: no shell interpolation) */
8
+ function fetchLatestVersion(packageName) {
9
+ try {
10
+ const result = execFileSync('npm', ['view', packageName, 'version'], { encoding: 'utf8' });
11
+ return result.trim();
12
+ }
13
+ catch {
14
+ return null;
15
+ }
16
+ }
17
+ export function registerUpdateCommand(program) {
18
+ program
19
+ .command('update')
20
+ .description('Check for updates and apply with merge support')
21
+ .option('--diff', 'Show available updates without applying')
22
+ .option('--dry-run', 'Simulate update without writing files')
23
+ .option('--apply', 'Apply updates after preview')
24
+ .action(async (opts) => {
25
+ const cwd = process.cwd();
26
+ const config = readConfig(cwd);
27
+ if (!config) {
28
+ logger.error('viui.config.ts not found. Run `viui init` first.');
29
+ process.exitCode = 1;
30
+ return;
31
+ }
32
+ const lockFile = readLockFile(cwd);
33
+ if (!lockFile) {
34
+ logger.error('.viui-lock.json not found. Run `viui init` first.');
35
+ process.exitCode = 1;
36
+ return;
37
+ }
38
+ logger.info('Checking for updates...');
39
+ // Check token version
40
+ const latestTokens = fetchLatestVersion(config.tokens);
41
+ const currentTokens = lockFile.tokens.version;
42
+ // Check theme versions
43
+ const latestThemes = fetchLatestVersion('@viui/themes');
44
+ const currentTheme = lockFile.themes[config.theme]?.version ?? '0.0.0';
45
+ const updates = [];
46
+ if (latestTokens && latestTokens !== currentTokens) {
47
+ updates.push(` tokens: ${currentTokens} → ${latestTokens}`);
48
+ }
49
+ if (latestThemes && latestThemes !== currentTheme) {
50
+ updates.push(` themes: ${currentTheme} → ${latestThemes}`);
51
+ }
52
+ if (updates.length === 0) {
53
+ logger.success('All packages up to date.');
54
+ return;
55
+ }
56
+ logger.header('\nAvailable updates:');
57
+ updates.forEach((u) => console.log(u));
58
+ logger.br();
59
+ if (opts.diff || opts.dryRun) {
60
+ logger.dim('Preview only. Use --apply to apply updates.');
61
+ return;
62
+ }
63
+ if (!opts.apply) {
64
+ logger.dim('Run with --apply to apply these updates.');
65
+ return;
66
+ }
67
+ // Backup before applying
68
+ createBackup(cwd, config.outputDir);
69
+ createBackup(cwd, '.viui-lock.json');
70
+ // Update lock file versions
71
+ if (latestTokens)
72
+ lockFile.tokens.version = latestTokens;
73
+ if (latestThemes && lockFile.themes[config.theme]) {
74
+ lockFile.themes[config.theme].version = latestThemes;
75
+ }
76
+ writeLockFile(cwd, lockFile);
77
+ logger.success('Lock file updated.');
78
+ // Prompt user to sync files immediately
79
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
80
+ try {
81
+ const answer = await rl.question('Sync files now? (Y/n): ');
82
+ if (answer.trim().toLowerCase() !== 'n') {
83
+ logger.info('Running sync...');
84
+ execFileSync('node', [process.argv[1], 'sync', '--apply'], {
85
+ cwd,
86
+ stdio: 'inherit',
87
+ });
88
+ }
89
+ else {
90
+ logger.dim('Skipped. Run `viui sync --apply` to pull latest files.');
91
+ }
92
+ }
93
+ finally {
94
+ rl.close();
95
+ }
96
+ });
97
+ }
@@ -0,0 +1,4 @@
1
+ import type { PromptData } from './prompt-data-loader.js';
2
+ import type { PromptMeta } from '../adapters/adapter-types.js';
3
+ export declare function buildCanonicalPrompt(data: PromptData, meta: PromptMeta, extraRules?: string): string;
4
+ //# sourceMappingURL=prompt-builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-builder.d.ts","sourceRoot":"","sources":["../../src/prompts/prompt-builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAA;AACzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAA;AAM9D,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,UAAU,EAChB,IAAI,EAAE,UAAU,EAChB,UAAU,CAAC,EAAE,MAAM,GAClB,MAAM,CAeR"}
@@ -0,0 +1,18 @@
1
+ import { buildComponentMapSection } from './prompt-sections/section-component-map.js';
2
+ import { buildColorTokensSection } from './prompt-sections/section-color-tokens.js';
3
+ import { buildTypographySpacingSection } from './prompt-sections/section-typography-spacing.js';
4
+ import { buildCodeExamplesSection } from './prompt-sections/section-code-examples.js';
5
+ export function buildCanonicalPrompt(data, meta, extraRules) {
6
+ const header = `# iNET Design System — ViUI Rules\n\n`
7
+ + `> Auto-generated by viui v${meta.version} | Theme: ${meta.theme} | ${meta.generatedAt}\n`
8
+ + `> DO NOT edit manually — regenerate with \`viui sync\`\n`;
9
+ const sections = [
10
+ header,
11
+ buildComponentMapSection(data.components),
12
+ buildColorTokensSection(data.tokens),
13
+ buildTypographySpacingSection(data.tokens),
14
+ buildCodeExamplesSection(),
15
+ extraRules ?? '',
16
+ ];
17
+ return sections.filter(Boolean).join('\n\n');
18
+ }