Skip to content

feat(desktop): add SnapShots window capture - #121

Merged
coreybain merged 5 commits into
mainfrom
agent/window-capture
Sep 9, 2026
Merged

feat(desktop): add SnapShots window capture#121
coreybain merged 5 commits into
mainfrom
agent/window-capture

Conversation

@coreybain

@coreybain coreybain commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator

Pathway users can now capture the window they are working in with a desktop shortcut and attach the image, app identity, window title, and available accessibility text to their draft. SnapShots are opt-in and run on the desktop client's computer, including when the conversation uses a remote environment.

This adapts T3 Code PR #8103, merge 299404a754f52c02c69634528d8856b3c93b378c, to Pathway's attachment contracts, V2 provider dispatch, environment-scoped drafts, and native Apple client. It includes macOS and Windows capture, Wayland compositor/portal backends, setup and permission recovery, configurable shortcuts, a command-palette action, and optional capture feedback. X11 remains unsupported.

Captures are saved before delivery and acknowledged only after the draft is persisted. Failed delivery can be retried or discarded. Pending captures belong to the signed-in account; account switches, sign-out, and renderer loss stop delivery and release native listeners. Accessibility work runs outside the renderer, with bounded depth and payloads. Provider context marks captured app text as untrusted, preserves the user's message, and covers every adapter through the common start/steer boundary.

Validation:

  • 423 focused desktop tests (23 Linux-only skips), 437 web tests, 91 contracts/artifact tests, and 73 server tests passed. Subsequent focused suites passed for the macOS window-selection fix (123 tests) and setup error guidance (53 tests).
  • Scoped desktop, web, contracts, server, and build-script typechecks and lint; production web and desktop bundles.
  • Native Apple app build and the simulator metadata decode/cache/resend regression. The test invocation excluded unchanged PathwayProjectIconTests.swift, whose existing optional-string errors prevent the full test target from compiling.
  • Windows and Linux OS capture have not been exercised on this Mac. The CI Rust job now includes both Linux capture helpers; local Rust compilation was unavailable.
  • Focused Convex fallback review: no Convex functions, subscriptions, or query fanout changed. No dedicated Convex performance skill was installed. The configured development cloud has an existing capability-validator mismatch; no cloud deployment was changed for this PR.

Manual verification: the isolated macOS app rendered the settings and setup flow, recognized Screen Recording and Accessibility grants, and recovered from a failed setup capture. That check exposed selection of a tiny same-process popup; capture now resolves Pathway's actual Electron window, with a regression test. The maintainer requested that further testing stop and will complete the hotkey, attachment, and metadata check. End-to-end capture and animation evidence are therefore still pending maintainer verification.

Rebased onto 5be1bbb0b (latest main at publication). The focused checks above ran before that clean rebase; no further checks were run after the maintainer requested a testing handoff.

Codex task: codex://threads/01a08406-d72e-7f93-9e9b-ccf4a37bcef4. GitHub displays this as a copyable URI; no approved HTTPS backlink bridge is configured.

Implemented with GPT-6 in the Codex harness, using parallel implementation and review agents.


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

@greptile-apps

greptile-apps Bot commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Too many files changed for review (212 files, 100 file limit).

Bypass the limit by tagging @greptile-apps to review.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 9, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-09T06:27:33.488202Z 678cc73 New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c32e3e3d78

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/desktop/src/snapShot/DesktopSnapShot.ts Outdated
Comment thread apps/desktop/src/snapShot/DesktopSnapShot.ts
Comment thread apps/web/src/components/desktop/SnapShotCoordinator.tsx Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e7c3f7e396

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/desktop/src/snapShot/DesktopSnapShot.ts Outdated
Comment thread apps/desktop/src/snapShot/DesktopSnapShot.ts Outdated
Comment thread apps/web/src/components/desktop/SnapShotCoordinator.tsx Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3a01ef7678

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/desktop/src/snapShot/GlobalShiftShortcutProcess.ts
Comment thread apps/desktop/src/snapShot/HyprlandSnapShot.ts Outdated
Comment thread apps/desktop/src/snapShot/DesktopSnapShot.ts
Comment thread apps/desktop/src/electron/ElectronWindow.ts
@coreybain
coreybain merged commit 157215f into main Sep 9, 2026
3 checks passed

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 678cc73bcb

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +38 to +46
let allowed = false;
for (const name of CLIENT_NAMES) {
const owner = await this._getNameOwner(name);
if (owner === sender) {
allowed = true;
break;
}
}
if (!allowed) throw new Error("Only Pathway may request a snapshot.");

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Authenticate the GNOME caller beyond its public bus name

When the GNOME extension is enabled, any process on the user's session bus can request one of the predictable CLIENT_NAMES and then call Capture, because authorization only compares the caller with the current owner of that name. Pathway owns the name only during its own capture operation, so another process can normally claim it and obtain screenshots of the focused window without portal consent. Bind authorization to the actual Pathway process identity rather than possession of a publicly known D-Bus name.

Useful? React with 👍 / 👎.

Comment on lines 28 to +29
yield* clientSettings.set(settings);
yield* snapShot.configure(settings);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Roll back persisted settings when snapshot configuration fails

If native snapshot configuration fails after the settings file has been written—for example, if globalShortcut.register throws for a malformed externally persisted accelerator—the IPC call rejects and persistClientSettingsPatch restores the renderer's previous snapshot, but the new settings remain on disk. The UI therefore reports that the save failed and shows the old value while the supposedly failed value reappears after restart; make the write and native reconfiguration transactional or restore the previous persisted settings on failure.

Useful? React with 👍 / 👎.

Comment on lines +44 to +48
const discard = async (id: string) => {
if (!bridge || discarding) return;
setDiscarding(id);
try {
await bridge.acknowledgeSnapShot(id);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Serialize discard against automatic delivery

When the coordinator is automatically draining a saved capture while the user clicks Discard in Settings, both paths operate independently on the same ID. If delivery has already read the PNG, this acknowledgement can delete the native files while deliverSnapShot continues and adds the image to the draft; its later acknowledgement then fails because the metadata is gone, producing an error even though the capture the user discarded was attached. Make discard atomically cancel or claim the capture before deletion so the reverse action cannot race with delivery.

AGENTS.md reference: AGENTS.md:L77-L77

Useful? React with 👍 / 👎.

Comment on lines +61 to +66
export async function dismissSnapShotAnimation(id: string): Promise<void> {
if (!pendingAnimations.some((capture) => capture.id === id)) return;
finishSnapShotAnimation(id);
const bridge = getDesktopSnapShotBridge();
if (typeof bridge?.dismissSnapShotAnimation !== "function") return;
await bridge.dismissSnapShotAnimation(id).catch(() => undefined);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Dismiss native overlays before the placeholder mounts

When native capture feedback has started but target resolution returns null or fails before beginSnapShotAnimation registers the local placeholder, the coordinator calls this function to tear down the capture. The early return skips the desktop dismissal because the ID is not yet in pendingAnimations, leaving the always-on-top native overlay visible until its independent six-to-ten-second timeout. Always forward dismissal to the desktop bridge even when there is no local animation entry.

Useful? React with 👍 / 👎.

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