Omniscio documentation
Browse all documentation
  1. Getting Started13
  2. Sessions & Agents115
  3. Inbox & Notifications59
  4. Projects & Tasks95
  5. Automation & Scheduling75
  6. Knowledge & Memory26
  7. AI Features60
  8. Integrations100
  9. Plugins & Marketplace33
  10. Cloud & Teams56
  11. Settings & Customization58
  12. Account & Billing28
  13. Troubleshooting84
  14. CLI & API Reference22
  15. Legal & Policies4
  16. Uncategorised22

PR Visual Evidence

Before/after screenshots and short screen recordings of a UI change, captured at the end of a coding-agent session and attached to your private session by default — and to the public GitHub PR only when the repo opts in a second time. Covers the per-repo switches, both capture paths, and the safety rules the platform enforces.

What it is

Shipped (2026-08-20) — on for everyone, but nothing happens until a repo opts in (per-repo, off by default). Phase 1 shipped before/after screenshots; Phase 2 adds a short before/after screen recording (video) of the changed flow (a capture may be screenshot-only, video-only, or both); Phase 3 adds a PURE-PLATFORM fast path that captures the before/after WITHOUT the agent driving the browser.

When a coding-agent session finishes a change that affects the UI, PR Visual Evidence captures a before/after screenshot of the changed screen — or a short before/after screen recording (video) of the changed flow — and attaches it where the change is reviewed: your private Omniscio session by default, and the public GitHub PR only when the repo explicitly opts into that a second time.

It's the automated version of what a careful engineer does by hand: show what the screen (or the flow) looked like before the change and after it, so a reviewer can see the visual diff at a glance. Screenshots suit a static change; a recording suits a flow / interaction / animation change.

Where to find it

Every install ships the feature, but nothing happens until a repository opts in. The switches are per repository, in that project's own settings under Edit Project → More options — the same place where you set the preview command and the separate opt-in for public PR posting.

How it behaves

The opt-in (the privacy model)

The feature ships on for everyone, but it does nothing until a repo opts in — and posting to a public PR needs a separate switch. In Edit Project → More options, three fields control it:

  • Attach before/after PR screenshots — the per-repo opt-in (off by default). Off ⇒ the feature is inert for that repo, and no browser-capture tools are loaded for its sessions.
  • Preview command — how to launch that repo's dev server so the screen can be captured (e.g. npm run dev). Leave blank to skip the "before" shot.
  • Also post to the public GitHub PR — the SECOND opt-in (off by default). Off ⇒ the before/after stays only in your private session; on ⇒ it is ALSO posted as one comment on the branch's open PR.

So the default for an opted-in repo is private: the screenshots land in the session, never on a public URL, until the repo owner deliberately turns on public posting.

How it works

  • The bundled pr-visual-evidence skill runs at the end of a UI-affecting session. It checks the preconditions (feature + repo opt-in, a web UI, an actual UI change, synthetic/test data only), then drives Omniscio's embedded browser to screenshot the changed screen.
  • The "before" is real — the platform resolves the change's merge-base, checks out the pre-change version in a throwaway worktree, launches its dev server with the repo's preview command, screenshots it, then tears the throwaway down (no leaked worktree or process).
  • The agent confirms the two shots actually differ (else it skips — no misleading identical pair), and hands the paths to the platform, which attaches them privately and — only on the second opt-in — hosts the screenshots on GitHub user-attachments (an access-controlled github.com/user-attachments/… URL that follows repo membership — private repo → only repo viewers, never a public capability link) and posts one PR comment embedding both images. If that upload fails, the PR image is skipped (still saved privately) and it never falls back to a public link.
  • Video (Phase 2) — for a flow change the skill records the SAME short flow on each version: the platform records the active browser tab (frame snapshots → mp4 via the bundled ffmpeg, capped ~20s / ≤1280px), attaches the mp4 privately, and — on the second opt-in — hosts it on GitHub user-attachments (the same access-controlled seam as the screenshots; nothing here is ever on a public link) and adds a "▶ Watch the before/after recording" link to the same PR comment.
  • Best-effort throughout: a missing preview, a build failure, no PR for the branch, a missing ffmpeg, or any capture/record error just means the visual is skipped and logged — it NEVER blocks, delays, or fails the actual code change.

Pure-platform capture (the fast path — no agent driving the browser)

