fix(conversation): stretch diff line rows to full width - #435
Open
RonenMars wants to merge 90 commits into
Open
Conversation
Add typed cache integrity alert contracts across REST, WebSocket, and per-server Zustand state. Sync pending alerts through websocket broadcasts and foreground-aware REST queries so clients converge after reconnects or missed unicasts. Present low-severity alerts in a banner and auto-open high-severity alerts in a localized resolution modal. Support prune-all, prune-selected, ignore, and reset-rescan actions; require confirmation for destructive choices; refetch on fingerprint conflicts; and surface backup paths on success. Cover store lifecycle, websocket dispatch, banner and modal interactions, locale parity, backward-compatible 404 handling, successful resolution, and fingerprint conflicts with unit and mocked-transport integration tests.
Explicit Help & Feedback submissions self-init Sentry like reportOneShot, show delivery method in the success UI, and keep standing reporting opt-in. Co-authored-by: Cursor <cursoragent@cursor.com>
Adds missing viaSentry/viaEmail keys to feedback.json for ar, he, and ru. The English keys were added in this branch but the other locales were never updated, which i18n-completeness.test.ts catches.
Legacy uploads with spaces in filenames broke Claude Code path parsing; escape spaces so multi-attachment sends remain valid single-token refs. Co-authored-by: Cursor <cursoragent@cursor.com>
Discard empty PTYs the user never typed into so they do not linger in the hub after abandoning a new session from browse. Co-authored-by: Cursor <cursoragent@cursor.com>
Mark Features 35/36 and Bugs 5/16 as in-flight; freeze the 2026-07-18 analysis as a snapshot with an updated release verdict. Co-authored-by: Cursor <cursoragent@cursor.com> [skip-ci]
Bumps the npm_and_yarn group with 1 update in the / directory: [shell-quote](https://github.com/ljharb/shell-quote). Updates `shell-quote` from 1.8.4 to 1.10.0 - [Changelog](https://github.com/ljharb/shell-quote/blob/main/CHANGELOG.md) - [Commits](ljharb/shell-quote@v1.8.4...v1.10.0) --- updated-dependencies: - dependency-name: shell-quote dependency-version: 1.10.0 dependency-type: indirect dependency-group: npm_and_yarn ... Signed-off-by: dependabot[bot] <support@github.com>
The conversation screen now polls its delta drain while focused and consumes streamed conversation_events, so an externally launched session reads as a live transcript without resuming it. Resuming a conversation that may still be open elsewhere shows a confirmation naming what the server detected, and offers Take over only when a real process was matched. External sessions route to the read-only conversation view instead of the PTY screen, and the discovered-session overtake path is gated off for them. Session rows show a distinct external-alive indicator derived from the additive liveness fields, falling back to pid for older servers.
Add typed cache integrity alert contracts across REST, WebSocket, and per-server Zustand state. Sync pending alerts through websocket broadcasts and foreground-aware REST queries so clients converge after reconnects or missed unicasts. Present low-severity alerts in a banner and auto-open high-severity alerts in a localized resolution modal. Support prune-all, prune-selected, ignore, and reset-rescan actions; require confirmation for destructive choices; refetch on fingerprint conflicts; and surface backup paths on success. Cover store lifecycle, websocket dispatch, banner and modal interactions, locale parity, backward-compatible 404 handling, successful resolution, and fingerprint conflicts with unit and mocked-transport integration tests.
The conversation screen now polls its delta drain while focused and consumes streamed conversation_events, so an externally launched session reads as a live transcript without resuming it. Resuming a conversation that may still be open elsewhere shows a confirmation naming what the server detected, and offers Take over only when a real process was matched. External sessions route to the read-only conversation view instead of the PTY screen, and the discovered-session overtake path is gated off for them. Session rows show a distinct external-alive indicator derived from the additive liveness fields, falling back to pid for older servers.
Adds a dead-key test asserting every English key is referenced somewhere in the source, complementing the existing key-parity gate in i18n-completeness.test.ts.
The scanner reads `t('ns:key')` and bare `t('key')` calls, keeps the static prefix of dynamic keys as a prefix match, and picks up keys hoisted into consts before reaching t().
Arrays are treated as leaves since they are fetched whole via `returnObjects: true`.
Removes the 161 keys it flagged across all four locales — 654 removals, since ar and ru carry extra CLDR plural forms.
Every flagged key was verified against a raw grep to rule out false positives.
Repoints the plural and interpolation assertions in i18n.test.ts onto keys the app actually uses, since the previous fixtures were among the dead keys.
Both server remove confirmations built their message from a hardcoded English template literal, so the dialog body stayed in English for he, ru, and ar users while the surrounding title and buttons translated.
The servers:dialog.removeMessage key already existed but had gone unreferenced, which is how the hardcoding went unnoticed.
Points both call sites at the key and adds a {{server}} placeholder to it, since the previous wording was generic while the hardcoded string named the server.
The English output is unchanged; the other three locales are rephrased to match.
Mark in-flight and shipped items from the July launch batch, reconcile stale Open rows, and set the next mobile actions (typecheck, Maestro, onboarding). Co-authored-by: Cursor <cursoragent@cursor.com> [skip-ci]
Unblocks `voice_dictation` by granting speech-recognition and microphone via simctl privacy in ensure-release-build.js. Co-authored-by: Cursor <cursoragent@cursor.com>
Guard Skip/swipe so Welcome cannot dump into an empty Hub, advance immediately after QR exchange, add back-to-choose, and fix Mac-centric copy / default port 8766. Co-authored-by: Cursor <cursoragent@cursor.com>
Attribute browse failures to setup/XCUITest flake rather than FilterSortSheet, add layout/close testIDs, and make feat1 switch Classic→Tree before drilling. Co-authored-by: Cursor <cursoragent@cursor.com>
Classify threadbase:// URIs and pt_* tokens, run exchangeToken for those, and keep Bearer /api/profiles for long-lived API keys. Co-authored-by: Cursor <cursoragent@cursor.com>
Add server_drag_reorder.yaml to test:e2e:mock and remove the known-crashing swipe on drag-handles; default path asserts the lock-toggle gate. Co-authored-by: Cursor <cursoragent@cursor.com>
Insert notifications after Connect (TOTAL_STEPS=4). Skip/pair-later jumps to Done and skips the notifications step. Co-authored-by: Cursor <cursoragent@cursor.com>
Evict stale session/conversation favorites and eager cache rows on 404, rehydrate the bound conversation after foreground reconnect, and cover the hub→browse handoff plus merge/dedupe helpers with tests.
Make Scan QR the recommended path, explain local vs remote reachability, validate server URLs before dial, improve camera-denial and error support paths, allow naming the paired server, and stop pre-filling localhost in production Add Server.
Keep paginated conversation fetches cancellable, surface empty/offline server sections, and force server chips when the same project path exists on more than one host so partial failures never blank the hub.
Assert favorite ids instead of union-narrowed conversationId, and stub getQueryData on the mocked query client used by reconnect rehydrate.
Treat any non-ok/non-error fetch status as warming, and align the manual connect integration assertion with On your computer copy.
Derive managed/external/resumed/on-hold/historical/stale labels from existing wire fields, drive hub rows and the session status bar from one helper, and localize live pills and status chrome.
…mport Inline ownership/liveness checks so the helper ports to main without requiring integration-only session fields as type imports.
## Summary - Prefer raw terminal when parse confidence is low or chat has no messages while PTY output is active, so normalized chat is never treated as authoritative when uncertain - Add row-level `RenderErrorBoundary` containment for message and terminal line renders - Extract provider terminal-chrome adapters (Claude / Codex / passthrough) and track unsupported/truncated escapes in `VirtualTerminal` - Virtualize the live PTY placeholder, add copy-all for terminal output, and clarify terminal vs chat mode on the session status bar - Add unit coverage for chrome adapters, confidence policy, long-output caps, and render containment ## Test plan - [x] Unit: `terminalChrome`, `renderConfidence`, `virtual-terminal` (+ long-output), `RenderErrorBoundary` - [x] Integration: `TerminalOutput`, `TerminalView`, `LiveConversationView` - [ ] Manual: open a live session in chat mode with PTY-only output and confirm raw-terminal fallback banner - [ ] Manual: toggle Terminal/Chat chip on session status bar - [ ] Manual: copy-all on terminal output
## Summary - Document the repo’s dominant PR title format (`type(scope): summary`) and matching branch names in `AGENTS.md` / `CLAUDE.md` - Record that this integration wave bases PRs on `integration-merge-354-355-376` - Explicitly retire bracket-slug titles like `[feat][task-name]` for new work ## Test plan - [x] Diff is docs-only
Surface Edit/Write diffs in a scoped read-only review UI with filters, large-diff safeguards, desktop handoff copy, and optional agent notes.
…405) ## Summary - Gate session-card / message enter animations on OS Reduce Motion - Enforce 44pt minimum touch targets on terminal jump/copy and diff copy controls - Cap Dynamic Type on monospace terminal/diff text; add VoiceOver labels for terminal lines - Document remaining U12 follow-ups in `docs/a11y-theme-perf.md` ## Test plan - [x] Unit: a11y constants - [x] Integration: TerminalOutput - [ ] Manual: Reduce Motion on → no FadeInDown on new cards/messages - [ ] Manual: Dynamic Type XL → terminal stays usable
…#407) ## Summary - Consume streamer `GET /api/diagnostics` (contract v1) with per-check status and stable remediation codes - Add Settings → Server health screen: multi-server picker, retry, localized remediation actions, copy/share sanitized report - Keep existing client feedback diagnostics (`/diagnostics`) separate ## Test plan - [x] Unit: parse/report helpers (`server-diagnostics.test.ts`) - [ ] Manual: Settings → Server health against a paired streamer on `integration/missing-prs-2026-07-23` - [ ] Confirm failed provider check shows `PROVIDER_NOT_INSTALLED` remediation card - [ ] Confirm copy report contains no secrets/URLs beyond the server label
) ## Summary - Consume streamer `GET /api/providers` (capabilities + availability + warnings) - Browse provider picker disables unavailable CLIs and shows localized capability/compatibility notes - Typed parser + unit coverage for the providers envelope ## Test plan - [x] Unit: `provider-health.test.ts` - [ ] Manual: browse with one provider missing on host → start disabled + warning - [ ] Manual: Codex selected → “no structured questions” note when available
## Summary - Consume streamer `GET /api/push/health` with delivery states (never-delivered / healthy / failing / dead / revoked) - Settings → Delivery health: quiet-hours preview, retry, re-register (sends `deviceId`) - Remove the notifications “Coming soon” overlay so prefs and local test are usable ## Test plan - [x] Unit: push-health parser - [ ] Manual: open Delivery health against a paired streamer with push store - [ ] Manual: Re-register updates token list; tokens never shown in UI
## Summary - Add Settings → Paired devices screen over `GET /api/devices` and `POST /api/devices/:id/revoke` (capability chips, last-seen, idempotent revoke). - Pair exchange now sends `deviceName` and stores `deviceId` / capabilities (device token in SecureStore only; never shown). - Owner API key remains the auth credential so device admin and backup stay available; U7 provider warning copy clarified as unverified, not broken. ## Test plan - [ ] Pair a server against streamer with device registry; open Settings → Paired devices and confirm this device appears with capabilities. - [ ] Revoke another device; confirm list updates and a second revoke reports already-revoked. - [ ] Confirm credentials/tokens never appear in the UI. - [ ] Unit: `devices`, `pair-exchange`, `useTBPair`, i18n completeness/unused.
## Summary - Add Settings → Backup & restore over `GET /api/backup/export` and `POST /api/backup/restore`. - Export is shareable/copyable JSON with an explicit metadata-only warning (conversations are not in the archive). - Restore is dry-run first, then confirm apply; `RESTORE_CONFLICT` surfaces the plan and blocks apply. ## Test plan - [ ] Export against a streamer with projects; copy/share JSON; confirm counts and host/version. - [ ] Paste the archive back, dry-run, confirm create/update summary, then apply. - [ ] Force a path conflict and confirm apply stays blocked with conflict copy. - [ ] Optional pathMap from→to rewrites paths in the dry-run plan. - [ ] Unit: `backup` parsers + i18n completeness/unused.
Show the newest three recent locations inline; when more exist, open a modal that lists all of them and filters by path substring.
The integration branch has never been run through test.yml, so three failures accumulated unnoticed across ~82 commits. PR #425 was the first thing to trigger CI on it, which surfaced them. Type check and Integration tests both traced to app/conversation/[id].tsx. a1e263c added LivePauseControl to the header actions and, in resolving that conflict, deleted the in-chat search Pressable that ff28c60 had introduced, while leaving the MagnifyingGlass import, the headerButton styles, the searchBarState hook, and the test coverage all in place. The same commit also dropped the makeSearchStyles import while keeping its call site, which is the TS2552 error. Restore both: the import and the search button, verbatim from a1e263c's parent. i18n unused keys flagged three keys with no remaining code reference. b75dfb8 pruned connect.step1 and connect.step2 as dead, but ConnectStep.tsx still renders all three steps as a numbered sequence, so step3 rendered alone after a gap. Restore step1 and step2 in all four locales from their pre-prune text. Drop onboarding.connect.footnote and servers.dialog.removeDismiss, which are genuinely unreferenced. conversation.search.open is left as-is: it labels the restored search button, so it was never dead.
Build 173 crashed at launch on every device with EXC_CRASH (SIGABRT) / "DYLD 4 Symbol missing": ExpoCamera 57.0.1 referenced AnyModule._decorateExpoObject(object:in:appContext:), but the bundled ExpoModulesCore 57.0.7 renamed that protocol requirement to the two-argument _decorateModule(object:in:). The skew came from #412, which pinned expo-modules-core forward to 57.0.7 via npm overrides to get ColorCompat for the Android R8 minify step, without moving the rest of the Expo module set with it. ExpoModulesCore ships as a precompiled xcframework, so the mismatch was invisible at compile time and only surfaced in dyld. Bump expo to 57.0.8 and align all 22 expo-*/@expo/* modules to that SDK's bundled native module set, which supplies expo-modules-core 57.0.7 legitimately and moves expo-camera to 57.0.3. The override is now redundant and is removed; the Android ColorCompat fix is preserved because core stays at 57.0.7. Also bump react-native-screens to 4.26.2 to match what expo-router 57.0.8 requires, removing a duplicate nested copy. expo-image-manipulator was still on 57.0.1 and referenced the same missing symbol, so the original fix was incomplete. Add two guardrails, both verified against a real Release build: - scripts/verify-dyld-symbols.sh resolves every cross-framework symbol in the archive before altool upload, so a launch-crashing build cannot reach TestFlight. - npm run check:native-deps fails CI on duplicate native modules, which is the npm-level shape of this bug.
Drop accidentally tracked crash-log.txt and log-mobile.txt from the tree.
Xcode 26.3's Swift 6 compiler fails on abs(milliseconds) in expo-modules-jsi's Date decoding with "type of expression is ambiguous without a type annotation", breaking the Ship iOS job. Expo's real fix (Xcode 26.4) isn't on GitHub's macos-15 runner yet, so patch-package disambiguates the call as a stopgap.
session_update is a fire-once push; one lost while backgrounded strands the thinking bubble indefinitely since reconnect never replays it or refetches status.
getRawLines() only dropped blank rows, so Claude Code's status-bar box borders leaked into the raw terminal view as literal characters when parse confidence fell to low.
RonenMars
force-pushed
the
26-07-2026.18-44-integration
branch
from
July 28, 2026 16:58
ce2fe1d to
ff17d31
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Test plan