@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.
- package/README.md +138 -139
- package/dist/adapters/adapter-registry.d.ts +12 -0
- package/dist/adapters/adapter-registry.d.ts.map +1 -0
- package/dist/adapters/adapter-registry.js +49 -0
- package/dist/adapters/adapter-types.d.ts +20 -0
- package/dist/adapters/adapter-types.d.ts.map +1 -0
- package/dist/adapters/adapter-types.js +1 -0
- package/dist/adapters/aider-adapter.d.ts +3 -0
- package/dist/adapters/aider-adapter.d.ts.map +1 -0
- package/dist/adapters/aider-adapter.js +8 -0
- package/dist/adapters/claude-adapter.d.ts +3 -0
- package/dist/adapters/claude-adapter.d.ts.map +1 -0
- package/dist/adapters/claude-adapter.js +15 -0
- package/dist/adapters/cline-adapter.d.ts +3 -0
- package/dist/adapters/cline-adapter.d.ts.map +1 -0
- package/dist/adapters/cline-adapter.js +8 -0
- package/dist/adapters/copilot-adapter.d.ts +5 -0
- package/dist/adapters/copilot-adapter.d.ts.map +1 -0
- package/dist/adapters/copilot-adapter.js +20 -0
- package/dist/adapters/cursor-adapter.d.ts +3 -0
- package/dist/adapters/cursor-adapter.d.ts.map +1 -0
- package/dist/adapters/cursor-adapter.js +18 -0
- package/dist/adapters/external/bolt-adapter.d.ts +3 -0
- package/dist/adapters/external/bolt-adapter.d.ts.map +1 -0
- package/dist/adapters/external/bolt-adapter.js +15 -0
- package/dist/adapters/external/chatgpt-adapter.d.ts +3 -0
- package/dist/adapters/external/chatgpt-adapter.d.ts.map +1 -0
- package/dist/adapters/external/chatgpt-adapter.js +14 -0
- package/dist/adapters/external/external-adapter-base.d.ts +15 -0
- package/dist/adapters/external/external-adapter-base.d.ts.map +1 -0
- package/dist/adapters/external/external-adapter-base.js +92 -0
- package/dist/adapters/external/gemini-adapter.d.ts +3 -0
- package/dist/adapters/external/gemini-adapter.d.ts.map +1 -0
- package/dist/adapters/external/gemini-adapter.js +14 -0
- package/dist/adapters/external/lovable-adapter.d.ts +3 -0
- package/dist/adapters/external/lovable-adapter.d.ts.map +1 -0
- package/dist/adapters/external/lovable-adapter.js +14 -0
- package/dist/adapters/external/v0-adapter.d.ts +3 -0
- package/dist/adapters/external/v0-adapter.d.ts.map +1 -0
- package/dist/adapters/external/v0-adapter.js +15 -0
- package/dist/adapters/windsurf-adapter.d.ts +3 -0
- package/dist/adapters/windsurf-adapter.d.ts.map +1 -0
- package/dist/adapters/windsurf-adapter.js +23 -0
- package/dist/assets/plugins/viui-conf/apply-theme-body.ts +23 -4
- package/dist/assets/plugins/viui-conf/defaults/README.md +2 -0
- package/dist/assets/plugins/viui-conf/defaults/app-bar.ts +1 -1
- package/dist/assets/plugins/viui-conf/defaults/buttons.ts +1 -1
- package/dist/assets/plugins/viui-conf/defaults/by-theme/minimalist-2.ts +1 -1
- package/dist/assets/plugins/viui-conf/defaults/cards.ts +1 -1
- package/dist/assets/plugins/viui-conf/defaults/expansion-panels.ts +16 -0
- package/dist/assets/plugins/viui-conf/defaults/index.ts +3 -0
- package/dist/assets/plugins/viui-conf/defaults/inputs.ts +11 -1
- package/dist/assets/plugins/viui-conf/design-tokens.ts +135 -0
- package/dist/assets/plugins/viui-conf/theme-base.ts +1 -1
- package/dist/assets/plugins/viui-conf/v-dark.ts +3 -5
- package/dist/assets/plugins/viui-conf/v-light.ts +3 -5
- package/dist/assets/plugins/vuetify.ts +36 -0
- package/dist/assets/prompt-data/components.json +106 -0
- package/dist/assets/prompt-data/tokens.json +83 -0
- package/dist/assets/themes/_bento-grid.scss +8 -0
- package/dist/assets/themes/_glassmorphism.scss +8 -0
- package/dist/assets/themes/_material.scss +8 -0
- package/dist/assets/themes/_minimalist-2.scss +375 -0
- package/dist/assets/themes/_minimalist.scss +9 -0
- package/dist/assets/themes/_neo-brutalism.scss +199 -0
- package/dist/assets/themes/bento-grid.scss +4 -0
- package/dist/assets/themes/glassmorphism.scss +4 -0
- package/dist/assets/themes/index.scss +11 -0
- package/dist/assets/themes/material.scss +4 -0
- package/dist/assets/themes/minimalist-2.scss +5 -0
- package/dist/assets/themes/minimalist.scss +4 -0
- package/dist/assets/themes/neo-brutalism.scss +5 -0
- package/dist/assets/viui-themes/_neo-brutalism.scss +70 -152
- package/dist/cli-paths.d.ts +7 -0
- package/dist/cli-paths.d.ts.map +1 -0
- package/dist/cli-paths.js +19 -0
- package/dist/cli.js +28 -578
- package/dist/cli.legacy.d.ts +3 -0
- package/dist/cli.legacy.d.ts.map +1 -0
- package/dist/cli.legacy.js +597 -0
- package/dist/commands/audit.d.ts +3 -0
- package/dist/commands/audit.d.ts.map +1 -0
- package/dist/commands/audit.js +152 -0
- package/dist/commands/config/config-export.d.ts +6 -0
- package/dist/commands/config/config-export.d.ts.map +1 -0
- package/dist/commands/config/config-export.js +23 -0
- package/dist/commands/config/config-health.d.ts +6 -0
- package/dist/commands/config/config-health.d.ts.map +1 -0
- package/dist/commands/config/config-health.js +42 -0
- package/dist/commands/config/config-import.d.ts +6 -0
- package/dist/commands/config/config-import.d.ts.map +1 -0
- package/dist/commands/config/config-import.js +63 -0
- package/dist/commands/config/config-rollback.d.ts +6 -0
- package/dist/commands/config/config-rollback.d.ts.map +1 -0
- package/dist/commands/config/config-rollback.js +47 -0
- package/dist/commands/config/config-setup.d.ts +6 -0
- package/dist/commands/config/config-setup.d.ts.map +1 -0
- package/dist/commands/config/config-setup.js +103 -0
- package/dist/commands/config/config-status.d.ts +6 -0
- package/dist/commands/config/config-status.d.ts.map +1 -0
- package/dist/commands/config/config-status.js +42 -0
- package/dist/commands/config/config-uninstall.d.ts +6 -0
- package/dist/commands/config/config-uninstall.d.ts.map +1 -0
- package/dist/commands/config/config-uninstall.js +74 -0
- package/dist/commands/config.d.ts +6 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +19 -0
- package/dist/commands/docs.d.ts +3 -0
- package/dist/commands/docs.d.ts.map +1 -0
- package/dist/commands/docs.js +17 -0
- package/dist/commands/doctor.d.ts +3 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +93 -0
- package/dist/commands/init.d.ts +3 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +183 -0
- package/dist/commands/sync.d.ts +3 -0
- package/dist/commands/sync.d.ts.map +1 -0
- package/dist/commands/sync.js +73 -0
- package/dist/commands/theme.d.ts +3 -0
- package/dist/commands/theme.d.ts.map +1 -0
- package/dist/commands/theme.js +86 -0
- package/dist/commands/update.d.ts +3 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +97 -0
- package/dist/prompts/prompt-builder.d.ts +4 -0
- package/dist/prompts/prompt-builder.d.ts.map +1 -0
- package/dist/prompts/prompt-builder.js +18 -0
- package/dist/prompts/prompt-data-loader.d.ts +11 -0
- package/dist/prompts/prompt-data-loader.d.ts.map +1 -0
- package/dist/prompts/prompt-data-loader.js +15 -0
- package/dist/prompts/prompt-sections/section-code-examples.d.ts +2 -0
- package/dist/prompts/prompt-sections/section-code-examples.d.ts.map +1 -0
- package/dist/prompts/prompt-sections/section-code-examples.js +36 -0
- package/dist/prompts/prompt-sections/section-color-tokens.d.ts +2 -0
- package/dist/prompts/prompt-sections/section-color-tokens.d.ts.map +1 -0
- package/dist/prompts/prompt-sections/section-color-tokens.js +19 -0
- package/dist/prompts/prompt-sections/section-component-map.d.ts +3 -0
- package/dist/prompts/prompt-sections/section-component-map.d.ts.map +1 -0
- package/dist/prompts/prompt-sections/section-component-map.js +12 -0
- package/dist/prompts/prompt-sections/section-typography-spacing.d.ts +2 -0
- package/dist/prompts/prompt-sections/section-typography-spacing.d.ts.map +1 -0
- package/dist/prompts/prompt-sections/section-typography-spacing.js +29 -0
- package/dist/services/backup-service.d.ts +7 -0
- package/dist/services/backup-service.d.ts.map +1 -0
- package/dist/services/backup-service.js +54 -0
- package/dist/services/config-service.d.ts +17 -0
- package/dist/services/config-service.d.ts.map +1 -0
- package/dist/services/config-service.js +64 -0
- package/dist/services/diff-engine.d.ts +13 -0
- package/dist/services/diff-engine.d.ts.map +1 -0
- package/dist/services/diff-engine.js +59 -0
- package/dist/services/ide-detector.d.ts +9 -0
- package/dist/services/ide-detector.d.ts.map +1 -0
- package/dist/services/ide-detector.js +113 -0
- package/dist/services/ide-detector.spec.d.ts +2 -0
- package/dist/services/ide-detector.spec.d.ts.map +1 -0
- package/dist/services/ide-detector.spec.js +108 -0
- package/dist/services/lock-file-service.d.ts +15 -0
- package/dist/services/lock-file-service.d.ts.map +1 -0
- package/dist/services/lock-file-service.js +74 -0
- package/dist/services/mcp-config-reader.d.ts +11 -0
- package/dist/services/mcp-config-reader.d.ts.map +1 -0
- package/dist/services/mcp-config-reader.js +40 -0
- package/dist/services/mcp-config-reader.spec.d.ts +2 -0
- package/dist/services/mcp-config-reader.spec.d.ts.map +1 -0
- package/dist/services/mcp-config-reader.spec.js +125 -0
- package/dist/services/mcp-config-writer.d.ts +11 -0
- package/dist/services/mcp-config-writer.d.ts.map +1 -0
- package/dist/services/mcp-config-writer.js +98 -0
- package/dist/services/mcp-config-writer.spec.d.ts +2 -0
- package/dist/services/mcp-config-writer.spec.d.ts.map +1 -0
- package/dist/services/mcp-config-writer.spec.js +162 -0
- package/dist/services/merge-engine.d.ts +12 -0
- package/dist/services/merge-engine.d.ts.map +1 -0
- package/dist/services/merge-engine.js +54 -0
- package/dist/services/vuetify-scaffold-service.d.ts +5 -0
- package/dist/services/vuetify-scaffold-service.d.ts.map +1 -0
- package/dist/services/vuetify-scaffold-service.js +67 -0
- package/dist/templates/vuetify-plugin.d.ts +90 -0
- package/dist/templates/vuetify-plugin.d.ts.map +1 -0
- package/dist/templates/vuetify-plugin.js +33 -0
- package/dist/types/command-types.d.ts +15 -0
- package/dist/types/command-types.d.ts.map +1 -0
- package/dist/types/command-types.js +2 -0
- package/dist/types/config-types.d.ts +29 -0
- package/dist/types/config-types.d.ts.map +1 -0
- package/dist/types/config-types.js +10 -0
- package/dist/types/ide-types.d.ts +29 -0
- package/dist/types/ide-types.d.ts.map +1 -0
- package/dist/types/ide-types.js +4 -0
- package/dist/types/lock-file-types.d.ts +27 -0
- package/dist/types/lock-file-types.d.ts.map +1 -0
- package/dist/types/lock-file-types.js +2 -0
- package/dist/utils/diff-display.d.ts +18 -0
- package/dist/utils/diff-display.d.ts.map +1 -0
- package/dist/utils/diff-display.js +61 -0
- package/dist/utils/fs-safe.d.ts +9 -0
- package/dist/utils/fs-safe.d.ts.map +1 -0
- package/dist/utils/fs-safe.js +44 -0
- package/dist/utils/logger.d.ts +14 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +28 -0
- package/dist/utils/open-browser.d.ts +3 -0
- package/dist/utils/open-browser.d.ts.map +1 -0
- package/dist/utils/open-browser.js +13 -0
- package/package.json +11 -6
- package/dist/assets/cursor/.design-system-version +0 -1
- package/dist/assets/cursor/commands/audit-accessibility.md +0 -25
- package/dist/assets/cursor/commands/audit-ui.md +0 -35
- package/dist/assets/cursor/commands/component.md +0 -18
- package/dist/assets/cursor/commands/fix-storybook.md +0 -24
- package/dist/assets/cursor/commands/generate-component-from-figma.md +0 -26
- package/dist/assets/cursor/commands/generate-page-from-figma.md +0 -26
- package/dist/assets/cursor/plans/DESIGN_SYSTEM_PLAN.md +0 -177
- package/dist/assets/cursor/plans/PLANS_INDEX.md +0 -35
- package/dist/assets/cursor/rules/accessibility-contrast.mdc +0 -38
- package/dist/assets/cursor/rules/bem-class-style.mdc +0 -107
- package/dist/assets/cursor/rules/component-naming.mdc +0 -57
- package/dist/assets/cursor/rules/design-system-component-library.mdc +0 -59
- package/dist/assets/cursor/rules/design-system-workflow.mdc +0 -48
- package/dist/assets/cursor/rules/figma-mapping.mdc +0 -37
- package/dist/assets/cursor/rules/icons.mdc +0 -42
- package/dist/assets/cursor/rules/project-structure.mdc +0 -137
- package/dist/assets/cursor/rules/storybook-component-template.mdc +0 -103
- package/dist/assets/cursor/rules/storybook.mdc +0 -68
- package/dist/assets/cursor/rules/tokens.mdc +0 -32
- package/dist/assets/cursor/rules/viui-themes.mdc +0 -53
- package/dist/assets/cursor/rules/vuetify-layout.mdc +0 -52
- package/dist/assets/cursor/skills/accessibility.md +0 -75
- package/dist/assets/cursor/skills/design-system-thinking.md +0 -40
- package/dist/assets/cursor/skills/figma-interpretation.md +0 -38
- package/dist/assets/cursor/skills/vue-vuetify-design-system-architect.md +0 -60
- package/dist/assets/cursor/sync-manifest.json +0 -6
- package/dist/assets/viui-themes/bento-grid-global.scss +0 -5
- package/dist/assets/viui-themes/glassmorphism-global.scss +0 -5
- package/dist/assets/viui-themes/material-global.scss +0 -5
- package/dist/assets/viui-themes/minimalist-2-global.scss +0 -5
- package/dist/assets/viui-themes/minimalist-global.scss +0 -5
- 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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
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
|
+
}
|