Skip to content

feat: prepare desktop release with style tracks and recording reliability - #2219

Open
richiemcilroy wants to merge 8 commits into
mainfrom
codex/desktop-release-readiness
Open

feat: prepare desktop release with style tracks and recording reliability#2219
richiemcilroy wants to merge 8 commits into
mainfrom
codex/desktop-release-readiness

Conversation

@richiemcilroy

@richiemcilroy richiemcilroy commented Sep 4, 2026

Copy link
Copy Markdown
Member

Prepares the next desktop release with timed style/image tracks in both editors, safer device and permission handling, bounded recording shutdown, retained Stop errors and recoverable low-storage failures. Includes preview/export lifecycle fixes, local inference checks, Linux capture/AppImage fixes, and consistent macOS 12.3 packaging.

Local validation: 321 desktop tests, desktop TypeScript, 52 packaging tests, strict scoped Biome, root and GPUI formatting, and Tauri plugin-version checks pass. Native package checks, cross-platform CI, A/V sync and performance validation are in progress.

Kept as a draft pending those results and Greptile review. Exact-candidate native low-storage → Stop → recovery → Quit, Tauri style/image playback/export, signed packages and updater testing remain release gates.

Greptile Summary

This PR prepares a broad desktop release spanning timed style/image tracks, editor preview and export behavior, recording shutdown and recovery, device permissions, Linux capture and packaging, and local inference.

  • Adds portable timed style and image project tracks across the Tauri and GPUI editors and shared renderer.
  • Hardens recording stop, low-storage recovery, device handling, and preview/export lifecycles.
  • Expands Linux Wayland/AppImage support and aligns macOS packaging requirements.
  • The review found clip-deletion timeline drift, a packaged Linux inference lookup failure, a stale GPUI preview race, and two repository-rule violations.

Confidence Score: 3/5

The PR is not yet safe to merge because clip deletion corrupts the timing of the new tracks, packaged Linux inference cannot locate its runtime, and explicit repository requirements remain unsatisfied.

Two blocking behavioral failures remain: deleting clips leaves style/image segments at stale output timestamps, and Linux packages place ONNX Runtime outside every searched location. The generated-file and filename requirements must also be resolved before merging.

Files Needing Attention: apps/desktop/src/routes/editor/context.ts, apps/desktop-gpui/src/editor_edits.rs, crates/camera-effects/src/segmentation.rs, apps/desktop-gpui/src/editor_export.rs, apps/desktop/src/utils/tauri.ts, and the new PascalCase editor component files

Important Files Changed

Filename Overview
apps/desktop/src/routes/editor/context.ts Adds style/image track state and editing actions, but clip deletion does not ripple the new output-time tracks.
apps/desktop-gpui/src/editor_edits.rs Adds native editor support for the new tracks while retaining the same clip-deletion timing omission.
apps/desktop-gpui/src/editor_export.rs Renders export previews from in-memory configuration, but older asynchronous requests can overwrite newer previews.
crates/camera-effects/src/segmentation.rs Adds ONNX Runtime preflight and dynamic loading, but omits the packaged Linux library directory from runtime candidates.
crates/project/src/configuration.rs Defines normalized, half-open output-time style and image segment contracts shared across clients.
crates/rendering/src/layers/image.rs Adds timed image compositing with safe asset loading, cache invalidation, and shared preview/export behavior.
apps/desktop/src-tauri/src/recording.rs Substantially hardens recording lifecycle ownership, bounded stop, cleanup, and recovery behavior.
scripts/finalize-linux-appimage.mjs Adds explicit GTK backend selection and removal of host-conflicting Wayland and PipeWire libraries.

