Skip to content

✨ Add CLI visual context workflows#247

Merged
Robdel12 merged 4 commits into
mainfrom
rd/cli-visual-context
Apr 30, 2026
Merged

✨ Add CLI visual context workflows#247
Robdel12 merged 4 commits into
mainfrom
rd/cli-visual-context

Conversation

@Robdel12
Copy link
Copy Markdown
Contributor

Summary

  • add read-only vizzly context commands for build, comparison, screenshot, similar, and review queue bundles
  • support local workspace context from .vizzly/ alongside cloud context resolution
  • document the new context surface in the CLI README and JSON output reference

Verification

  • node --test tests/api/endpoints.test.js tests/commands/*.test.js
  • npm run lint

Add read-only context commands for cloud and local workspace use, document the new JSON and agent workflows, and keep the surface aligned with the context API.
@claude
Copy link
Copy Markdown

claude Bot commented Apr 30, 2026

PR Review: ✨ Add CLI visual context workflows

Overall this is a well-structured addition. The dependency-injection pattern for testability (deps = {} with injectable defaults) matches the project's existing style, the --json flag pre-parsing refactor is a clean improvement, and the local/cloud provider split via resolveContextSource is a solid abstraction. The test coverage for the happy paths and the CLI integration tests are solid. A few things worth addressing before merge:


🐛 Bugs

1. Hardcoded macOS path in resolveAssetReference (src/context/local-workspace-provider.js line ~1597)

if (/^https?:\/\//.test(assetPath) || assetPath.startsWith('/Users/')) {
  return assetPath;
}

The /Users/ check is macOS-specific. On Linux (CI) and Windows this will fall through to the /images/ branch or return the path as-is, producing broken asset URLs. The intent seems to be "this is already an absolute path" — use path.isAbsolute(assetPath) instead:

import { isAbsolute } from 'node:path';

if (/^https?:\/\//.test(assetPath) || isAbsolute(assetPath)) {
  return assetPath;
}

2. Schema mismatch in displayFingerprintContext (src/commands/context.js line ~1132)

output.print(`  ${colors.bold(context.fingerprint_hash)}`);

The JSON output doc (and the getSimilarFingerprintContext response shape) nests this as context.fingerprint.hash, not a top-level context.fingerprint_hash. This will render as undefined for cloud responses. Verify the actual API response shape and align the accessor.


⚡ Performance

3. loadSnapshot() called up to 3× per request (src/context/local-workspace-provider.js)

canHandle() calls isAvailable() which calls loadSnapshot(), and then canHandle() also calls loadSnapshot() itself. When resolveContextSource calls localProvider.isAvailable() followed by localProvider.canHandle(), the snapshot (multiple JSON file reads) is loaded three times before a single API call is made.

Simplest fix — memoize within a request scope by caching the snapshot inside the closure on first load, or accept a pre-loaded snapshot as a parameter in canHandle:

function isAvailable(snapshot) {
  return Boolean(
    snapshot.serverInfo || snapshot.session || ...
  );
}

Similarly, shouldExplainLocalSimilarityGap in context.js calls localProvider.isAvailable() again after the source has already been resolved — a fourth disk read.


🧹 Code quality

4. Double output configuration (src/commands/context.js, each command handler)

Each exported command (e.g., contextBuildCommand) calls output.configure() at the top. But loadContextRuntime also calls output.error() and output.cleanup() before the second configure in the caller ever runs — because the configure happens before the await loadContextRuntime(...) call but the load itself can call output methods synchronously for auth errors. The cli.js change also adds a second output.configure() call after normalization. Trace a failed-auth path end-to-end to confirm output state is consistent.

5. limit default in getReviewQueueContext (src/context/local-workspace-provider.js line ~2049)

let limit = query.limit || unresolved.length || 10;

If there are no limits set and 500 unresolved comparisons, this returns all 500. The cloud endpoint presumably pages; local should too. Consider capping at a sensible default (e.g., 50) to keep the output predictable for agents.

6. --source description inconsistency

buildSourceErrorMessage() says "auto, cloud, or local" but the Commander option description says "auto, cloud, or local workspace". Pick one.


🧪 Test coverage gaps

  • src/context/provider-resolver.js has no unit tests at all. The autolocalcloud resolution logic (especially the canHandle branch and the requestedSource === 'local' error path) should be directly tested rather than relying on CLI integration tests to cover it indirectly.
  • displayBuildContext / displayComparisonContext / etc. — the human-readable output paths aren't tested. At minimum, a smoke test that these don't throw on a valid fixture would catch the fingerprint_hash schema mismatch above before it ships.
  • The shouldExplainLocalSimilarityGap path (auto + similar + local workspace available → throw local capability error instead of auth error) is complex and untested.

Minor nits

  • contextBuildCommand and siblings all have identical boilerplate for the output.configure + try/catch + spinner pattern. Could be a shared runContextCommand(fn) wrapper, though this is optional polish.
  • The review_summary stub in the local comparison context (total: 0, completed: 0, ...) diverges from what the display function reads (context.review.build_comments.length, context.review.screenshot_comments). Make sure the local provider shape exactly matches what displayComparisonContext expects.

The /Users/ path bug and the fingerprint schema mismatch are the two things I'd want confirmed/fixed before this lands. The performance issue is worth fixing too given this feature is explicitly targeting agent workflows where fast local reads matter.

Address the cross-platform local path check, fingerprint display mismatch, local snapshot caching, and add direct resolver/provider coverage for the context workflow.
Move report data normalization into shared CLI utils so the built context provider no longer depends on reporter source paths at runtime.
@vizzly-testing

This comment has been minimized.

Update the reporter report-data test to use the shared utility path so Node and visual CI jobs stop importing the removed reporter-local module.
@vizzly-testing
Copy link
Copy Markdown

vizzly-testing Bot commented Apr 30, 2026

Vizzly - Visual Test Results

CLI Reporter - Approved

19 comparisons, no changes detected.

View build

CLI TUI - Approved

5 comparisons approved.

Review changes


rd/cli-visual-context · 8edecf0e

@Robdel12 Robdel12 merged commit d8cd385 into main Apr 30, 2026
34 of 41 checks passed
@Robdel12 Robdel12 deleted the rd/cli-visual-context branch April 30, 2026 05:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant