Skip to content

Ios Sim Fixes#221

Merged
arul28 merged 3 commits into
mainfrom
ade/ios-sim-fixes-b9a9fe39
May 1, 2026
Merged

Ios Sim Fixes#221
arul28 merged 3 commits into
mainfrom
ade/ios-sim-fixes-b9a9fe39

Conversation

@arul28
Copy link
Copy Markdown
Owner

@arul28 arul28 commented Apr 30, 2026

Summary

Describe the change.

What Changed

Key files and behaviors.

Validation

How you tested.

Risks

Anything to watch.

Summary by CodeRabbit

Release Notes

  • New Features

    • Added ade git user-identity CLI command to retrieve git user configuration.
    • Added ade prs list-open CLI command to list open pull requests.
    • Introduced iosurface-indigo backend for iOS Simulator streaming with improved performance.
    • Enhanced branch picker with last-commit metadata and associated pull request information.
  • Improvements

    • iOS Simulator now launches headless by default for better performance.
    • Expanded stream status reporting with latency percentiles (P50/P95), fallback reasons, and helper diagnostics.
    • Improved backend selection with automatic fallback on repeated failures.

Greptile Summary

This PR introduces the iosurface-indigo backend for iOS Simulator streaming (native IOSurface frames + Indigo HID input), adds a rich branch picker with PR pills and commit metadata, and wires up ade git user-identity / ade prs list-open CLI commands.

  • P1 — stream startup regression: changing the startStream default from "simctl-screenshot-poll" to "auto" now calls await detectIosurfaceIndigoCapability(), which blocks for up to 120 s while the helper builds on first run. Any stream request that races the background warmup will stall that long before streaming begins.
  • P2 — dead computation: hashHelperSources(helperRoot) is called but its return value is discarded; the hash comparison against helpers.sourceHash is never performed.

Confidence Score: 4/5

Safe to merge with the stream-startup blocking issue addressed; all other paths look correct.

One P1 finding (stream startup can block for up to 120 s on first call with the new auto default) caps the score at 4. The rest of the changes are well-structured with proper error handling and fallback chains.

apps/desktop/src/main/services/ios/iosSimulatorService.ts — specifically the startStream function's use of detectIosurfaceIndigoCapability for auto resolution.

Important Files Changed

Filename Overview
apps/desktop/src/main/services/ios/iosSimulatorService.ts Introduces the new iosurface-indigo backend with capability detection, helper build/cache, fallback chain, and Indigo input helper. One P1 issue: the new auto default for startStream can block for up to 120 s if the helper build hasn't finished warming up.
apps/desktop/src/main/services/prs/prService.ts Adds listOpenPullRequests() and maxPages param to fetchAllPages; previous unbounded-page concern is now addressed with maxPages: 5.
apps/desktop/src/main/services/git/gitOperationsService.ts Enhances listBranches to include per-branch commit metadata (SHA, date, author, message) and adds getUserIdentity. Tab-delimited format with subject last avoids parsing issues.
apps/desktop/src/renderer/components/lanes/BranchPickerView.tsx New branch picker component with virtualized list, PR pills, and relative timestamps. The now timestamp uses useState + setInterval (60s refresh), addressing the stale-time concern from a previous review.
apps/desktop/src/renderer/components/lanes/branchPickerSearch.ts New search/filter module with token parsing (pr:open, pr:draft, author:me, stale:Nd, #N). The pr:open token now correctly includes drafts with an explanatory comment, addressing the previous review concern.
apps/desktop/src/renderer/components/lanes/CreateLaneDialog.tsx Replaces the old <select> for branch import with the new BranchPickerView sheet. PR pill and commit metadata are displayed on the selected-branch summary row.
apps/desktop/src/shared/types/iosSimulator.ts Extends IosSimulatorStreamStatus with latency percentiles, helper PID, input backend, fallback/degradation reasons, and the iosurface-indigo backend variant.
apps/desktop/src/shared/types/git.ts Adds BranchPullRequest, GitUserIdentity, and commit metadata fields to GitBranchSummary. Clean type additions with JSDoc.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[startStream called\ndefault: auto] --> B{backend === auto?}
    B -->|yes| C[detectIosurfaceIndigoCapability\nblocks if build in progress ⚠]
    B -->|no| D[Use requested backend directly]
    C --> E{iosurface available\n& <2 failures/60s?}
    E -->|yes| F[startIosurfaceIndigoStream]
    E -->|no| G{windowCaptureAllowed?}
    G -->|yes| H[startWindowCaptureStream]
    G -->|no| I{idb + idb_companion?}
    I -->|yes| J[startIdbMjpegStream]
    I -->|no| K[startSimctlPreview]
    F --> L{First frame within 5s?}
    L -->|yes| M[Stream running ✓]
    L -->|no| N[startFallbackAfterIosurfaceFailure\nrememberIosurfaceFailure ++]
    N --> G
    J --> O{idb-mjpeg exits?}
    O -->|yes, ffmpeg avail| P[startIdbH264FfmpegStream]
    O -->|yes, no ffmpeg| K
Loading

Comments Outside Diff (5)

  1. apps/desktop/src/main/services/ios/iosSimulatorService.ts, line 1213-1216 (link)

    P2 stdin.write() failure is silently ignored on backpressure

    When sendIosurfaceInputCommand writes to the input helper's stdin, the code registers an empty "drain" listener when write() returns false, but the JSON.stringify({ id, ...command }) payload is already flushed — it is NOT buffered and retried. If the pipe is currently under backpressure (write()false), the payload is still written but the pending-map entry will time out after 5 s rather than getting an ack, and the caller will receive a spurious timeout error.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: apps/desktop/src/main/services/ios/iosSimulatorService.ts
    Line: 1213-1216
    
    Comment:
    **`stdin.write()` failure is silently ignored on backpressure**
    
    When `sendIosurfaceInputCommand` writes to the input helper's `stdin`, the code registers an empty `"drain"` listener when `write()` returns `false`, but the `JSON.stringify({ id, ...command })` payload is already flushed — it is NOT buffered and retried. If the pipe is currently under backpressure (`write()``false`), the payload is still written but the pending-map entry will time out after 5 s rather than getting an ack, and the caller will receive a spurious timeout error.
    
    How can I resolve this? If you propose a fix, please make it concise.

    Fix in Claude Code

  2. apps/desktop/src/main/services/ios/iosSimulatorService.ts, line 184-188 (link)

    P2 Module-level cache creates cross-test / cross-session contamination

    iosurfaceCapabilityCache is a module-level variable and is never cleared on service disposal. If the user switches the selected Xcode (via xcode-select -s) mid-session the stale cache will continue returning the old capability until restart. The detectIosurfaceIndigoCapability function correctly invalidates by developerDir, but the settled fallback in peekIosurfaceIndigoCapabilityForStatus will still serve the cached value. A clearCache() export or a cleanup hook called from dispose() would prevent this from silently causing the wrong backend to be chosen.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: apps/desktop/src/main/services/ios/iosSimulatorService.ts
    Line: 184-188
    
    Comment:
    **Module-level cache creates cross-test / cross-session contamination**
    
    `iosurfaceCapabilityCache` is a module-level variable and is never cleared on service disposal. If the user switches the selected Xcode (via `xcode-select -s`) mid-session the stale cache will continue returning the old capability until restart. The `detectIosurfaceIndigoCapability` function correctly invalidates by `developerDir`, but the settled fallback in `peekIosurfaceIndigoCapabilityForStatus` will still serve the cached value. A `clearCache()` export or a cleanup hook called from `dispose()` would prevent this from silently causing the wrong backend to be chosen.
    
    How can I resolve this? If you propose a fix, please make it concise.

    Fix in Claude Code

  3. apps/desktop/src/main/services/ios/iosSimulatorService.ts, line 919-940 (link)

    P2 Startup-timeout fires after stopStream() has changed streamStatus.backend

    Inside startIosurfaceIndigoStream, the startup timer checks streamStatus.backend !== "iosurface-indigo" before acting, but the timer captures child in a closure. After stopStream() is called and a new backend is started, streamProcess !== child guard correctly skips the callback — so this is fine when the stream is fully restarted. However, if setStreamStopped is called in the meantime (e.g., via stopStream()), streamStatus.running is false, so the early-return guard fires and both startFallbackAfterIosurfaceFailure AND the prior backend-stop code leave streamProcess === null. The fallback then spawns a new process and emits another "stream-started" event when the UI may already be showing a stopped state from a user-initiated stop. Consider adding an explicit disposed/stopped flag to the timeout callback.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: apps/desktop/src/main/services/ios/iosSimulatorService.ts
    Line: 919-940
    
    Comment:
    **Startup-timeout fires after `stopStream()` has changed `streamStatus.backend`**
    
    Inside `startIosurfaceIndigoStream`, the startup timer checks `streamStatus.backend !== "iosurface-indigo"` before acting, but the timer captures `child` in a closure. After `stopStream()` is called and a new backend is started, `streamProcess !== child` guard correctly skips the callback — so this is fine when the stream is fully restarted. However, if `setStreamStopped` is called in the meantime (e.g., via `stopStream()`), `streamStatus.running` is `false`, so the early-return guard fires and both `startFallbackAfterIosurfaceFailure` AND the prior backend-stop code leave `streamProcess === null`. The fallback then spawns a new process and emits another `"stream-started"` event when the UI may already be showing a stopped state from a user-initiated stop. Consider adding an explicit `disposed/stopped` flag to the timeout callback.
    
    How can I resolve this? If you propose a fix, please make it concise.

    Fix in Claude Code

  4. apps/desktop/src/main/services/ipc/registerIpc.ts, line 5874-5454 (link)

    P2 keepSimulatorInBackground flag is double-read from arg but launch() already stores it

    In the iosSimulatorLaunch IPC handler, keepSimulatorInBackground is read from arg a second time here to decide whether to call prepareSimulatorWindowForCapture. But launch() already processes launchArgs.keepSimulatorInBackground (defaulting to true) and stores it in activeSession.keepSimulatorInBackground. Reading it again from the raw arg object (with a different default logic) means the IPC layer and the service's internal flag could differ if the argument is absent. It is safer to rely on the returned result.session?.keepSimulatorInBackground from launch().

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: apps/desktop/src/main/services/ipc/registerIpc.ts
    Line: 5874-5454
    
    Comment:
    **`keepSimulatorInBackground` flag is double-read from `arg` but `launch()` already stores it**
    
    In the `iosSimulatorLaunch` IPC handler, `keepSimulatorInBackground` is read from `arg` a second time here to decide whether to call `prepareSimulatorWindowForCapture`. But `launch()` already processes `launchArgs.keepSimulatorInBackground` (defaulting to `true`) and stores it in `activeSession.keepSimulatorInBackground`. Reading it again from the raw `arg` object (with a different default logic) means the IPC layer and the service's internal flag could differ if the argument is absent. It is safer to rely on the returned `result.session?.keepSimulatorInBackground` from `launch()`.
    
    How can I resolve this? If you propose a fix, please make it concise.

    Fix in Claude Code

  5. apps/desktop/src/main/services/ios/iosSimulatorService.ts, line 3443-3451 (link)

    P1 startStream can block for up to 120 s on first call with new auto default

    The default stream backend changed from "simctl-screenshot-poll" to "auto". With auto, startStream now calls await detectIosurfaceIndigoCapability(), which may block for up to 120 seconds (buildIosurfaceIndigoHelpers timeout) if the stream is requested before the background warmup resolves. Any startStream("auto") call that races the build shares the same pending Promise and stalls. Previously, a caller with no backend arg would get simctl-screenshot-poll immediately.

    Consider using peekIosurfaceIndigoCapabilityForStatus for the auto resolution in startStream (its settled value is available instantly, falling back to the next backend while the build completes), or add a short max-wait timeout before degrading gracefully.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: apps/desktop/src/main/services/ios/iosSimulatorService.ts
    Line: 3443-3451
    
    Comment:
    **`startStream` can block for up to 120 s on first call with new `auto` default**
    
    The default stream backend changed from `"simctl-screenshot-poll"` to `"auto"`. With `auto`, `startStream` now calls `await detectIosurfaceIndigoCapability()`, which may block for up to 120 seconds (`buildIosurfaceIndigoHelpers` timeout) if the stream is requested before the background warmup resolves. Any `startStream("auto")` call that races the build shares the same pending Promise and stalls. Previously, a caller with no `backend` arg would get `simctl-screenshot-poll` immediately.
    
    Consider using `peekIosurfaceIndigoCapabilityForStatus` for the `auto` resolution in `startStream` (its settled value is available instantly, falling back to the next backend while the build completes), or add a short max-wait timeout before degrading gracefully.
    
    How can I resolve this? If you propose a fix, please make it concise.

    Fix in Claude Code

Fix All in Claude Code

Prompt To Fix All With AI
Fix the following 2 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 2
apps/desktop/src/main/services/ios/iosSimulatorService.ts:3443-3451
**`startStream` can block for up to 120 s on first call with new `auto` default**

The default stream backend changed from `"simctl-screenshot-poll"` to `"auto"`. With `auto`, `startStream` now calls `await detectIosurfaceIndigoCapability()`, which may block for up to 120 seconds (`buildIosurfaceIndigoHelpers` timeout) if the stream is requested before the background warmup resolves. Any `startStream("auto")` call that races the build shares the same pending Promise and stalls. Previously, a caller with no `backend` arg would get `simctl-screenshot-poll` immediately.

Consider using `peekIosurfaceIndigoCapabilityForStatus` for the `auto` resolution in `startStream` (its settled value is available instantly, falling back to the next backend while the build completes), or add a short max-wait timeout before degrading gracefully.

### Issue 2 of 2
apps/desktop/src/main/services/ios/iosSimulatorService.ts:469-471
**`hashHelperSources` result is computed but discarded**

`hashHelperSources(helperRoot)` is called here and its SHA-256 return value is silently thrown away. The intent appears to be integrity/staleness detection — comparing against `helpers.sourceHash` from `build.sh --print-json`. Without that comparison this is dead computation; the only observable effect is throwing if a source file is unreadable, which the surrounding try/catch already converts into `available: false`.

Either wire the hash comparison (`hashHelperSources(helperRoot) !== helpers.sourceHash` → rebuild or warn), or remove the call.

Reviews (3): Last reviewed commit: "ship: revert iosurface-indigo stall watc..." | Re-trigger Greptile

@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 30, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
ade Ignored Ignored Preview Apr 30, 2026 11:53pm

@arul28
Copy link
Copy Markdown
Owner Author

arul28 commented Apr 30, 2026

@copilot review but do not make fixes

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 30, 2026

📝 Walkthrough

Walkthrough

Extends iOS simulator streaming with native IOSurface-Indigo capture and Indigo HID input helpers, introduces RPC tools for git user identity and listing open PRs, and adds a branch picker UI component for lane creation with commit metadata and PR filtering capabilities.

Changes

Cohort / File(s) Summary
iOS Simulator Native Helpers
apps/desktop/native/ios-sim-helpers/build.sh, sim-capture.swift, sim-input.m, .gitignore, README.md
New build infrastructure and native helper executables: build script detects Xcode/SimulatorKit, computes deterministic output paths, and compiles Swift frame-capture and Obj-C input-control helpers; captures IOSurface frames as length-prefixed JPEG with diagnostic JSON; handles HID touch/swipe input via JSON request/ack correlation.
CLI and RPC Tools
apps/ade-cli/src/adeRpcServer.ts, cli.ts, cli.test.ts, README.md
New RPC tools git_get_user_identity and prs_list_open with expanded git_list_branches schema; CLI subcommands git user-identity and prs list-open route to new tools; iOS simulator help text updated for headless-by-default launch and Indigo/backend resolution details.
Git and PR Service Backends
apps/desktop/src/main/services/git/gitOperationsService.ts, .../gitOperationsService.branchSwitch.test.ts, .../prs/prService.ts
GitOperationsService.listBranches extended with last-commit metadata (SHA, date, author, message); new getUserIdentity method retrieves git config user; prService.listOpenPullRequests fetches open PRs from GitHub REST API for branch-picker integration.
iOS Simulator Service and Backend Selection
apps/desktop/src/main/services/ios/iosSimulatorService.ts, iosSimulatorService.test.ts, .../shared/types/iosSimulator.ts
IOSurface-Indigo capability detection and build caching (macOS, Xcode version gating); resolveIosSimulatorStreamBackend ranks Indigo with fallback logic; startStream spawns Indigo helper with JPEG frame buffering, latency percentiles (P50/P95), and idle-stop mechanism; Indigo input helper with timeout/ack correlation and idb fallback on repeated failures; stream status expanded with backend, degradation reason, helper pid, input backend, and latency metrics.
IPC Bridge and Preload
apps/desktop/src/main/services/ipc/registerIpc.ts, .../preload/preload.ts, .../preload/global.d.ts, .../shared/ipc.ts
New IPC endpoints gitGetUserIdentity and prsListOpenForRepo registered via ipcMain.handle; preload bridges exposed via contextBridge with strong type signatures from shared types; conditional keepSimulatorInBackground flag for launch behavior control.
Branch Picker UI Component and Search
apps/desktop/src/renderer/components/lanes/BranchPickerView.tsx, BranchPickerView.test.tsx, branchPickerSearch.ts, branchPickerSearch.test.ts
New BranchPickerView component with virtualized branch list, PR pill display, query parsing (tokens: pr:open/draft/none, author:*, mine, stale:Nd, #N), and fuzzy matching across branch/PR metadata; formatRelativeTime for relative timestamp display; comprehensive test coverage for filtering and interaction.
Lane Creation and Integration
apps/desktop/src/renderer/components/lanes/CreateLaneDialog.tsx, LanesPage.tsx, laneUtils.ts
CreateLaneDialog integrates BranchPickerView when importing existing branch; LanesPage fetches branch PR metadata and git user identity during dialog preparation; LaneBranchOption extended with optional last-commit fields (SHA, message, date, author).
Simulator Streaming UI and Chat
apps/desktop/src/renderer/components/chat/ChatIosSimulatorPanel.tsx, ChatIosSimulatorPanel.test.tsx, AgentChatComposer.tsx
ChatIosSimulatorPanel adds dynamic backend selection (Indigo/idb MJPEG/H264/screenshot with fallback), stream status with latency/degradation details, session-scoped toggle between headless and window-capture modes, MJPEG frame buffering, and rAF-scheduled rendering; composer beam activation prevented while simulator open.
Shared Type Definitions and Guidance
apps/desktop/src/shared/types/git.ts, adeCliGuidance.ts
New types GitUserIdentity, GitGetUserIdentityArgs, BranchPullRequest; GitBranchSummary extended with optional commit metadata; CLI guidance updated for headless launch, backend auto-resolution, and stream-status field expansion.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • arul28/ADE#185: Modifies adeRpcServer.ts for RPC tool routing and guidance injection.
  • arul28/ADE#192: Extends IPC endpoints and prService for new handlers and methods.
  • arul28/ADE#108: Modifies CreateLaneDialog.tsx and lane creation flow for import branch selection.

Suggested labels

desktop

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 3.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'Ios Sim Fixes' is vague and generic, using non-descriptive terms that don't convey the scope or primary change of this substantial changeset. Replace with a more specific title that highlights the main feature or primary change, e.g., 'Add iosurface-indigo streaming backend for iOS simulator' or 'Introduce iOS simulator native helpers and branch picker UI'.
✅ Passed checks (3 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ade/ios-sim-fixes-b9a9fe39

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Comment thread apps/desktop/src/main/services/prs/prService.ts
Comment thread apps/desktop/src/renderer/components/lanes/BranchPickerView.tsx
Comment thread apps/desktop/src/renderer/components/lanes/branchPickerSearch.ts
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 10

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/desktop/src/renderer/components/lanes/LanesPage.tsx (1)

1536-1572: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Reset create-dialog identity/loading state before conditional fetches.

prepareCreateDialog clears branches/PRs, but currentGitUserName and loading flags can carry stale values when primary is unavailable (or while prior async calls are still settling). That can produce incorrect mine/author:me filtering and stale loading UI.

Suggested fix
   const prepareCreateDialog = useCallback(() => {
@@
     setCreateBranches([]);
     setCreateBranchPullRequests([]);
+    setCreateGitUserName("");
+    setCreateBranchesLoading(false);
+    setCreateBranchPullRequestsLoading(false);
     setLaneCreated(false);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/desktop/src/renderer/components/lanes/LanesPage.tsx` around lines 1536 -
1572, Reset the create-dialog identity and loading state immediately before the
primary-branch-dependent async work so stale values aren't shown when primary is
absent or prior requests are pending: ensure you call setCreateGitUserName("")
and setCreateBranchPullRequestsLoading(false) and
setCreateBranchesLoading(false) (and optionally setCreateBranches([]) /
setCreateBranchPullRequests([]) if you want empty lists) alongside the existing
setCreateBranchPullRequests([]) / setLaneCreated(false) /
createBaseBranchUserPickedRef.current = false at the top of prepareCreateDialog;
keep the later window.ade.git.* and window.ade.prs.* calls only inside the
primary check as they are now.
🧹 Nitpick comments (1)
apps/desktop/src/renderer/components/chat/ChatIosSimulatorPanel.test.tsx (1)

366-400: ⚡ Quick win

Avoid wall-clock sleeps in this fallback test.

The 1.6s / 2.5s waits make the suite slower and still depend on scheduler timing. Switching this case to fake timers would make the retry assertions deterministic.

♻️ Suggested test refactor
-    await new Promise((resolve) => setTimeout(resolve, 1_600));
+    vi.advanceTimersByTime(1_600);
+    await Promise.resolve();

Apply the same pattern to the later 2.5s idle check.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/desktop/src/renderer/components/chat/ChatIosSimulatorPanel.test.tsx`
around lines 366 - 400, Replace the real-time sleeps with fake timers: in the
test before triggering retries call vi.useFakeTimers(), render
ChatIosSimulatorPanel (using installIosSimulatorApi to get api), and then
advance timers via vi.advanceTimersByTime(...) inside act() to simulate the
1_600ms and 2_500ms delays instead of awaiting new Promise timeouts; after
asserting api.startStream call counts and fallback behavior advance the fake
timers as needed and finally call vi.useRealTimers() to restore; reference
installIosSimulatorApi, api.startStream, emit (for stream-error), and
ChatIosSimulatorPanel when locating where to replace the setTimeout-based waits.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/ade-cli/src/cli.ts`:
- Around line 1688-1690: The PR list-open command path currently returns a label
"PR list open" which prevents the PR table formatter from being applied; update
the branch that checks sub === "list-open" || sub === "open" || sub ===
"list-repo-open" to return the same label used by the prs list formatter (e.g.,
"prs-list") while keeping the steps unchanged (the actionCallStep("result",
"prs_list_open", {}) call should remain); this ensures the formatter inference
recognizes the command and preserves text-mode table output.

In `@apps/desktop/native/ios-sim-helpers/build.sh`:
- Around line 90-92: The current PRINT_JSON branch uses printf to emit JSON
which will break if any of the variables XCODE_VERSION, SOURCE_HASH, OUT_DIR,
CAPTURE, or INPUT contain quotes or backslashes; replace the printf call with a
real JSON encoder (e.g., use python -c, node -e, or jq -n) to construct and
print a properly escaped JSON object when PRINT_JSON == "1", ensuring the keys
"xcodeVersion","sourceHash","buildDir","capture","input" are populated from
those variables.

In `@apps/desktop/native/ios-sim-helpers/sim-capture.swift`:
- Around line 325-376: There is a data race on currentStream and
currentDeviceUdid because they are accessed from signal handlers (sigTerm,
sigInt) on the main queue and the background polling loop; introduce a dedicated
serial DispatchQueue (e.g., streamStateQueue) and wrap every read/write to
currentStream and currentDeviceUdid inside streamStateQueue.sync or async as
appropriate (apply to the signal handlers where you call currentStream?.stop()
and set currentStream/currentDeviceUdid, and to the polling loop locations that
read or mutate these variables and check/assign notifiedNoBoot), ensuring all
access paths (sigTerm, sigInt, and the DispatchQueue.global loop) use the same
queue to serialize access.

In `@apps/desktop/native/ios-sim-helpers/sim-input.m`:
- Around line 385-386: ensureHID() may fail but the code currently proceeds to
elog(@"[sim-input] ready"); instead of aborting; update the startup sequence in
sim-input.m to check the result of ensureHID() (or catch any NSError it
produces), and if initialization fails log a clear error via elog (including the
error details) and terminate the helper immediately (e.g., exit with non-zero or
return an error code) instead of printing "ready" and continuing; locate the
call to ensureHID() and replace the unconditional call+elog with a conditional
that fails fast on error.

In `@apps/desktop/src/main/services/ios/iosSimulatorService.ts`:
- Around line 3577-3581: The iosurfaceScreenMetrics map is not being cleared on
session shutdown/dispose so stale metrics persist and cause mis-normalized
coordinates; update the teardown/shutdown/dispose paths (where activeSession is
nulled, e.g. in shutdown(), dispose(), and the other teardown block around the
other session cleanup) to reset iosurfaceScreenMetrics (clear the map or assign
an empty object) for the UDID or entirely (iosurfaceScreenMetrics = {} or delete
the UDID key) so new sessions start with fresh metrics; ensure you apply the
same change in the other cleanup location mentioned in the review.
- Around line 4287-4310: The sticky fallback uses "anonymous" when there's no
activeSession but preferIndigoInput only compares against activeSession?.id, so
anonymous sessions never match and keep retrying Indigo; update
preferIndigoInput to compare iosurfaceInputStickyFallbackSessionId against
(activeSession?.id ?? "anonymous") (i.e., change the early-return check to use
activeSession?.id ?? "anonymous") so the "anonymous" sticky fallback prevents
Indigo retries for anonymous flows.

In `@apps/desktop/src/main/services/ipc/registerIpc.ts`:
- Around line 5877-5878: The current truthy coercion of
keepSimulatorInBackground can mis-handle non-boolean payloads; change the
parsing so only a literal boolean is accepted and otherwise default to
true—locate the assignment to keepSimulatorInBackground in registerIpc.ts and
replace the Boolean((arg as {...})?.keepSimulatorInBackground ?? true) logic
with a type check that sets keepSimulatorInBackground = typeof (arg as {
keepSimulatorInBackground?: unknown } | null)?.keepSimulatorInBackground ===
'boolean' ? (arg as { keepSimulatorInBackground?: boolean
}).keepSimulatorInBackground : true; thereby ensuring only actual booleans are
respected and all other values (strings, numbers, null, undefined) fall back to
true.

In `@apps/desktop/src/renderer/components/chat/ChatIosSimulatorPanel.tsx`:
- Around line 1244-1247: The preserveVisual path is currently clearing the MJPEG
`url` (in the `setLiveVisual` updater) which unmounts the canvas and causes
flicker; change the updater used where `preserveVisual` is checked so that for
`current?.kind === "mjpeg"` you only update `status` to "reconnecting" (and
optionally reset `error`) but do NOT set `url: null` — keep the existing `url`
while reconnecting, and only clear `url` in the hard-stop/error code paths where
the visual should truly be removed; apply the same change to the other
`setLiveVisual` sites that handle `"mjpeg"` (the occurrences referenced by the
reviewer).
- Around line 1757-1758: The watchdog early-return currently skips stall
detection for iosurface-indigo once a first frame has arrived because the
condition is `streamStatus.backend === "iosurface-indigo" && lastFrameMs`;
change the logic so we only skip the watchdog before the first frame on
iosurface-indigo (i.e., return only when backend is "iosurface-indigo" &&
!lastFrameMs) so that staleAfterMs and restart recovery still run after the
first frame; update the conditional near where `streamStatus`, `lastFrameMs`,
and `staleAfterMs` are computed in ChatIosSimulatorPanel to reflect this
corrected check.

In `@apps/desktop/src/renderer/components/lanes/BranchPickerView.tsx`:
- Around line 135-155: Replace the frozen "now" useMemo with a stateful ticking
timestamp: change const now = React.useMemo(() => Date.now(), []) to a useState
e.g. const [now, setNow] = React.useState(Date.now()), and add a React.useEffect
that sets a lightweight setInterval (e.g. 30s–60s) to call setNow(Date.now())
and clears the interval on cleanup so the component updates while the picker is
open; leave inputRef focus logic intact and ensure the existing useMemo for
filtered (which references now, prByBranch, parsed, parseSearchQuery,
findPrForBranch, matchesQuery) continues to depend on now so relative ages and
stale: filtering refresh.

---

Outside diff comments:
In `@apps/desktop/src/renderer/components/lanes/LanesPage.tsx`:
- Around line 1536-1572: Reset the create-dialog identity and loading state
immediately before the primary-branch-dependent async work so stale values
aren't shown when primary is absent or prior requests are pending: ensure you
call setCreateGitUserName("") and setCreateBranchPullRequestsLoading(false) and
setCreateBranchesLoading(false) (and optionally setCreateBranches([]) /
setCreateBranchPullRequests([]) if you want empty lists) alongside the existing
setCreateBranchPullRequests([]) / setLaneCreated(false) /
createBaseBranchUserPickedRef.current = false at the top of prepareCreateDialog;
keep the later window.ade.git.* and window.ade.prs.* calls only inside the
primary check as they are now.

---

Nitpick comments:
In `@apps/desktop/src/renderer/components/chat/ChatIosSimulatorPanel.test.tsx`:
- Around line 366-400: Replace the real-time sleeps with fake timers: in the
test before triggering retries call vi.useFakeTimers(), render
ChatIosSimulatorPanel (using installIosSimulatorApi to get api), and then
advance timers via vi.advanceTimersByTime(...) inside act() to simulate the
1_600ms and 2_500ms delays instead of awaiting new Promise timeouts; after
asserting api.startStream call counts and fallback behavior advance the fake
timers as needed and finally call vi.useRealTimers() to restore; reference
installIosSimulatorApi, api.startStream, emit (for stream-error), and
ChatIosSimulatorPanel when locating where to replace the setTimeout-based waits.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 8cf11857-e12e-4411-b610-153c34b77ed1

📥 Commits

Reviewing files that changed from the base of the PR and between 913c2c1 and a1749ca.

⛔ Files ignored due to path filters (4)
  • docs/ARCHITECTURE.md is excluded by !docs/**
  • docs/features/ios-simulator/README.md is excluded by !docs/**
  • docs/features/lanes/README.md is excluded by !docs/**
  • docs/features/pull-requests/README.md is excluded by !docs/**
📒 Files selected for processing (31)
  • apps/ade-cli/README.md
  • apps/ade-cli/src/adeRpcServer.ts
  • apps/ade-cli/src/cli.test.ts
  • apps/ade-cli/src/cli.ts
  • apps/desktop/native/ios-sim-helpers/.gitignore
  • apps/desktop/native/ios-sim-helpers/README.md
  • apps/desktop/native/ios-sim-helpers/build.sh
  • apps/desktop/native/ios-sim-helpers/sim-capture.swift
  • apps/desktop/native/ios-sim-helpers/sim-input.m
  • apps/desktop/src/main/services/git/gitOperationsService.branchSwitch.test.ts
  • apps/desktop/src/main/services/git/gitOperationsService.ts
  • apps/desktop/src/main/services/ios/iosSimulatorService.test.ts
  • apps/desktop/src/main/services/ios/iosSimulatorService.ts
  • apps/desktop/src/main/services/ipc/registerIpc.ts
  • apps/desktop/src/main/services/prs/prService.ts
  • apps/desktop/src/preload/global.d.ts
  • apps/desktop/src/preload/preload.ts
  • apps/desktop/src/renderer/components/chat/AgentChatComposer.tsx
  • apps/desktop/src/renderer/components/chat/ChatIosSimulatorPanel.test.tsx
  • apps/desktop/src/renderer/components/chat/ChatIosSimulatorPanel.tsx
  • apps/desktop/src/renderer/components/lanes/BranchPickerView.test.tsx
  • apps/desktop/src/renderer/components/lanes/BranchPickerView.tsx
  • apps/desktop/src/renderer/components/lanes/CreateLaneDialog.tsx
  • apps/desktop/src/renderer/components/lanes/LanesPage.tsx
  • apps/desktop/src/renderer/components/lanes/branchPickerSearch.test.ts
  • apps/desktop/src/renderer/components/lanes/branchPickerSearch.ts
  • apps/desktop/src/renderer/components/lanes/laneUtils.ts
  • apps/desktop/src/shared/adeCliGuidance.ts
  • apps/desktop/src/shared/ipc.ts
  • apps/desktop/src/shared/types/git.ts
  • apps/desktop/src/shared/types/iosSimulator.ts

Comment thread apps/ade-cli/src/cli.ts
Comment thread apps/desktop/native/ios-sim-helpers/build.sh Outdated
Comment thread apps/desktop/native/ios-sim-helpers/sim-capture.swift
Comment thread apps/desktop/native/ios-sim-helpers/sim-input.m Outdated
Comment thread apps/desktop/src/main/services/ios/iosSimulatorService.ts
Comment thread apps/desktop/src/main/services/ios/iosSimulatorService.ts
Comment thread apps/desktop/src/main/services/ipc/registerIpc.ts Outdated
Comment thread apps/desktop/src/renderer/components/chat/ChatIosSimulatorPanel.tsx
Comment thread apps/desktop/src/renderer/components/chat/ChatIosSimulatorPanel.tsx
Comment thread apps/desktop/src/renderer/components/lanes/BranchPickerView.tsx Outdated
arul28 added a commit that referenced this pull request Apr 30, 2026
…omments

CI: convert idb_companion spawn errors into structured stream-error events
and add disposed-checks to ensureCompanion's prewarm path so a fire-and-forget
spawn does not bubble as an unhandled error after dispose.

Review (CodeRabbit + Greptile):
- ade-cli prs list-open table formatter label fix
- native helpers: jq/python JSON, serial DispatchQueue for sim-capture state,
  ensureHID failure now exits non-zero
- iosSimulatorService: clear iosurfaceScreenMetrics on shutdown/dispose;
  preferIndigoInput compares against fallback marker
- registerIpc: explicit boolean handling for keepSimulatorInBackground
- ChatIosSimulatorPanel: stable MJPEG url through preserveVisual; stall
  detection extended to iosurface-indigo with per-transport threshold
- BranchPickerView: ticking now-state for relative ages
- LanesPage: reset identity/loading state in prepareCreateDialog
- prService: maxPages cap on listOpenPullRequests
- branchPickerSearch: pr:open includes drafts

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@arul28
Copy link
Copy Markdown
Owner Author

arul28 commented Apr 30, 2026

@copilot review but do not make fixes

arul28 and others added 2 commits April 30, 2026 19:52
iOS simulator native helpers + sim-capture/sim-input bridges, ChatIosSimulatorPanel updates, lanes BranchPickerView, branch-picker search utilities, ADE CLI guidance + RPC tweaks, and feature docs sync.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…omments

CI: convert idb_companion spawn errors into structured stream-error events
and add disposed-checks to ensureCompanion's prewarm path so a fire-and-forget
spawn does not bubble as an unhandled error after dispose.

Review (CodeRabbit + Greptile):
- ade-cli prs list-open table formatter label fix
- native helpers: jq/python JSON, serial DispatchQueue for sim-capture state,
  ensureHID failure now exits non-zero
- iosSimulatorService: clear iosurfaceScreenMetrics on shutdown/dispose;
  preferIndigoInput compares against fallback marker
- registerIpc: explicit boolean handling for keepSimulatorInBackground
- ChatIosSimulatorPanel: stable MJPEG url through preserveVisual; stall
  detection extended to iosurface-indigo with per-transport threshold
- BranchPickerView: ticking now-state for relative ages
- LanesPage: reset identity/loading state in prepareCreateDialog
- prService: maxPages cap on listOpenPullRequests
- branchPickerSearch: pr:open includes drafts

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@arul28 arul28 force-pushed the ade/ios-sim-fixes-b9a9fe39 branch from 97af9ef to 5019589 Compare April 30, 2026 23:53
Restores the early-return for iosurface-indigo after first frame so the
test "does not restart an idle native stream after it has produced a
frame" continues to pass. The CodeRabbit nit was minor and conflicts
with this load-bearing test.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@arul28
Copy link
Copy Markdown
Owner Author

arul28 commented Apr 30, 2026

@copilot review but do not make fixes

@arul28
Copy link
Copy Markdown
Owner Author

arul28 commented Apr 30, 2026

@greptile review

@arul28 arul28 merged commit 399fbd0 into main May 1, 2026
24 of 25 checks passed
@arul28 arul28 deleted the ade/ios-sim-fixes-b9a9fe39 branch May 1, 2026 00:06
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