The skill now asks the platform to do the whole thing FIRST, via POST /pr-visual-evidence/auto-capture { sessionId }. For the common case — a web app whose home screen shows the change — the platform captures the before/after entirely server-side and the agent never touches the browser:

  • It confirms the change is UI-affecting (from the diff, including uncommitted edits), boots the pristine "before" preview (merge-base) and an "after" preview from the session's live worktree, waits for each to load, screenshots the home screen of both using the same offscreen browser engine the agent flow uses, confirms they differ, attaches the pair privately, and tears both previews down.
  • Private-only. Pure-platform capture NEVER posts to a public PR — it can't personally assert the screen shows synthetic data the way the agent flow does, so public posting stays on the agent path (gated on the repo's postToPublicPr opt-in).
  • Degrades to the agent. When the platform can't get a clean shot it returns a reason (no-ui-change, no-base-preview, no-worktree, preview-not-ready, not-web-ui, no-visual-change, capture-failed) and the skill falls back to the agent-driven flow above — the agent knows the login/seed/route the platform doesn't.
  • Safety. The "after" preview runs against the session's real worktree, so its teardown only stops the dev server — it NEVER removes the worktree (the session's uncommitted work is never touched).
  • Scope (proof-slice): the home route / only; Omniscio's own renderer is out (a plain browser tab can't load its Electron bridge). Diff→route inference for deeper screens is a later layer.

What the platform enforces (so the agent can't get it wrong)

  • Private-always, PR-post-only-on-opt-in. The publish path always attaches to the session first; it only posts to the PR when the repo's postToPublicPr is on AND a PR is known for the session — and the screenshots AND recordings it embeds host on GitHub user-attachments (access-controlled, never a public capability URL).
  • Ownership. The public PR is auto-detected from the session's own branch on the project's own origin repo (gh pr list --head <branch> --repo <origin>), and the repo is validated server-side — a session can never post to some other repo's PR.
  • Idempotent. A re-run for the same session finds its hidden marker in the PR's comments and skips the duplicate.
  • Synthetic data only. Capture runs against a running app, so the skill requires test/seed data and skips when it can't guarantee it — an "after" shot or clip could otherwise reach a public PR. A VIDEO records a whole flow, so EVERY screen in it must be synthetic, not just the last.
  • Video hosting respects GitHub's own caps. A clip hosts on the same access-controlled user-attachments URL as screenshots; a clip over GitHub's per-file plan cap (10 MB on free-plan repos, 100 MB on paid) or any failed upload is simply skipped from the PR comment while the private attachment still stands — never a public fallback. No new dependency — encoding reuses the bundled ffmpeg.

For agents

Turning it on (CLI)

The feature is shipped (on for everyone) — no global toggle to flip. Opt a repo in per-project:

  • PATCH /project/:id { "prVisualEvidence": true, "previewCommand": "npm run dev", "postToPublicPr": false } (or Edit Project → More options).

Where it lives

  • Feature gate + settings: src/shared/unreleased-features.ts (pr-visual-evidence, status: 'shipped'; settingKey/envVar retained as gate helpers) + the per-project prVisualEvidence / previewCommand / postToPublicPr fields (src/shared/types/project.ts, migration 20260819170759).
  • Backend service: src/main/services/pr-visual-evidence/ (provision-base.ts, publish.ts, record.ts — the video recorder, session-pr-gh.ts, auto-capture.ts (pure-platform orchestrator), capture.ts (browser-readiness + screenshot + perceptual differ), index.ts). CLI routes: POST /pr-visual-evidence/provision-base, /record/start, /record/stop, /publish, /auto-capture.
  • Capture engine: the embedded ai-browser (resolveAgentWebContents + screenshotPng for stills and the recorder's frames; runAiBrowserTool for the pure-platform path's offscreen WebContents.capturePage()), composed PER-REPO via isBrowserCaptureVisibleForProject (only opted-in repos' sessions; the route 404-gate stays global on isBrowserCaptureVisible, not un-retired for general use). Video encode reuses runFfmpeg; hosting of screenshots AND recordings goes through the one GitHub user-attachments uploader (github-attachment.ts). The pure-platform path drives the browser from main; the agent path drives it via MCP.
  • UI-change heuristic: src/shared/ui-affecting-diff.ts. Agent flow: .claude/skills/pr-visual-evidence/SKILL.md.
  • Full invariants + route contracts: .claude/memory/contracts/pr-visual-evidence-contract.md.

Related

pull-requests.md covers the PR lifecycle the comment above lands in. web-app-verification.md covers verifying a running web app from a session — the same browser machinery this capture path drives. And screenshot-snip-tool.md is the manual, in-app way to grab a screen when you want a picture by hand rather than an automatic before/after pair.

Last verified 2026-09-23