@vizzly-testing/cli 0.13.4 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. package/dist/cli.js +68 -68
  2. package/dist/commands/doctor.js +30 -34
  3. package/dist/commands/finalize.js +24 -23
  4. package/dist/commands/init.js +30 -28
  5. package/dist/commands/login.js +49 -55
  6. package/dist/commands/logout.js +14 -19
  7. package/dist/commands/project.js +83 -103
  8. package/dist/commands/run.js +77 -89
  9. package/dist/commands/status.js +48 -49
  10. package/dist/commands/tdd-daemon.js +90 -86
  11. package/dist/commands/tdd.js +59 -88
  12. package/dist/commands/upload.js +57 -57
  13. package/dist/commands/whoami.js +40 -45
  14. package/dist/index.js +2 -5
  15. package/dist/plugin-loader.js +15 -17
  16. package/dist/reporter/reporter-bundle.css +1 -1
  17. package/dist/reporter/reporter-bundle.iife.js +78 -32
  18. package/dist/sdk/index.js +36 -45
  19. package/dist/server/handlers/api-handler.js +14 -15
  20. package/dist/server/handlers/tdd-handler.js +34 -37
  21. package/dist/server/http-server.js +75 -869
  22. package/dist/server/middleware/cors.js +22 -0
  23. package/dist/server/middleware/json-parser.js +35 -0
  24. package/dist/server/middleware/response.js +79 -0
  25. package/dist/server/routers/assets.js +91 -0
  26. package/dist/server/routers/auth.js +144 -0
  27. package/dist/server/routers/baseline.js +163 -0
  28. package/dist/server/routers/cloud-proxy.js +146 -0
  29. package/dist/server/routers/config.js +126 -0
  30. package/dist/server/routers/dashboard.js +130 -0
  31. package/dist/server/routers/health.js +61 -0
  32. package/dist/server/routers/projects.js +168 -0
  33. package/dist/server/routers/screenshot.js +86 -0
  34. package/dist/services/auth-service.js +1 -1
  35. package/dist/services/build-manager.js +13 -40
  36. package/dist/services/config-service.js +2 -4
  37. package/dist/services/html-report-generator.js +6 -5
  38. package/dist/services/index.js +64 -0
  39. package/dist/services/project-service.js +121 -40
  40. package/dist/services/screenshot-server.js +9 -9
  41. package/dist/services/server-manager.js +11 -18
  42. package/dist/services/static-report-generator.js +3 -4
  43. package/dist/services/tdd-service.js +246 -103
  44. package/dist/services/test-runner.js +24 -25
  45. package/dist/services/uploader.js +5 -4
  46. package/dist/types/commands/init.d.ts +1 -2
  47. package/dist/types/index.d.ts +2 -3
  48. package/dist/types/plugin-loader.d.ts +1 -2
  49. package/dist/types/reporter/src/api/client.d.ts +178 -0
  50. package/dist/types/reporter/src/components/app-router.d.ts +1 -3
  51. package/dist/types/reporter/src/components/code-block.d.ts +4 -0
  52. package/dist/types/reporter/src/components/comparison/comparison-modes/onion-skin-mode.d.ts +10 -0
  53. package/dist/types/reporter/src/components/comparison/comparison-modes/overlay-mode.d.ts +11 -0
  54. package/dist/types/reporter/src/components/comparison/comparison-modes/shared/base-comparison-mode.d.ts +14 -0
  55. package/dist/types/reporter/src/components/comparison/comparison-modes/shared/image-renderer.d.ts +30 -0
  56. package/dist/types/reporter/src/components/comparison/comparison-modes/toggle-view.d.ts +8 -0
  57. package/dist/types/reporter/src/components/comparison/comparison-viewer.d.ts +4 -0
  58. package/dist/types/reporter/src/components/comparison/fullscreen-viewer.d.ts +13 -0
  59. package/dist/types/reporter/src/components/comparison/screenshot-display.d.ts +16 -0
  60. package/dist/types/reporter/src/components/comparison/screenshot-list.d.ts +9 -0
  61. package/dist/types/reporter/src/components/comparison/variant-selector.d.ts +1 -1
  62. package/dist/types/reporter/src/components/design-system/alert.d.ts +9 -0
  63. package/dist/types/reporter/src/components/design-system/badge.d.ts +17 -0
  64. package/dist/types/reporter/src/components/design-system/button.d.ts +19 -0
  65. package/dist/types/reporter/src/components/design-system/card.d.ts +31 -0
  66. package/dist/types/reporter/src/components/design-system/empty-state.d.ts +13 -0
  67. package/dist/types/reporter/src/components/design-system/form-controls.d.ts +44 -0
  68. package/dist/types/reporter/src/components/design-system/health-ring.d.ts +7 -0
  69. package/dist/types/reporter/src/components/design-system/index.d.ts +11 -0
  70. package/dist/types/reporter/src/components/design-system/modal.d.ts +10 -0
  71. package/dist/types/reporter/src/components/design-system/skeleton.d.ts +19 -0
  72. package/dist/types/reporter/src/components/design-system/spinner.d.ts +10 -0
  73. package/dist/types/reporter/src/components/design-system/tabs.d.ts +13 -0
  74. package/dist/types/reporter/src/components/layout/header.d.ts +5 -0
  75. package/dist/types/reporter/src/components/layout/index.d.ts +2 -0
  76. package/dist/types/reporter/src/components/layout/layout.d.ts +6 -0
  77. package/dist/types/reporter/src/components/views/builds-view.d.ts +1 -0
  78. package/dist/types/reporter/src/components/views/comparison-detail-view.d.ts +5 -0
  79. package/dist/types/reporter/src/components/views/comparisons-view.d.ts +5 -6
  80. package/dist/types/reporter/src/components/views/stats-view.d.ts +1 -6
  81. package/dist/types/reporter/src/components/waiting-for-screenshots.d.ts +1 -0
  82. package/dist/types/reporter/src/hooks/queries/use-auth-queries.d.ts +15 -0
  83. package/dist/types/reporter/src/hooks/queries/use-cloud-queries.d.ts +6 -0
  84. package/dist/types/reporter/src/hooks/queries/use-config-queries.d.ts +6 -0
  85. package/dist/types/reporter/src/hooks/queries/use-tdd-queries.d.ts +9 -0
  86. package/dist/types/reporter/src/lib/query-client.d.ts +2 -0
  87. package/dist/types/reporter/src/lib/query-keys.d.ts +13 -0
  88. package/dist/types/sdk/index.d.ts +2 -4
  89. package/dist/types/server/handlers/tdd-handler.d.ts +2 -0
  90. package/dist/types/server/http-server.d.ts +1 -1
  91. package/dist/types/server/middleware/cors.d.ts +11 -0
  92. package/dist/types/server/middleware/json-parser.d.ts +10 -0
  93. package/dist/types/server/middleware/response.d.ts +50 -0
  94. package/dist/types/server/routers/assets.d.ts +6 -0
  95. package/dist/types/server/routers/auth.d.ts +9 -0
  96. package/dist/types/server/routers/baseline.d.ts +13 -0
  97. package/dist/types/server/routers/cloud-proxy.d.ts +11 -0
  98. package/dist/types/server/routers/config.d.ts +9 -0
  99. package/dist/types/server/routers/dashboard.d.ts +6 -0
  100. package/dist/types/server/routers/health.d.ts +11 -0
  101. package/dist/types/server/routers/projects.d.ts +9 -0
  102. package/dist/types/server/routers/screenshot.d.ts +11 -0
  103. package/dist/types/services/build-manager.d.ts +4 -3
  104. package/dist/types/services/config-service.d.ts +2 -3
  105. package/dist/types/services/index.d.ts +7 -0
  106. package/dist/types/services/project-service.d.ts +6 -4
  107. package/dist/types/services/screenshot-server.d.ts +5 -5
  108. package/dist/types/services/server-manager.d.ts +5 -3
  109. package/dist/types/services/tdd-service.d.ts +12 -1
  110. package/dist/types/services/test-runner.d.ts +3 -3
  111. package/dist/types/utils/output.d.ts +84 -0
  112. package/dist/utils/config-loader.js +24 -48
  113. package/dist/utils/global-config.js +2 -17
  114. package/dist/utils/output.js +445 -0
  115. package/dist/utils/security.js +3 -4
  116. package/docs/api-reference.md +0 -1
  117. package/docs/plugins.md +22 -22
  118. package/package.json +3 -2
  119. package/dist/container/index.js +0 -215
  120. package/dist/services/base-service.js +0 -154
  121. package/dist/types/container/index.d.ts +0 -59
  122. package/dist/types/reporter/src/components/comparison/viewer-modes/onion-viewer.d.ts +0 -3
  123. package/dist/types/reporter/src/components/comparison/viewer-modes/overlay-viewer.d.ts +0 -3
  124. package/dist/types/reporter/src/components/comparison/viewer-modes/side-by-side-viewer.d.ts +0 -3
  125. package/dist/types/reporter/src/components/comparison/viewer-modes/toggle-viewer.d.ts +0 -3
  126. package/dist/types/reporter/src/components/dashboard/dashboard-header.d.ts +0 -5
  127. package/dist/types/reporter/src/components/dashboard/dashboard-stats.d.ts +0 -4
  128. package/dist/types/reporter/src/components/dashboard/empty-state.d.ts +0 -8
  129. package/dist/types/reporter/src/components/ui/form-field.d.ts +0 -16
  130. package/dist/types/reporter/src/components/ui/status-badge.d.ts +0 -5
  131. package/dist/types/reporter/src/hooks/use-auth.d.ts +0 -10
  132. package/dist/types/reporter/src/hooks/use-baseline-actions.d.ts +0 -5
  133. package/dist/types/reporter/src/hooks/use-config.d.ts +0 -9
  134. package/dist/types/reporter/src/hooks/use-projects.d.ts +0 -10
  135. package/dist/types/reporter/src/hooks/use-report-data.d.ts +0 -7
  136. package/dist/types/reporter/src/hooks/use-vizzly-api.d.ts +0 -9
  137. package/dist/types/services/base-service.d.ts +0 -71
  138. package/dist/types/utils/console-ui.d.ts +0 -61
  139. package/dist/types/utils/logger-factory.d.ts +0 -26
  140. package/dist/types/utils/logger.d.ts +0 -79
  141. package/dist/utils/console-ui.js +0 -241
  142. package/dist/utils/logger-factory.js +0 -76
  143. package/dist/utils/logger.js +0 -231
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Configure output settings
3
+ * Call this once at CLI startup with global options
4
+ */
5
+ export function configure(options?: {}): void;
6
+ /**
7
+ * Show command header (e.g., "vizzly · tdd · local")
8
+ * Only shows once per command execution
9
+ */
10
+ export function header(command: any, mode?: any): void;
11
+ /**
12
+ * Get current colors instance (for custom formatting)
13
+ */
14
+ export function getColors(): {
15
+ success: any;
16
+ error: any;
17
+ warning: any;
18
+ info: any;
19
+ };
20
+ /**
21
+ * Show a success message
22
+ */
23
+ export function success(message: any, data?: {}): void;
24
+ /**
25
+ * Show final result summary (e.g., "✓ 5 screenshots · 234ms")
26
+ */
27
+ export function result(message: any): void;
28
+ /**
29
+ * Show an info message
30
+ */
31
+ export function info(message: any, data?: {}): void;
32
+ /**
33
+ * Show a warning message (goes to stderr)
34
+ */
35
+ export function warn(message: any, data?: {}): void;
36
+ /**
37
+ * Show an error message (goes to stderr)
38
+ * Does NOT exit - caller decides whether to exit
39
+ */
40
+ export function error(message: any, err?: any, data?: {}): void;
41
+ /**
42
+ * Print a blank line for spacing
43
+ */
44
+ export function blank(): void;
45
+ /**
46
+ * Print raw text without any formatting
47
+ */
48
+ export function print(text: any): void;
49
+ /**
50
+ * Print raw text to stderr
51
+ */
52
+ export function printErr(text: any): void;
53
+ /**
54
+ * Output structured data
55
+ */
56
+ export function data(obj: any): void;
57
+ /**
58
+ * Start a spinner with message
59
+ */
60
+ export function startSpinner(message: any): void;
61
+ /**
62
+ * Update spinner message
63
+ */
64
+ export function updateSpinner(message: any, current?: number, total?: number): void;
65
+ /**
66
+ * Stop the spinner
67
+ */
68
+ export function stopSpinner(): void;
69
+ /**
70
+ * Show progress update
71
+ */
72
+ export function progress(message: any, current?: number, total?: number): void;
73
+ /**
74
+ * Log debug message with component prefix (only shown in verbose mode)
75
+ *
76
+ * @param {string} component - Component name (e.g., 'server', 'config', 'build')
77
+ * @param {string} message - Debug message
78
+ * @param {Object} data - Optional data object to display inline
79
+ */
80
+ export function debug(component: string, message: string, data?: any): void;
81
+ /**
82
+ * Clean up (stop spinner, flush logs)
83
+ */
84
+ export function cleanup(): void;
@@ -3,7 +3,8 @@ import { resolve } from 'path';
3
3
  import { getApiToken, getApiUrl, getParallelId } from './environment-config.js';
4
4
  import { validateVizzlyConfigWithDefaults } from './config-schema.js';
5
5
  import { getAccessToken, getProjectMapping } from './global-config.js';
6
- const DEFAULT_CONFIG = {
6
+ import * as output from './output.js';
7
+ let DEFAULT_CONFIG = {
7
8
  // API Configuration
8
9
  apiKey: undefined,
9
10
  // Will be set from env, global config, or CLI overrides
@@ -37,8 +38,8 @@ const DEFAULT_CONFIG = {
37
38
  };
38
39
  export async function loadConfig(configPath = null, cliOverrides = {}) {
39
40
  // 1. Load from config file using cosmiconfig
40
- const explorer = cosmiconfigSync('vizzly');
41
- const result = configPath ? explorer.load(configPath) : explorer.search();
41
+ let explorer = cosmiconfigSync('vizzly');
42
+ let result = configPath ? explorer.load(configPath) : explorer.search();
42
43
  let fileConfig = {};
43
44
  if (result && result.config) {
44
45
  // Handle ESM default export (cosmiconfig wraps it in { default: {...} })
@@ -46,10 +47,10 @@ export async function loadConfig(configPath = null, cliOverrides = {}) {
46
47
  }
47
48
 
48
49
  // 2. Validate config file using Zod schema
49
- const validatedFileConfig = validateVizzlyConfigWithDefaults(fileConfig);
50
+ let validatedFileConfig = validateVizzlyConfigWithDefaults(fileConfig);
50
51
 
51
52
  // Create a proper clone of the default config to avoid shared object references
52
- const config = {
53
+ let config = {
53
54
  ...DEFAULT_CONFIG,
54
55
  server: {
55
56
  ...DEFAULT_CONFIG.server
@@ -74,11 +75,8 @@ export async function loadConfig(configPath = null, cliOverrides = {}) {
74
75
 
75
76
  // 3. Check project mapping for current directory (if no CLI flag)
76
77
  if (!cliOverrides.token) {
77
- const currentDir = process.cwd();
78
- if (process.env.DEBUG_CONFIG) {
79
- console.log('[CONFIG] Looking up project mapping for:', currentDir);
80
- }
81
- const projectMapping = await getProjectMapping(currentDir);
78
+ let currentDir = process.cwd();
79
+ let projectMapping = await getProjectMapping(currentDir);
82
80
  if (projectMapping && projectMapping.token) {
83
81
  // Handle both string tokens and token objects (backward compatibility)
84
82
  let token;
@@ -93,59 +91,37 @@ export async function loadConfig(configPath = null, cliOverrides = {}) {
93
91
  config.apiKey = token;
94
92
  config.projectSlug = projectMapping.projectSlug;
95
93
  config.organizationSlug = projectMapping.organizationSlug;
96
-
97
- // Debug logging
98
- if (process.env.DEBUG_CONFIG) {
99
- console.log('[CONFIG] Found project mapping:', {
100
- dir: currentDir,
101
- projectSlug: projectMapping.projectSlug,
102
- hasToken: !!projectMapping.token,
103
- tokenType: typeof projectMapping.token,
104
- tokenPrefix: token ? token.substring(0, 8) + '***' : 'none'
105
- });
106
- console.log('[CONFIG] Set config.apiKey to:', config.apiKey ? config.apiKey.substring(0, 8) + '***' : 'NONE');
107
- }
108
- } else if (process.env.DEBUG_CONFIG) {
109
- console.log('[CONFIG] No project mapping found for:', currentDir);
94
+ output.debug('Using project mapping', {
95
+ project: projectMapping.projectSlug,
96
+ org: projectMapping.organizationSlug
97
+ });
110
98
  }
111
99
  }
112
100
 
113
101
  // 3.5. Check global config for user access token (if no CLI flag)
114
102
  if (!config.apiKey && !cliOverrides.token) {
115
- const globalToken = await getAccessToken();
103
+ let globalToken = await getAccessToken();
116
104
  if (globalToken) {
117
105
  config.apiKey = globalToken;
118
106
  }
119
107
  }
120
108
 
121
109
  // 4. Override with environment variables (higher priority than fallbacks)
122
- const envApiKey = getApiToken();
123
- const envApiUrl = getApiUrl();
124
- const envParallelId = getParallelId();
125
- if (process.env.DEBUG_CONFIG) {
126
- console.log('[CONFIG] Step 4 - env vars:', JSON.stringify({
127
- hasEnvApiKey: !!envApiKey,
128
- envApiKeyPrefix: envApiKey ? envApiKey.substring(0, 8) + '***' : 'none',
129
- configApiKeyBefore: config.apiKey ? config.apiKey.substring(0, 8) + '***' : 'NONE'
130
- }));
110
+ let envApiKey = getApiToken();
111
+ let envApiUrl = getApiUrl();
112
+ let envParallelId = getParallelId();
113
+ if (envApiKey) {
114
+ config.apiKey = envApiKey;
115
+ output.debug('Using API token from environment');
131
116
  }
132
- if (envApiKey) config.apiKey = envApiKey;
133
117
  if (envApiUrl !== 'https://app.vizzly.dev') config.apiUrl = envApiUrl;
134
118
  if (envParallelId) config.parallelId = envParallelId;
135
119
 
136
120
  // 5. Apply CLI overrides (highest priority)
137
- if (process.env.DEBUG_CONFIG) {
138
- console.log('[CONFIG] Step 5 - before CLI overrides:', {
139
- configApiKey: config.apiKey ? config.apiKey.substring(0, 8) + '***' : 'NONE',
140
- cliToken: cliOverrides.token ? cliOverrides.token.substring(0, 8) + '***' : 'none'
141
- });
121
+ if (cliOverrides.token) {
122
+ output.debug('Using API token from --token flag');
142
123
  }
143
124
  applyCLIOverrides(config, cliOverrides);
144
- if (process.env.DEBUG_CONFIG) {
145
- console.log('[CONFIG] Step 6 - after CLI overrides:', {
146
- configApiKey: config.apiKey ? config.apiKey.substring(0, 8) + '***' : 'NONE'
147
- });
148
- }
149
125
  return config;
150
126
  }
151
127
 
@@ -191,7 +167,7 @@ function applyCLIOverrides(config, cliOverrides = {}) {
191
167
  if (cliOverrides.allowNoToken !== undefined) config.allowNoToken = cliOverrides.allowNoToken;
192
168
  }
193
169
  function mergeConfig(target, source) {
194
- for (const key in source) {
170
+ for (let key in source) {
195
171
  if (source[key] && typeof source[key] === 'object' && !Array.isArray(source[key])) {
196
172
  if (!target[key]) target[key] = {};
197
173
  mergeConfig(target[key], source[key]);
@@ -201,7 +177,7 @@ function mergeConfig(target, source) {
201
177
  }
202
178
  }
203
179
  export function getScreenshotPaths(config) {
204
- const screenshotsDir = config.upload?.screenshotsDir || './screenshots';
205
- const paths = Array.isArray(screenshotsDir) ? screenshotsDir : [screenshotsDir];
180
+ let screenshotsDir = config.upload?.screenshotsDir || './screenshots';
181
+ let paths = Array.isArray(screenshotsDir) ? screenshotsDir : [screenshotsDir];
206
182
  return paths.map(p => resolve(process.cwd(), p));
207
183
  }
@@ -7,6 +7,7 @@ import { homedir } from 'os';
7
7
  import { join, dirname, parse } from 'path';
8
8
  import { readFile, writeFile, mkdir, chmod } from 'fs/promises';
9
9
  import { existsSync } from 'fs';
10
+ import * as output from './output.js';
10
11
 
11
12
  /**
12
13
  * Get the path to the global Vizzly directory
@@ -57,7 +58,7 @@ export async function loadGlobalConfig() {
57
58
  }
58
59
 
59
60
  // Log warning about corrupted config but don't crash
60
- console.warn('Warning: Global config file is corrupted, ignoring');
61
+ output.warn('Global config file is corrupted, ignoring');
61
62
  return {};
62
63
  }
63
64
  }
@@ -176,9 +177,6 @@ export async function getAccessToken() {
176
177
  export async function getProjectMapping(directoryPath) {
177
178
  let config = await loadGlobalConfig();
178
179
  if (!config.projects) {
179
- if (process.env.DEBUG_CONFIG) {
180
- console.log('[MAPPING] No projects in global config');
181
- }
182
180
  return null;
183
181
  }
184
182
 
@@ -187,18 +185,8 @@ export async function getProjectMapping(directoryPath) {
187
185
  let {
188
186
  root
189
187
  } = parse(currentPath);
190
- if (process.env.DEBUG_CONFIG) {
191
- console.log('[MAPPING] Starting lookup from:', currentPath);
192
- console.log('[MAPPING] Available mappings:', Object.keys(config.projects));
193
- }
194
188
  while (currentPath !== root) {
195
- if (process.env.DEBUG_CONFIG) {
196
- console.log('[MAPPING] Checking:', currentPath);
197
- }
198
189
  if (config.projects[currentPath]) {
199
- if (process.env.DEBUG_CONFIG) {
200
- console.log('[MAPPING] Found match at:', currentPath);
201
- }
202
190
  return config.projects[currentPath];
203
191
  }
204
192
 
@@ -210,9 +198,6 @@ export async function getProjectMapping(directoryPath) {
210
198
  }
211
199
  currentPath = parentPath;
212
200
  }
213
- if (process.env.DEBUG_CONFIG) {
214
- console.log('[MAPPING] No mapping found');
215
- }
216
201
  return null;
217
202
  }
218
203