@vizzly-testing/cli 0.20.0 → 0.20.1-beta.1

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 (84) hide show
  1. package/dist/api/client.js +134 -0
  2. package/dist/api/core.js +341 -0
  3. package/dist/api/endpoints.js +314 -0
  4. package/dist/api/index.js +19 -0
  5. package/dist/auth/client.js +91 -0
  6. package/dist/auth/core.js +176 -0
  7. package/dist/auth/index.js +30 -0
  8. package/dist/auth/operations.js +148 -0
  9. package/dist/cli.js +178 -3
  10. package/dist/client/index.js +144 -77
  11. package/dist/commands/doctor.js +121 -36
  12. package/dist/commands/finalize.js +49 -18
  13. package/dist/commands/init.js +13 -18
  14. package/dist/commands/login.js +49 -55
  15. package/dist/commands/logout.js +17 -9
  16. package/dist/commands/project.js +100 -71
  17. package/dist/commands/run.js +189 -95
  18. package/dist/commands/status.js +101 -66
  19. package/dist/commands/tdd-daemon.js +61 -32
  20. package/dist/commands/tdd.js +104 -98
  21. package/dist/commands/upload.js +78 -34
  22. package/dist/commands/whoami.js +44 -42
  23. package/dist/config/core.js +438 -0
  24. package/dist/config/index.js +13 -0
  25. package/dist/config/operations.js +327 -0
  26. package/dist/index.js +1 -1
  27. package/dist/project/core.js +295 -0
  28. package/dist/project/index.js +13 -0
  29. package/dist/project/operations.js +393 -0
  30. package/dist/reporter/reporter-bundle.css +1 -1
  31. package/dist/reporter/reporter-bundle.iife.js +16 -16
  32. package/dist/screenshot-server/core.js +157 -0
  33. package/dist/screenshot-server/index.js +11 -0
  34. package/dist/screenshot-server/operations.js +183 -0
  35. package/dist/sdk/index.js +3 -2
  36. package/dist/server/handlers/api-handler.js +14 -5
  37. package/dist/server/handlers/tdd-handler.js +191 -53
  38. package/dist/server/http-server.js +9 -3
  39. package/dist/server/routers/baseline.js +58 -0
  40. package/dist/server/routers/dashboard.js +10 -6
  41. package/dist/server/routers/screenshot.js +32 -0
  42. package/dist/server-manager/core.js +186 -0
  43. package/dist/server-manager/index.js +81 -0
  44. package/dist/server-manager/operations.js +209 -0
  45. package/dist/services/build-manager.js +2 -69
  46. package/dist/services/index.js +21 -48
  47. package/dist/services/screenshot-server.js +40 -74
  48. package/dist/services/server-manager.js +45 -80
  49. package/dist/services/test-runner.js +90 -250
  50. package/dist/services/uploader.js +56 -358
  51. package/dist/tdd/core/hotspot-coverage.js +112 -0
  52. package/dist/tdd/core/signature.js +101 -0
  53. package/dist/tdd/index.js +19 -0
  54. package/dist/tdd/metadata/baseline-metadata.js +103 -0
  55. package/dist/tdd/metadata/hotspot-metadata.js +93 -0
  56. package/dist/tdd/services/baseline-downloader.js +151 -0
  57. package/dist/tdd/services/baseline-manager.js +166 -0
  58. package/dist/tdd/services/comparison-service.js +230 -0
  59. package/dist/tdd/services/hotspot-service.js +71 -0
  60. package/dist/tdd/services/result-service.js +123 -0
  61. package/dist/tdd/tdd-service.js +1145 -0
  62. package/dist/test-runner/core.js +255 -0
  63. package/dist/test-runner/index.js +13 -0
  64. package/dist/test-runner/operations.js +483 -0
  65. package/dist/types/client.d.ts +25 -2
  66. package/dist/uploader/core.js +396 -0
  67. package/dist/uploader/index.js +11 -0
  68. package/dist/uploader/operations.js +412 -0
  69. package/dist/utils/colors.js +187 -39
  70. package/dist/utils/config-loader.js +3 -6
  71. package/dist/utils/context.js +228 -0
  72. package/dist/utils/output.js +449 -14
  73. package/docs/api-reference.md +173 -8
  74. package/docs/tui-elements.md +560 -0
  75. package/package.json +13 -13
  76. package/dist/services/api-service.js +0 -412
  77. package/dist/services/auth-service.js +0 -226
  78. package/dist/services/config-service.js +0 -369
  79. package/dist/services/html-report-generator.js +0 -455
  80. package/dist/services/project-service.js +0 -326
  81. package/dist/services/report-generator/report.css +0 -411
  82. package/dist/services/report-generator/viewer.js +0 -102
  83. package/dist/services/static-report-generator.js +0 -207
  84. package/dist/services/tdd-service.js +0 -1437