Comments Outside Diff (1)

  1. crates/camera-effects/src/segmentation.rs, line 200-220 (link)

    P1 Linux runtime path is missing

    Linux bundles install ONNX Runtime under /usr/lib/cap, but these candidates only check beside the executable, a macOS Resources directory, and the development target directory. Startup uses this same lookup to set ORT_DYLIB_PATH, so packaged Linux camera blur and Parakeet initialization cannot find the shipped library unless that environment variable is supplied externally.

    Knowledge Base Used: Desktop build and distribution tooling

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: crates/camera-effects/src/segmentation.rs
    Line: 200-220
    
    Comment:
    **Linux runtime path is missing**
    
    Linux bundles install ONNX Runtime under `/usr/lib/cap`, but these candidates only check beside the executable, a macOS `Resources` directory, and the development target directory. Startup uses this same lookup to set `ORT_DYLIB_PATH`, so packaged Linux camera blur and Parakeet initialization cannot find the shipped library unless that environment variable is supplied externally.
    
    **Knowledge Base Used:** [Desktop build and distribution tooling](https://app.greptile.com/cap/-/custom-context/knowledge-base/capsoftware/cap/-/docs/desktop-build-and-distribution.md)
    
    ---
    
    For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.
Prompt To Fix All With AI
### Issue 1
apps/desktop/src/routes/editor/context.ts:680
**Clip deletion misaligns overlays**

Deleting a clip shortens the output timeline, but this path only removes the clip and adjusts transitions. It does not move the new style and image segments. For example, deleting the first clip leaves later overlays at their old timestamps, so preview and export attach them to later content or place them beyond the new timeline. The GPUI clip-deletion path has the same omission, while transcript deletion already ripples both tracks correctly.

### Issue 2
apps/desktop-gpui/src/editor_export.rs:491
**Older previews overwrite newer**

Each refresh captures its own project snapshot, but replacing `preview_task` does not cancel the previous task or identify which request is newest. If an older render finishes after a newer one, it unconditionally replaces the current preview and statistics. Rapid style, image, playhead, or export-setting changes can therefore show a stale preview.

### Issue 3
crates/camera-effects/src/segmentation.rs:200-220
**Linux runtime path is missing**

Linux bundles install ONNX Runtime under `/usr/lib/cap`, but these candidates only check beside the executable, a macOS `Resources` directory, and the development target directory. Startup uses this same lookup to set `ORT_DYLIB_PATH`, so packaged Linux camera blur and Parakeet initialization cannot find the shipped library unless that environment variable is supplied externally.

### Issue 4
apps/desktop/src/utils/tauri.ts:1069
**Generated binding edited directly**

This change directly edits `tauri.ts`, even though the repository directive says never to edit generated `**/tauri.ts` files. The added image and style bindings must be produced through the documented generator. This repository requirement must be satisfied before merging.

### Issue 5
apps/desktop/src/routes/editor/ImageOverlay.tsx:1
**New filenames violate convention**

The repository naming directive requires files to use kebab-case, but this new component uses a PascalCase filename. The same issue appears in `ImageSegmentConfig.tsx`, `StyleSegmentConfig.tsx`, `Timeline/ImageTrack.tsx`, and `Timeline/StyleTrack.tsx`. Rename these modules and update their imports before merging to satisfy the repository requirement.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Reviews (1): Last reviewed commit: "improve: let homepage navigation use the..." | Re-trigger Greptile

Greptile also left 4 inline comments on this PR.

Context used (7)

@richiemcilroy

Copy link
Copy Markdown
Member Author

hey @greptileai, please re-review the PR

produce((project) => {
const timeline = project.timeline;
if (!timeline) return;
timeline.segments.splice(segmentIndex, 1);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Clip deletion misaligns overlays

Deleting a clip shortens the output timeline, but this path only removes the clip and adjusts transitions. It does not move the new style and image segments. For example, deleting the first clip leaves later overlays at their old timestamps, so preview and export attach them to later content or place them beyond the new timeline. The GPUI clip-deletion path has the same omission, while transcript deletion already ripples both tracks correctly.

Knowledge Base Used:

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/desktop/src/routes/editor/context.ts
Line: 680

Comment:
**Clip deletion misaligns overlays**

Deleting a clip shortens the output timeline, but this path only removes the clip and adjusts transitions. It does not move the new style and image segments. For example, deleting the first clip leaves later overlays at their old timestamps, so preview and export attach them to later content or place them beyond the new timeline. The GPUI clip-deletion path has the same omission, while transcript deletion already ripples both tracks correctly.

**Knowledge Base Used:**
- [Export and editor rendering](https://app.greptile.com/cap/-/custom-context/knowledge-base/capsoftware/cap/-/docs/export-and-editor-rendering.md)
- [GPUI desktop client](https://app.greptile.com/cap/-/custom-context/knowledge-base/capsoftware/cap/-/docs/gpui-desktop-client.md)

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

.await;
let result = gpui_tokio::Tokio::spawn(cx, async move {
render_preview(path, time, settings, force).await
render_preview_with_config(path, project, time, settings, force).await

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Older previews overwrite newer

Each refresh captures its own project snapshot, but replacing preview_task does not cancel the previous task or identify which request is newest. If an older render finishes after a newer one, it unconditionally replaces the current preview and statistics. Rapid style, image, playhead, or export-setting changes can therefore show a stale preview.

Knowledge Base Used: Export and editor rendering

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/desktop-gpui/src/editor_export.rs
Line: 491

Comment:
**Older previews overwrite newer**

Each refresh captures its own project snapshot, but replacing `preview_task` does not cancel the previous task or identify which request is newest. If an older render finishes after a newer one, it unconditionally replaces the current preview and statistics. Rapid style, image, playhead, or export-setting changes can therefore show a stale preview.

**Knowledge Base Used:** [Export and editor rendering](https://app.greptile.com/cap/-/custom-context/knowledge-base/capsoftware/cap/-/docs/export-and-editor-rendering.md)

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

@@ -1066,6 +1066,7 @@ export type Hotkey = { code: string; meta: boolean; ctrl: boolean; alt: boolean;
export type HotkeyAction = "startStudioRecording" | "startInstantRecording" | "stopRecording" | "restartRecording" | "togglePauseRecording" | "cycleRecordingMode" | "openRecordingPicker" | "openRecordingPickerDisplay" | "openRecordingPickerWindow" | "openRecordingPickerArea" | "screenshotDisplay" | "screenshotWindow" | "screenshotArea" | "other"
export type HotkeysConfiguration = { show: boolean }
export type HotkeysStore = { hotkeys: { [key in HotkeyAction]: Hotkey } }
export type ImageSegment = { start: number; end: number; track: number; enabled: boolean; path: string; name: string; center: XY<number>; size: XY<number>; opacity: number; rotation: number; rounding: number; flipX: boolean; flipY: boolean; lockAspect: boolean }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Generated binding edited directly

This change directly edits tauri.ts, even though the repository directive says never to edit generated **/tauri.ts files. The added image and style bindings must be produced through the documented generator. This repository requirement must be satisfied before merging.

Context Used: CLAUDE.md (source)

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/desktop/src/utils/tauri.ts
Line: 1069

Comment:
**Generated binding edited directly**

This change directly edits `tauri.ts`, even though the repository directive says never to edit generated `**/tauri.ts` files. The added image and style bindings must be produced through the documented generator. This repository requirement must be satisfied before merging.

**Context Used:** CLAUDE.md ([source](https://github.com/capsoftware/cap/blob/main/CLAUDE.md))

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

@@ -0,0 +1,246 @@
import { createEventListener } from "@solid-primitives/event-listener";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 New filenames violate convention

The repository naming directive requires files to use kebab-case, but this new component uses a PascalCase filename. The same issue appears in ImageSegmentConfig.tsx, StyleSegmentConfig.tsx, Timeline/ImageTrack.tsx, and Timeline/StyleTrack.tsx. Rename these modules and update their imports before merging to satisfy the repository requirement.

Context Used: AGENTS.md (source)

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/desktop/src/routes/editor/ImageOverlay.tsx
Line: 1

Comment:
**New filenames violate convention**

The repository naming directive requires files to use kebab-case, but this new component uses a PascalCase filename. The same issue appears in `ImageSegmentConfig.tsx`, `StyleSegmentConfig.tsx`, `Timeline/ImageTrack.tsx`, and `Timeline/StyleTrack.tsx`. Rename these modules and update their imports before merging to satisfy the repository requirement.

**Context Used:** AGENTS.md ([source](https://github.com/capsoftware/cap/blob/main/AGENTS.md))

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

@richiemcilroy
richiemcilroy marked this pull request as ready for review September 4, 2026 14:54
@greptile-apps

greptile-apps Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

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

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

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