Skip to content

Conversation

@Robdel12
Copy link
Contributor

Summary

Adds vizzly preview <path> command to upload static files as a preview attached to a Vizzly build. Enables teams to share live previews of their built applications alongside visual test results.

  • New vizzly preview command - Uploads static files (dist/, build/, etc.) to preview hosting
  • Session tracking - Build context flows between commands via .vizzly/session.json
  • GitHub Actions integration - Auto-writes VIZZLY_BUILD_ID to $GITHUB_ENV for cross-step use
  • Preview URL in status - vizzly status now shows preview URL when available
  • Zero new dependencies - Uses system zip command (macOS/Linux) or PowerShell (Windows)

Usage

Local development:

vizzly run "npm test"    # Creates build, writes session
npm run build
vizzly preview ./dist    # Reads session automatically

CI (same job):

vizzly run "npm test"    # Sets VIZZLY_BUILD_ID in $GITHUB_ENV
npm run build
vizzly preview ./dist    # Reads from env

CI (parallel shards):

# Shards
vizzly run "npm test --shard=$SHARD" --parallel-id run-$RUN_ID

# Finalize + preview
vizzly finalize run-$RUN_ID
npm run build
vizzly preview ./dist

Test plan

  • Unit tests for session module (read/write/expiration/branch detection)
  • Unit tests for preview command (validation, build ID resolution, output modes)
  • Unit tests for API endpoints (uploadPreviewZip, getPreviewInfo)
  • All 1790 tests pass
  • Manual test: vizzly preview ./dist with session file
  • Manual test: vizzly preview ./dist --build <id> explicit mode
  • Manual test: Verify $GITHUB_ENV writing in GHA

Add `vizzly preview <path>` command to upload static files as a preview
attached to a Vizzly build. The preview URL is served via Cloudflare Worker
at `{buildId}.vizzly.xyz`.

Key features:
- Session file (.vizzly/session.json) tracks build context between commands
- Auto-writes to $GITHUB_ENV for cross-step persistence in GitHub Actions
- Reads build ID from session, env var, or explicit --build flag
- Uses system zip command (no new dependencies)
- Shows preview URL in `vizzly status` output

Commands affected:
- `vizzly preview <path>` - new command
- `vizzly run` - writes session after build creation
- `vizzly upload` - writes session after build creation
- `vizzly finalize` - writes session after parallel build finalized
- `vizzly status` - shows preview URL if one exists

Workflow:
  vizzly run "npm test"    # Creates build, writes session
  npm run build
  vizzly preview ./dist    # Reads session, uploads preview
@claude
Copy link

claude bot commented Jan 14, 2026

PR Review: Preview Command for Static Site Hosting

Completed thorough review. Overall excellent work with clean architecture and comprehensive testing.

✅ Strengths

  • Session management well-designed (env var → session file priority)
  • Dependency injection for testability
  • Zero new dependencies (clever use of system zip)
  • Cross-platform support (PowerShell fallback on Windows)
  • GitHub Actions integration via GITHUB_ENV/GITHUB_OUTPUT
  • Comprehensive JSDoc and error handling
  • 1790 tests passing

🔧 HIGH PRIORITY Issues

1. Command Injection Vulnerability ⚠️

Location: src/commands/preview.js:78-91

createZipWithSystem is vulnerable to command injection. Paths are not sanitized before being used in shell commands.

Risk: Malicious path like ./dist"; rm -rf /; echo " could execute arbitrary commands.

Fix: Validate paths for shell metacharacters or use pure JS zip library instead.

2. Path Traversal Risk ⚠️

Location: src/commands/preview.js:99-134

countFiles follows symlinks without validation, could access files outside intended directory or cause infinite loops.

Fix: Check for symlinks and ensure paths stay within base directory.

3. Race Condition in Temp Cleanup ⚠️

Location: src/commands/preview.js:308

Temp file names use only Date.now() (collision risk), cleanup errors swallowed.

Fix: Add randomBytes for unique names, use try/finally for cleanup.

🔧 MEDIUM PRIORITY Issues

  1. Missing input validation - No path traversal checks, build ID format validation
  2. Missing size limits - Should validate total size before upload
  3. Session file permissions - Should use mode 0o600 instead of default 644
  4. Error handling in status command - getPreviewInfo call could crash command

🔒 Security Summary

Issue Severity
Command injection HIGH ⚠️
Path traversal HIGH ⚠️
Temp file race condition MEDIUM
Missing validation MEDIUM

✅ Recommendation

Excellent architecture and implementation! Please address HIGH severity security issues before merging:

  1. Fix command injection in ZIP creation
  2. Add path traversal protection
  3. Improve temp file handling
  4. Add size limits
  5. Complete manual testing checklist

Happy to help implement fixes. The session management pattern is particularly well-designed!

- Add path validation (isPathSafe) to prevent command injection
- Skip symlinks in countFiles to prevent path traversal
- Verify subdirectories stay within base directory using realpath
- Add randomness to temp file names (timestamp + randomBytes)
- Set session file permissions to 0o600 (owner read/write only)
- Fix lint errors (import order, template literals, unused vars)
@Robdel12 Robdel12 merged commit 83918d1 into main Jan 14, 2026
20 of 22 checks passed
@Robdel12 Robdel12 deleted the feature/preview-command branch January 14, 2026 07:17
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.

2 participants