@@ -0,0 +1,228 @@
1
+ /**
2
+ * Dynamic context detection for CLI commands
3
+ *
4
+ * Detects the current state of Vizzly in the working directory:
5
+ * - TDD server status
6
+ * - Project configuration
7
+ * - Authentication status
8
+ * - Baseline counts
9
+ */
10
+
11
+ import { existsSync, readFileSync } from 'node:fs';
12
+ import { homedir } from 'node:os';
13
+ import { dirname, join } from 'node:path';
14
+
15
+ /**
16
+ * Get dynamic context about the current Vizzly state
17
+ * Returns an array of context items with type, label, and value
18
+ *
19
+ * @returns {Array<{type: 'success'|'warning'|'info', label: string, value: string}>}
20
+ */
21
+ export function getContext() {
22
+ let items = [];
23
+ try {
24
+ let cwd = process.cwd();
25
+ let globalConfigPath = join(process.env.VIZZLY_HOME || join(homedir(), '.vizzly'), 'config.json');
26
+
27
+ // Load global config once
28
+ let globalConfig = {};
29
+ try {
30
+ if (existsSync(globalConfigPath)) {
31
+ globalConfig = JSON.parse(readFileSync(globalConfigPath, 'utf8'));
32
+ }
33
+ } catch {
34
+ // Ignore
35
+ }
36
+
37
+ // Check for vizzly.config.js (project config)
38
+ let hasProjectConfig = existsSync(join(cwd, 'vizzly.config.js'));
39
+
40
+ // Check for .vizzly directory (TDD baselines)
41
+ let baselineCount = 0;
42
+ try {
43
+ let metaPath = join(cwd, '.vizzly', 'baselines', 'metadata.json');
44
+ if (existsSync(metaPath)) {
45
+ let meta = JSON.parse(readFileSync(metaPath, 'utf8'));
46
+ baselineCount = meta.screenshots?.length || 0;
47
+ }
48
+ } catch {
49
+ // Ignore
50
+ }
51
+
52
+ // Check for TDD server running
53
+ let serverRunning = false;
54
+ let serverPort = null;
55
+ try {
56
+ let serverFile = join(cwd, '.vizzly', 'server.json');
57
+ if (existsSync(serverFile)) {
58
+ let serverInfo = JSON.parse(readFileSync(serverFile, 'utf8'));
59
+ serverPort = serverInfo.port;
60
+ serverRunning = true;
61
+ }
62
+ } catch {
63
+ // Ignore
64
+ }
65
+
66
+ // Check for project mapping (from vizzly project:select)
67
+ // Traverse up to find project config, with bounds check for Windows compatibility
68
+ let projectMapping = null;
69
+ let checkPath = cwd;
70
+ let prevPath = null;
71
+ while (checkPath && checkPath !== prevPath) {
72
+ if (globalConfig.projects?.[checkPath]) {
73
+ projectMapping = globalConfig.projects[checkPath];
74
+ break;
75
+ }
76
+ prevPath = checkPath;
77
+ checkPath = dirname(checkPath);
78
+ }
79
+
80
+ // Check for OAuth login (from vizzly login)
81
+ let isLoggedIn = !!globalConfig.auth?.accessToken;
82
+ let userName = globalConfig.auth?.user?.name || globalConfig.auth?.user?.email;
83
+
84
+ // Check for env token
85
+ let hasEnvToken = !!process.env.VIZZLY_TOKEN;
86
+
87
+ // Build context items - prioritize most useful info
88
+ if (serverRunning) {
89
+ items.push({
90
+ type: 'success',
91
+ label: 'TDD Server',
92
+ value: `running on :${serverPort}`
93
+ });
94
+ }
95
+ if (projectMapping) {
96
+ items.push({
97
+ type: 'success',
98
+ label: 'Project',
99
+ value: `${projectMapping.projectName} (${projectMapping.organizationSlug})`
100
+ });
101
+ } else if (isLoggedIn && userName) {
102
+ items.push({
103
+ type: 'success',
104
+ label: 'Logged in',
105
+ value: userName
106
+ });
107
+ } else if (hasEnvToken) {
108
+ items.push({
109
+ type: 'success',
110
+ label: 'API Token',
111
+ value: 'via VIZZLY_TOKEN'
112
+ });
113
+ } else {
114
+ items.push({
115
+ type: 'info',
116
+ label: 'Not connected',
117
+ value: 'run vizzly login or project:select'
118
+ });
119
+ }
120
+ if (baselineCount > 0) {
121
+ items.push({
122
+ type: 'success',
123
+ label: 'Baselines',
124
+ value: `${baselineCount} screenshots`
125
+ });
126
+ }
127
+ if (!hasProjectConfig && !serverRunning && baselineCount === 0) {
128
+ // Only show "no config" hint if there's nothing else useful
129
+ items.push({
130
+ type: 'info',
131
+ label: 'Get started',
132
+ value: 'run vizzly init'
133
+ });
134
+ }
135
+ } catch {
136
+ // If anything fails, just return empty - context is optional
137
+ }
138
+ return items;
139
+ }
140
+
141
+ /**
142
+ * Get detailed context with raw values (for doctor command)
143
+ * Returns more detailed information suitable for diagnostics
144
+ *
145
+ * @returns {Object} Detailed context object
146
+ */
147
+ export function getDetailedContext() {
148
+ let cwd = process.cwd();
149
+ let globalConfigPath = join(process.env.VIZZLY_HOME || join(homedir(), '.vizzly'), 'config.json');
150
+ let context = {
151
+ tddServer: {
152
+ running: false,
153
+ port: null
154
+ },
155
+ project: {
156
+ hasConfig: false,
157
+ mapping: null
158
+ },
159
+ auth: {
160
+ loggedIn: false,
161
+ userName: null,
162
+ hasEnvToken: false
163
+ },
164
+ baselines: {
165
+ count: 0,
166
+ path: null
167
+ }
168
+ };
169
+ try {
170
+ // Load global config
171
+ let globalConfig = {};
172
+ try {
173
+ if (existsSync(globalConfigPath)) {
174
+ globalConfig = JSON.parse(readFileSync(globalConfigPath, 'utf8'));
175
+ }
176
+ } catch {
177
+ // Ignore
178
+ }
179
+
180
+ // Check for vizzly.config.js
181
+ context.project.hasConfig = existsSync(join(cwd, 'vizzly.config.js'));
182
+
183
+ // Check for baselines
184
+ try {
185
+ let metaPath = join(cwd, '.vizzly', 'baselines', 'metadata.json');
186
+ if (existsSync(metaPath)) {
187
+ let meta = JSON.parse(readFileSync(metaPath, 'utf8'));
188
+ context.baselines.count = meta.screenshots?.length || 0;
189
+ context.baselines.path = join(cwd, '.vizzly', 'baselines');
190
+ }
191
+ } catch {
192
+ // Ignore
193
+ }
194
+
195
+ // Check for TDD server
196
+ try {
197
+ let serverFile = join(cwd, '.vizzly', 'server.json');
198
+ if (existsSync(serverFile)) {
199
+ let serverInfo = JSON.parse(readFileSync(serverFile, 'utf8'));
200
+ context.tddServer.running = true;
201
+ context.tddServer.port = serverInfo.port;
202
+ }
203
+ } catch {
204
+ // Ignore
205
+ }
206
+
207
+ // Check for project mapping
208
+ // Traverse up to find project config, with bounds check for Windows compatibility
209
+ let checkPath = cwd;
210
+ let prevPath = null;
211
+ while (checkPath && checkPath !== prevPath) {
212
+ if (globalConfig.projects?.[checkPath]) {
213
+ context.project.mapping = globalConfig.projects[checkPath];
214
+ break;
215
+ }
216
+ prevPath = checkPath;
217
+ checkPath = dirname(checkPath);
218
+ }
219
+
220
+ // Check auth status
221
+ context.auth.loggedIn = !!globalConfig.auth?.accessToken;
222
+ context.auth.userName = globalConfig.auth?.user?.name || globalConfig.auth?.user?.email;
223
+ context.auth.hasEnvToken = !!process.env.VIZZLY_TOKEN;
224
+ } catch {
225
+ // If anything fails, return defaults
226
+ }
227
+ return context;
228
+ }