@vizzly-testing/cli 0.35.0 → 0.35.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.
@@ -1163,6 +1163,9 @@ export class TddService {
1163
1163
  let newComparisons = getNewComparisons(this.comparisons);
1164
1164
  let passedComparisons = this.comparisons.filter(c => c.status === 'passed' || c.status === 'baseline-created' || c.status === 'baseline-updated');
1165
1165
  let hasChanges = failedComparisons.length > 0 || newComparisons.length > 0;
1166
+ if (output.isJson?.()) {
1167
+ return results;
1168
+ }
1166
1169
 
1167
1170
  // Header with summary - use bear emoji as Vizzly mascot
1168
1171
  output.blank();
@@ -1239,9 +1242,10 @@ export class TddService {
1239
1242
  let serverFile = `${this.workingDir}/.vizzly/server.json`;
1240
1243
  let serverRunning = false;
1241
1244
  let serverPort = 47392;
1245
+ let serverInfo = {};
1242
1246
  try {
1243
1247
  if (existsSync(serverFile)) {
1244
- let serverInfo = JSON.parse(readFileSync(serverFile, 'utf8'));
1248
+ serverInfo = JSON.parse(readFileSync(serverFile, 'utf8'));
1245
1249
  if (serverInfo.port) {
1246
1250
  serverPort = serverInfo.port;
1247
1251
  serverRunning = true;
@@ -1250,7 +1254,7 @@ export class TddService {
1250
1254
  } catch {
1251
1255
  // Ignore errors reading server file
1252
1256
  }
1253
- if (serverRunning) {
1257
+ if (serverRunning && !serverInfo.buildId) {
1254
1258
  // Server is running - show the dashboard URL
1255
1259
  output.print(` ${textTertiary('→')} Review changes: ${infoColor(colors.underline(`http://localhost:${serverPort}`))}`);
1256
1260
  } else {
@@ -234,12 +234,14 @@ export function hasApiKey(config) {
234
234
  /**
235
235
  * Build spawn options for test command execution
236
236
  * @param {Object} env - Environment variables
237
+ * @param {Object} [options] - Spawn display options
238
+ * @param {boolean} [options.json] - Keep stdout reserved for CLI JSON output
237
239
  * @returns {Object} Spawn options
238
240
  */
239
- export function buildSpawnOptions(env) {
241
+ export function buildSpawnOptions(env, options = {}) {
240
242
  return {
241
243
  env,
242
- stdio: 'inherit',
244
+ stdio: options.json ? ['inherit', 'pipe', 'pipe'] : 'inherit',
243
245
  shell: true
244
246
  };
245
247
  }
@@ -188,6 +188,7 @@ export async function finalizeBuild({
188
188
  export function executeTestCommand({
189
189
  command,
190
190
  env,
191
+ json = false,
191
192
  deps
192
193
  }) {
193
194
  let {
@@ -195,8 +196,18 @@ export function executeTestCommand({
195
196
  createError
196
197
  } = deps;
197
198
  return new Promise((resolve, reject) => {
198
- let spawnOptions = buildSpawnOptions(env);
199
+ let spawnOptions = buildSpawnOptions(env, {
200
+ json
201
+ });
199
202
  let testProcess = spawn(command, spawnOptions);
203
+ if (json) {
204
+ testProcess.stdout?.on('data', data => {
205
+ process.stderr.write(data);
206
+ });
207
+ testProcess.stderr?.on('data', data => {
208
+ process.stderr.write(data);
209
+ });
210
+ }
200
211
  testProcess.on('error', error => {
201
212
  reject(createError(`Failed to run test command: ${error.message}`, 'TEST_COMMAND_FAILED'));
202
213
  });
@@ -271,6 +282,7 @@ export async function runTests({
271
282
  await executeTestCommand({
272
283
  command: testCommand,
273
284
  env,
285
+ json: runOptions.json,
274
286
  deps: {
275
287
  spawn,
276
288
  createError
@@ -341,6 +353,7 @@ export async function runTests({
341
353
  await executeTestCommand({
342
354
  command: testCommand,
343
355
  env,
356
+ json: runOptions.json,
344
357
  deps: {
345
358
  spawn,
346
359
  createError
@@ -409,7 +422,9 @@ export async function runTests({
409
422
 
410
423
  // Throw test error after cleanup
411
424
  if (testError) {
412
- output.error('Test run failed:', testError);
425
+ if (!runOptions.json) {
426
+ output.error('Test run failed:', testError);
427
+ }
413
428
  throw testError;
414
429
  }
415
430
  return buildRunResult({
@@ -82,6 +82,7 @@ export async function loadConfig(configPath = null, cliOverrides = {}) {
82
82
  config.userToken = userToken;
83
83
  output.debug('config', 'using user login for user-authenticated commands');
84
84
  }
85
+ config._configPath = result?.filepath || null;
85
86
  return config;
86
87
  }
87
88
 
@@ -232,6 +232,9 @@ export function getLogLevel() {
232
232
  export function isVerbose() {
233
233
  return config.logLevel === 'debug';
234
234
  }
235
+ export function isJson() {
236
+ return config.json;
237
+ }
235
238
 
236
239
  /**
237
240
  * Show command header with distinctive branding
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vizzly-testing/cli",
3
- "version": "0.35.0",
3
+ "version": "0.35.1",
4
4
  "description": "Visual regression testing from your terminal",
5
5
  "keywords": [
6
6
  "llm-context",
@@ -23,16 +23,24 @@ If a task names a screen, component, or screenshot, inspect that screenshot's hi
23
23
  vizzly context screenshot "<screenshot-name>" --source local --json
24
24
  ```
25
25
 
26
- When you make or verify UI changes, run the focused user workflow that owns the surface:
26
+ When you make or verify UI changes, use the local TDD server as the active feedback loop:
27
27
 
28
28
  ```bash
29
- vizzly tdd run "<test command>" --no-open
29
+ vizzly tdd start &
30
+ npm run test:e2e -- tests/e2e/path.spec.js
31
+ vizzly context build current --source local --agent --json
30
32
  ```
31
33
 
32
- Then inspect what changed:
34
+ The user may choose whether the TDD server runs in the foreground or background. Once it is
35
+ running, run tests normally from the repo. The SDK discovers `.vizzly/server.json`, posts
36
+ screenshots to the active TDD server, and refreshes `.vizzly/current`, `.vizzly/diffs`, report
37
+ data, and local context.
38
+
39
+ Use `vizzly tdd run` for true one-off runs where you want the CLI to own starting the visual
40
+ session and running the command:
33
41
 
34
42
  ```bash
35
- vizzly context build current --source local --agent --json
43
+ vizzly tdd run "<test command>" --no-open
36
44
  ```
37
45
 
38
46
  For specific evidence, drill in:
@@ -5,13 +5,19 @@ Use these commands to gather Vizzly evidence before making UI assumptions.
5
5
  ## Local TDD
6
6
 
7
7
  ```bash
8
- vizzly tdd start
8
+ vizzly tdd start --open
9
+ vizzly tdd status
10
+ vizzly tdd stop
9
11
  vizzly tdd run "<test command>" --no-open
10
12
  vizzly context build current --source local --agent
11
13
  vizzly context build current --source local --agent --json
12
14
  ```
13
15
 
14
- Local context reads `.vizzly` state and does not require cloud auth.
16
+ If `tdd start` prints a non-default port, pass that same port to
17
+ `tdd status --port <port>` and `tdd stop --port <port>`.
18
+
19
+ Local context reads `.vizzly` state and does not require cloud auth. After a
20
+ one-shot `tdd run`, prefer the printed `contextCommand` before editing UI.
15
21
 
16
22
  ## Cloud Builds
17
23
 
@@ -6,11 +6,13 @@ Use Vizzly locally for fast feedback and in CI for shared review.
6
6
 
7
7
  ```bash
8
8
  vizzly init
9
- vizzly tdd start
9
+ vizzly tdd start --open
10
10
  vizzly tdd run "<test command>" --no-open
11
11
  ```
12
12
 
13
13
  The local SDK discovers `.vizzly/server.json` and sends screenshots to the TDD server when it is running.
14
+ For one-off checks, `vizzly tdd run` writes local review data under `.vizzly/`
15
+ and prints a context command for follow-up inspection.
14
16
 
15
17
  ## Cloud Setup
16
18