Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions docs/json-output.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ vizzly run "pnpm test" --json
"data": {
"buildId": "abc123-def456",
"status": "completed",
"contextCommand": "vizzly context build abc123-def456 --agent",
"contextCommand": "vizzly context build abc123-def456 --agent --json",
"screenshotsCaptured": 15,
"executionTimeMs": 4821,
"git": {
Expand Down Expand Up @@ -106,7 +106,7 @@ With `--wait`, includes comparison results:
"identical": 12
},
"approvalStatus": "pending",
"contextCommand": "vizzly context build abc123-def456 --agent",
"contextCommand": "vizzly context build abc123-def456 --agent --json",
"exitCode": 1
}
}
Expand Down Expand Up @@ -147,7 +147,7 @@ vizzly tdd run "pnpm test" --json
"new": 0
},
"reportPath": ".vizzly/report/index.html",
"contextCommand": "vizzly context build current --source local --agent"
"contextCommand": "vizzly context build current --source local --agent --json"
}
}
```
Expand Down
22 changes: 18 additions & 4 deletions src/commands/run.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,20 @@ export async function resolveBuildDisplayUrl({
return undefined;
}

function buildContextCommand(buildId) {
return `vizzly context build ${buildId} --agent`;
/**
* Build the follow-up command for a cloud run.
*
* JSON consumers need a self-contained command that returns structured
* evidence when executed. Human output keeps the existing readable summary.
*
* @param {string} buildId - Cloud build ID to inspect.
* @param {Object} options - Command output options.
* @param {boolean} [options.structured=false] - Include machine-readable JSON.
* @returns {string} Executable build context command.
*/
function buildContextCommand(buildId, { structured = false } = {}) {
let jsonFlag = structured ? ' --json' : '';
return `vizzly context build ${buildId} --agent${jsonFlag}`;
}

/**
Expand Down Expand Up @@ -377,7 +389,7 @@ export async function runCommand(
message,
},
contextCommand: result.buildId
? buildContextCommand(result.buildId)
? buildContextCommand(result.buildId, { structured: true })
: null,
exitCode: 0,
};
Expand Down Expand Up @@ -516,7 +528,9 @@ export async function runCommand(
identical: buildResult.identicalComparisons || 0,
},
approvalStatus: buildResult.approvalStatus || 'pending',
contextCommand: buildContextCommand(result.buildId),
contextCommand: buildContextCommand(result.buildId, {
structured: true,
}),
exitCode,
};

Expand Down
17 changes: 14 additions & 3 deletions src/commands/tdd.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,19 @@ import {
} from '../utils/git.js';
import * as defaultOutput from '../utils/output.js';

function buildLocalContextCommand() {
return 'vizzly context build current --source local --agent';
/**
* Build the follow-up command for local TDD evidence.
*
* JSON consumers need a self-contained command that returns structured
* evidence when executed. Human output keeps the existing readable summary.
*
* @param {Object} options - Command output options.
* @param {boolean} [options.structured=false] - Include machine-readable JSON.
* @returns {string} Executable local context command.
*/
function buildLocalContextCommand({ structured = false } = {}) {
let jsonFlag = structured ? ' --json' : '';
return `vizzly context build current --source local --agent${jsonFlag}`;
}

/**
Expand Down Expand Up @@ -296,7 +307,7 @@ export async function tddCommand(
comparisons,
summary,
reportPath: runResult.reportPath || '.vizzly/report/index.html',
contextCommand: buildLocalContextCommand(),
contextCommand: buildLocalContextCommand({ structured: true }),
});
output.cleanup();
}
Expand Down
4 changes: 4 additions & 0 deletions tests/cli/tdd-lifecycle.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,10 @@ describe('cli/tdd lifecycle', () => {
assert.strictEqual(payload.status, 'data');
assert.strictEqual(payload.data.status, 'completed');
assert.strictEqual(payload.data.summary.total, 0);
assert.strictEqual(
payload.data.contextCommand,
'vizzly context build current --source local --agent --json'
);
});

it('keeps JSON TDD run failures parseable while forwarding child output to stderr', async () => {
Expand Down
4 changes: 4 additions & 0 deletions tests/commands/run-cli.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,10 @@ describe('commands/run CLI', () => {
assert.strictEqual(payload.data.status, 'completed');
assert.strictEqual(payload.data.buildId, 'build-123');
assert.strictEqual(payload.data.comparisons.total, 0);
assert.strictEqual(
payload.data.contextCommand,
'vizzly context build build-123 --agent --json'
);
assert.deepStrictEqual(
requests.map(request => `${request.method} ${request.url}`),
[
Expand Down
12 changes: 6 additions & 6 deletions tests/commands/run.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -302,13 +302,13 @@ describe('commands/run', () => {
assert.ok(output.calls.some(c => c.method === 'complete'));
// Now uses print for screenshot summary
assert.ok(output.calls.some(c => c.method === 'print'));
assert.ok(
output.calls.some(
c =>
c.method === 'print' &&
c.args[0].includes('vizzly context build build-123 --agent')
)
let contextCall = output.calls.find(
call =>
call.method === 'print' &&
call.args[0].includes('vizzly context build build-123 --agent')
);
assert.ok(contextCall);
assert.doesNotMatch(contextCall.args[0], /--json/);
});

it('handles test command failure with exit code', async () => {
Expand Down
16 changes: 8 additions & 8 deletions tests/commands/tdd.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -232,15 +232,15 @@ describe('commands/tdd', () => {

assert.strictEqual(result.success, true);
assert.strictEqual(result.exitCode, 0);
assert.ok(
output.calls.some(
c =>
c.method === 'print' &&
c.args[0].includes(
'vizzly context build current --source local --agent'
)
)
let contextCall = output.calls.find(
call =>
call.method === 'print' &&
call.args[0].includes(
'vizzly context build current --source local --agent'
)
);
assert.ok(contextCall);
assert.doesNotMatch(contextCall.args[0], /--json/);
});

it('handles test run with failed comparisons', async () => {
Expand Down