[orchestrator-v2] fix(mobile): Stabilize iOS draft attachments, Hermes sort, and Home - #3923

Closed
mwolson wants to merge 138 commits into
pingdotgg:t3code/codex-turn-mappingfrom
mwolson:fix/ios-v2-attachment-persistence
Closed

[orchestrator-v2] fix(mobile): Stabilize iOS draft attachments, Hermes sort, and Home#3923
mwolson wants to merge 138 commits into
pingdotgg:t3code/codex-turn-mappingfrom
mwolson:fix/ios-v2-attachment-persistence

Conversation

@mwolson

@mwolsonmwolson commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Keep CTM mobile draft image attachments working when they carry both a local id and a dataUrl.
  • Avoid a Hermes fatal in the queue UI by replacing missing Array.prototype.toSorted with a shared copy-sort helper.
  • Hide orchestration-v2 subagent threads from the mobile Home list (forks stay visible).
  • Stabilize Home native-stack options and callbacks so ordinary Home updates do not re-enter navigation through PreventRemoveProvider.
  • Normalize V2 shell active/archive membership from archivedAt so archived threads do not stick on the Home list after a missed archive delta.

Base

This branch is now built on mwolson/t3codev2-base, a merge of the shared iOS/mobile fixes line (ios-fixes-main) into t3code/codex-turn-mapping. Because GitHub diffs against t3code/codex-turn-mapping, the PR diff includes that merge (mobile keyboard/feed fixes, shell reconnect heal, serverConfig/vcsRefs caching, and the V2 thread resume completion marker) in addition to the two commits listed below. Review the two head commits for this PR's own delta.

Problem and Fix

Problem and Why it HappenedFix
CTM drafts can include image attachments with both a local id and a dataUrl. The start-turn path did not treat those dual-tagged attachments as uploads, so order and persistence broke for mobile screenshots.Treat dual-tagged attachments as uploads, strip local-only fields before persistence, and dispatch server IDs while preserving order with already-persisted attachments.
Hermes 250829098 (RN 0.85.3) does not implement Array.prototype.toSorted. CTM queue UI calls it from deriveThreadQueueWorkflowState / ThreadQueueControl, so queuing a reply or finishing a turn can crash with TypeError: undefined is not a function.Add @t3tools/shared/ArraycopySorted ([...values].sort) and use it on mobile-reachable call sites (threadWorkflows, ThreadRelationshipsBanner, use-thread-selection, CTM model.ts).
Orchestration-v2 subagent shells appeared in the mobile Home list, unlike the desktop sidebar.Skip threads with lineage.relationshipToParent === "subagent" when grouping Home rows; keep fork threads.
Unstable Home native-stack options and callbacks re-entered setOptions and could hit maximum update depth through PreventRemoveProvider on CTM device launches.Memoize iOS Home header options (filter menu inputs as deps; handlers via ref) and stabilize Settings / New Task callbacks and title option objects.
A dropped thread.archived shell delta (or a mis-tagged full snapshot) could keep an archived thread listed as active on Home even after the reconnect heal applied a fresh snapshot.Add normalizeShellThreadMembership and apply it to every full snapshot (reducer enrichment refreshes and reconnect heals) so active/archive membership always derives from archivedAt. The HTTP heal, forced socket snapshot, and stale-snapshot rejection it pairs with live in v2-base.

Validation

  • Targeted tests: client-runtime attachment command tests; Home subagent filter tests (including fork negative control); shared Array tests; shell-sync / shellReducer membership tests.
  • vp check (0 errors) and full vp run typecheck on the rebuilt branch.
  • Device: archived threads from a paired CTM environment leave Home after reconnect/heal.
  • Device: Release Hermes com.mwolson.t3code.v2.dev from local orchestrator-v2 integration; queued reply send after active turn finished without crash; Home list usable after nav stability fix.

Notes

Note

Stabilize iOS draft attachments, Hermes array sort, and Home screen for mobile

This is a large orchestrator-v2 stabilization PR with dozens of changes across mobile, web, server, and desktop. Key highlights:

  • iOS draft attachments: persistAttachments now correctly maps upload results back to their source positions and strips client-only fields (id, previewUri) before sending to the server.
  • Hermes sort fix: Replaces Array.prototype.toSorted (unsupported on Hermes) with a shared copySorted utility throughout mobile thread sorting.
  • Home screen (Android): Adds a floating new-task FAB, custom branded header with inline search, and persists collapsed project groups via preferences atoms.
  • Draft hero UX: Web chat view gains a centered composer for empty drafts with animated docking transitions and a DraftHeroHeadline project picker.
  • Thread feed scroll correction: ThreadFeed now auto-corrects scroll position when content underflows the viewport and shows a full-screen loading overlay during hydration.
  • iOS terminal stability: TerminalInputSequence normalizes all return keys to carriage return (\r); autoFocus prop added to control keyboard focus.
  • Shell state synchronization: makeEnvironmentShellState no longer paints cached snapshots immediately; starts in synchronizing and waits for an HTTP heal or authoritative socket snapshot.
  • Thread resume completion marker: Server and client cooperate on a synchronized marker so warm-start clients exit the syncing state faster.
  • Android terminal: Full native terminal canvas (TerminalCanvasView, GhosttyBridge) with JNI bindings, selection, scroll, and theme support.
  • Incoming share flow (iOS/Android): IncomingShareProvider and IncomingShareInbox serialize share ingestion, merge content into composer drafts idempotently, and clean up temporary files.
  • Legal pages: Marketing site gains Privacy Policy, Terms of Service, and Security Policy pages with a shared LegalPage layout component.
  • Risk: IndexedDB schema bumped from v2 to v4; upgrade path adds new object stores but no migration for existing server-config/vcs-refs data (cold start for those caches).

Macroscope summarized 47dc628.


Note

Medium Risk
Touches desktop launcher/signing behavior, auto-update state, and substantial mobile native/Expo configuration; misconfiguration could affect local iOS builds, store screenshots CI, or renderer chrome, but changes are mostly additive with tests on key desktop paths.

Overview
Adds a manual GitHub workflow to capture and validate iOS and Android store showcase screenshots (pnpm screenshots:mobile), upload artifacts, and ignore generated .showcase/ / artifacts/app-store/screenshots/ paths.

Desktop changes improve the macOS dev launcher (branded bundle with a separate launcher executable that execs in-bundle Electron, launcher version bump), context menu positioning scaled by webContents zoom, native fullscreen state exposed to the renderer via IPC/preload, nightly update release notes (setFullChangelog + HTML/markdown normalization into update state), and WSL Node engine validation during probe.

Marketing adds a shared legal document layout, index plus privacy/terms/security pages, footer links, and Grok CLI messaging/assets on the homepage (with minor harness/layout tweaks).

Mobile expands Expo config: repo-root brand assets, Personal Team local iOS builds (optional bundle id, stripped widgets/share/SiWA entitlements), more Android plugins (Gradle heap, predictive back, modern menus/alerts, crash log), DM Sans registered under native PostScript names, and a new Android T3ComposerEditor native view (chips, paste images, theming). iOS markdown shadow node now rebuilds attributed content from current children instead of stale measure-time cache. Composer iOS fonts align to DMSans-Regular / DMSans-Medium.

Also bumps electron-builder, adds minimal root app.json, extends Macroscope Effect service conventions (dependency acquisition / runtime boundaries), and minor asset/doc updates.

Reviewed by Cursor Bugbot for commit 47dc628. Bugbot is set up for automated code reviews on this repo. Configure here.

juliusmarmingeand others added 17 commits July 7, 2026 15:55
…gg#3781)
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
…pingdotgg#3795)
Co-authored-by: Julius Marminge <julius@mac.lan>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
…tgg#3823)
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: Horus Lugo <horusgoul@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: maria-rcks <maria@kuuro.net>
Co-authored-by: Shivam Sharma <91240327+shivamhwp@users.noreply.github.com>
Co-authored-by: Ben Davis <45952064+bmdavis419@users.noreply.github.com>
Co-authored-by: Alex <me@pixp.cc>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: Julius Marminge <julius@mac.lan>
Co-authored-by: codex <codex@users.noreply.github.com>
@coderabbitai

coderabbitaiBot commented Jul 12, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 8bbf5543-c8a1-4f1c-8bfe-1d903c77b419

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Jul 12, 2026
Comment threadapps/mobile/src/features/home/HomeHeader.tsx
@mwolson
mwolson marked this pull request as ready for review July 12, 2026 21:35
Comment threadpackages/shared/src/Array.ts Outdated
@macroscopeapp

macroscopeappBot commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

25 blocking correctness issues found. Diff is too large for automated approval analysis. A human reviewer should evaluate this PR.

You can customize Macroscope's approvability policy. Learn more.

@mwolson
mwolsonforce-pushed the fix/ios-v2-attachment-persistence branch from 2857eb3 to 76a88a0CompareJuly 12, 2026 21:41
@mwolsonmwolson changed the title fix(mobile): Stabilize CTM iOS draft attachments, Hermes sort, and Home[orchestrator-v2] fix(mobile): Stabilize CTM iOS draft attachments, Hermes sort, and HomeJul 12, 2026
Capture RCTFatal message and stack to Documents via a native handler so
Release Hermes aborts leave last-crash.json without a device console.
Harden the JS ErrorUtils path with a minimal write-first record, durable
fsync writes, breadcrumb max-wait flush, and an Expo AppDelegate plugin.
Skip NativeStackScreenOptions setOptions when content is unchanged so
Thread catch-up re-renders do not loop through PreventRemoveProvider and
hit maximum update depth.
CI Mobile Native Static Analysis failed on a multi-line if where the
opening brace was on the following line.
Completes the pingdotgg#4055 port in the v2-base merge: draft routes carry a
pre-allocated thread id, and the conditional subscription blocked
promotion to live shell data until remount. Flagged by Grok review.

@cursorcursorBot left a comment

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.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

There are 4 total unresolved issues (including 3 from previous reviews).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 47dc628. Configure here.


Function("markShowcaseReady") { (scene: String) in
let readyPath = NSHomeDirectory() + "/Library/Caches/T3ShowcaseReadyScene"
try? scene.write(toFile: readyPath, atomically: true, encoding: .utf8)

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.

Crash breadcrumb fsync path removed

Medium Severity

The writeSyncText function, which provided durable last-chance crash log writes, was removed from T3NativeControlsModule. This breaks the breadcrumbPersist mechanism, which still expects this native fsync path. As a result, last-minute breadcrumbs may be lost during iOS fatals, impacting crash diagnostics.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 47dc628. Configure here.

@mwolson

Copy link
Copy Markdown
ContributorAuthor

Closing for now; may reattempt later after the iOS fixes have landed on main, and have been backmerged to codex-turn-mapping.

@mwolsonmwolson closed this Jul 20, 2026
juliusmarminge added a commit that referenced this pull request Jul 20, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
maria-rcks pushed a commit that referenced this pull request Aug 3, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 4, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 4, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 5, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 7, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 10, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 11, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 12, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 14, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 14, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 15, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 17, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 28, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 28, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 28, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 29, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 29, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 29, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 29, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 30, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 30, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Sep 1, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Sep 2, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

20 participants

@mwolson@juliusmarminge@avocardow@Prgm-code@jakeleventhal@VedankPurohit@twistedgrim@t3dotgg@kridaydave@D3OXY@dmstoykov@HugoVizcainoSantana@EricTsai83@AmoonPod@BunnyGamezsc@olivoil@Fazalkadivar21@maxwellyoung@nateEc@jamesx0416
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

[orchestrator-v2] fix(mobile): Stabilize iOS draft attachments, Hermes sort, and Home - #3923

Closed
mwolson wants to merge 138 commits into
pingdotgg:t3code/codex-turn-mappingfrom
mwolson:fix/ios-v2-attachment-persistence
Closed

[orchestrator-v2] fix(mobile): Stabilize iOS draft attachments, Hermes sort, and Home#3923
mwolson wants to merge 138 commits into
pingdotgg:t3code/codex-turn-mappingfrom
mwolson:fix/ios-v2-attachment-persistence

Conversation

@mwolson

@mwolsonmwolson commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Keep CTM mobile draft image attachments working when they carry both a local id and a dataUrl.
  • Avoid a Hermes fatal in the queue UI by replacing missing Array.prototype.toSorted with a shared copy-sort helper.
  • Hide orchestration-v2 subagent threads from the mobile Home list (forks stay visible).
  • Stabilize Home native-stack options and callbacks so ordinary Home updates do not re-enter navigation through PreventRemoveProvider.
  • Normalize V2 shell active/archive membership from archivedAt so archived threads do not stick on the Home list after a missed archive delta.

Base

This branch is now built on mwolson/t3codev2-base, a merge of the shared iOS/mobile fixes line (ios-fixes-main) into t3code/codex-turn-mapping. Because GitHub diffs against t3code/codex-turn-mapping, the PR diff includes that merge (mobile keyboard/feed fixes, shell reconnect heal, serverConfig/vcsRefs caching, and the V2 thread resume completion marker) in addition to the two commits listed below. Review the two head commits for this PR's own delta.

Problem and Fix

Problem and Why it HappenedFix
CTM drafts can include image attachments with both a local id and a dataUrl. The start-turn path did not treat those dual-tagged attachments as uploads, so order and persistence broke for mobile screenshots.Treat dual-tagged attachments as uploads, strip local-only fields before persistence, and dispatch server IDs while preserving order with already-persisted attachments.
Hermes 250829098 (RN 0.85.3) does not implement Array.prototype.toSorted. CTM queue UI calls it from deriveThreadQueueWorkflowState / ThreadQueueControl, so queuing a reply or finishing a turn can crash with TypeError: undefined is not a function.Add @t3tools/shared/ArraycopySorted ([...values].sort) and use it on mobile-reachable call sites (threadWorkflows, ThreadRelationshipsBanner, use-thread-selection, CTM model.ts).
Orchestration-v2 subagent shells appeared in the mobile Home list, unlike the desktop sidebar.Skip threads with lineage.relationshipToParent === "subagent" when grouping Home rows; keep fork threads.
Unstable Home native-stack options and callbacks re-entered setOptions and could hit maximum update depth through PreventRemoveProvider on CTM device launches.Memoize iOS Home header options (filter menu inputs as deps; handlers via ref) and stabilize Settings / New Task callbacks and title option objects.
A dropped thread.archived shell delta (or a mis-tagged full snapshot) could keep an archived thread listed as active on Home even after the reconnect heal applied a fresh snapshot.Add normalizeShellThreadMembership and apply it to every full snapshot (reducer enrichment refreshes and reconnect heals) so active/archive membership always derives from archivedAt. The HTTP heal, forced socket snapshot, and stale-snapshot rejection it pairs with live in v2-base.

Validation

  • Targeted tests: client-runtime attachment command tests; Home subagent filter tests (including fork negative control); shared Array tests; shell-sync / shellReducer membership tests.
  • vp check (0 errors) and full vp run typecheck on the rebuilt branch.
  • Device: archived threads from a paired CTM environment leave Home after reconnect/heal.
  • Device: Release Hermes com.mwolson.t3code.v2.dev from local orchestrator-v2 integration; queued reply send after active turn finished without crash; Home list usable after nav stability fix.

Notes

Note

Stabilize iOS draft attachments, Hermes array sort, and Home screen for mobile

This is a large orchestrator-v2 stabilization PR with dozens of changes across mobile, web, server, and desktop. Key highlights:

  • iOS draft attachments: persistAttachments now correctly maps upload results back to their source positions and strips client-only fields (id, previewUri) before sending to the server.
  • Hermes sort fix: Replaces Array.prototype.toSorted (unsupported on Hermes) with a shared copySorted utility throughout mobile thread sorting.
  • Home screen (Android): Adds a floating new-task FAB, custom branded header with inline search, and persists collapsed project groups via preferences atoms.
  • Draft hero UX: Web chat view gains a centered composer for empty drafts with animated docking transitions and a DraftHeroHeadline project picker.
  • Thread feed scroll correction: ThreadFeed now auto-corrects scroll position when content underflows the viewport and shows a full-screen loading overlay during hydration.
  • iOS terminal stability: TerminalInputSequence normalizes all return keys to carriage return (\r); autoFocus prop added to control keyboard focus.
  • Shell state synchronization: makeEnvironmentShellState no longer paints cached snapshots immediately; starts in synchronizing and waits for an HTTP heal or authoritative socket snapshot.
  • Thread resume completion marker: Server and client cooperate on a synchronized marker so warm-start clients exit the syncing state faster.
  • Android terminal: Full native terminal canvas (TerminalCanvasView, GhosttyBridge) with JNI bindings, selection, scroll, and theme support.
  • Incoming share flow (iOS/Android): IncomingShareProvider and IncomingShareInbox serialize share ingestion, merge content into composer drafts idempotently, and clean up temporary files.
  • Legal pages: Marketing site gains Privacy Policy, Terms of Service, and Security Policy pages with a shared LegalPage layout component.
  • Risk: IndexedDB schema bumped from v2 to v4; upgrade path adds new object stores but no migration for existing server-config/vcs-refs data (cold start for those caches).

Macroscope summarized 47dc628.


Note

Medium Risk
Touches desktop launcher/signing behavior, auto-update state, and substantial mobile native/Expo configuration; misconfiguration could affect local iOS builds, store screenshots CI, or renderer chrome, but changes are mostly additive with tests on key desktop paths.

Overview
Adds a manual GitHub workflow to capture and validate iOS and Android store showcase screenshots (pnpm screenshots:mobile), upload artifacts, and ignore generated .showcase/ / artifacts/app-store/screenshots/ paths.

Desktop changes improve the macOS dev launcher (branded bundle with a separate launcher executable that execs in-bundle Electron, launcher version bump), context menu positioning scaled by webContents zoom, native fullscreen state exposed to the renderer via IPC/preload, nightly update release notes (setFullChangelog + HTML/markdown normalization into update state), and WSL Node engine validation during probe.

Marketing adds a shared legal document layout, index plus privacy/terms/security pages, footer links, and Grok CLI messaging/assets on the homepage (with minor harness/layout tweaks).

Mobile expands Expo config: repo-root brand assets, Personal Team local iOS builds (optional bundle id, stripped widgets/share/SiWA entitlements), more Android plugins (Gradle heap, predictive back, modern menus/alerts, crash log), DM Sans registered under native PostScript names, and a new Android T3ComposerEditor native view (chips, paste images, theming). iOS markdown shadow node now rebuilds attributed content from current children instead of stale measure-time cache. Composer iOS fonts align to DMSans-Regular / DMSans-Medium.

Also bumps electron-builder, adds minimal root app.json, extends Macroscope Effect service conventions (dependency acquisition / runtime boundaries), and minor asset/doc updates.

Reviewed by Cursor Bugbot for commit 47dc628. Bugbot is set up for automated code reviews on this repo. Configure here.

juliusmarmingeand others added 17 commits July 7, 2026 15:55
…gg#3781)
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
…pingdotgg#3795)
Co-authored-by: Julius Marminge <julius@mac.lan>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
…tgg#3823)
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: Horus Lugo <horusgoul@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: maria-rcks <maria@kuuro.net>
Co-authored-by: Shivam Sharma <91240327+shivamhwp@users.noreply.github.com>
Co-authored-by: Ben Davis <45952064+bmdavis419@users.noreply.github.com>
Co-authored-by: Alex <me@pixp.cc>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: Julius Marminge <julius@mac.lan>
Co-authored-by: codex <codex@users.noreply.github.com>
@coderabbitai

coderabbitaiBot commented Jul 12, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 8bbf5543-c8a1-4f1c-8bfe-1d903c77b419

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Jul 12, 2026
Comment threadapps/mobile/src/features/home/HomeHeader.tsx
@mwolson
mwolson marked this pull request as ready for review July 12, 2026 21:35
Comment threadpackages/shared/src/Array.ts Outdated
@macroscopeapp

macroscopeappBot commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

25 blocking correctness issues found. Diff is too large for automated approval analysis. A human reviewer should evaluate this PR.

You can customize Macroscope's approvability policy. Learn more.

@mwolson
mwolsonforce-pushed the fix/ios-v2-attachment-persistence branch from 2857eb3 to 76a88a0CompareJuly 12, 2026 21:41
@mwolsonmwolson changed the title fix(mobile): Stabilize CTM iOS draft attachments, Hermes sort, and Home[orchestrator-v2] fix(mobile): Stabilize CTM iOS draft attachments, Hermes sort, and HomeJul 12, 2026
Capture RCTFatal message and stack to Documents via a native handler so
Release Hermes aborts leave last-crash.json without a device console.
Harden the JS ErrorUtils path with a minimal write-first record, durable
fsync writes, breadcrumb max-wait flush, and an Expo AppDelegate plugin.
Skip NativeStackScreenOptions setOptions when content is unchanged so
Thread catch-up re-renders do not loop through PreventRemoveProvider and
hit maximum update depth.
CI Mobile Native Static Analysis failed on a multi-line if where the
opening brace was on the following line.
Completes the pingdotgg#4055 port in the v2-base merge: draft routes carry a
pre-allocated thread id, and the conditional subscription blocked
promotion to live shell data until remount. Flagged by Grok review.

@cursorcursorBot left a comment

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.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

There are 4 total unresolved issues (including 3 from previous reviews).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 47dc628. Configure here.


Function("markShowcaseReady") { (scene: String) in
let readyPath = NSHomeDirectory() + "/Library/Caches/T3ShowcaseReadyScene"
try? scene.write(toFile: readyPath, atomically: true, encoding: .utf8)

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.

Crash breadcrumb fsync path removed

Medium Severity

The writeSyncText function, which provided durable last-chance crash log writes, was removed from T3NativeControlsModule. This breaks the breadcrumbPersist mechanism, which still expects this native fsync path. As a result, last-minute breadcrumbs may be lost during iOS fatals, impacting crash diagnostics.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 47dc628. Configure here.

@mwolson

Copy link
Copy Markdown
ContributorAuthor

Closing for now; may reattempt later after the iOS fixes have landed on main, and have been backmerged to codex-turn-mapping.

@mwolsonmwolson closed this Jul 20, 2026
juliusmarminge added a commit that referenced this pull request Jul 20, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
maria-rcks pushed a commit that referenced this pull request Aug 3, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 4, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 4, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 5, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 7, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 10, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 11, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 12, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 14, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 14, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 15, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 17, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 28, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 28, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 28, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 29, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 29, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 29, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 29, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 30, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 30, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Sep 1, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Sep 2, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

20 participants

@mwolson@juliusmarminge@avocardow@Prgm-code@jakeleventhal@VedankPurohit@twistedgrim@t3dotgg@kridaydave@D3OXY@dmstoykov@HugoVizcainoSantana@EricTsai83@AmoonPod@BunnyGamezsc@olivoil@Fazalkadivar21@maxwellyoung@nateEc@jamesx0416
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

[orchestrator-v2] fix(mobile): Stabilize iOS draft attachments, Hermes sort, and Home - #3923

Closed
mwolson wants to merge 138 commits into
pingdotgg:t3code/codex-turn-mappingfrom
mwolson:fix/ios-v2-attachment-persistence
Closed

[orchestrator-v2] fix(mobile): Stabilize iOS draft attachments, Hermes sort, and Home#3923
mwolson wants to merge 138 commits into
pingdotgg:t3code/codex-turn-mappingfrom
mwolson:fix/ios-v2-attachment-persistence

Conversation

@mwolson

@mwolsonmwolson commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Keep CTM mobile draft image attachments working when they carry both a local id and a dataUrl.
  • Avoid a Hermes fatal in the queue UI by replacing missing Array.prototype.toSorted with a shared copy-sort helper.
  • Hide orchestration-v2 subagent threads from the mobile Home list (forks stay visible).
  • Stabilize Home native-stack options and callbacks so ordinary Home updates do not re-enter navigation through PreventRemoveProvider.
  • Normalize V2 shell active/archive membership from archivedAt so archived threads do not stick on the Home list after a missed archive delta.

Base

This branch is now built on mwolson/t3codev2-base, a merge of the shared iOS/mobile fixes line (ios-fixes-main) into t3code/codex-turn-mapping. Because GitHub diffs against t3code/codex-turn-mapping, the PR diff includes that merge (mobile keyboard/feed fixes, shell reconnect heal, serverConfig/vcsRefs caching, and the V2 thread resume completion marker) in addition to the two commits listed below. Review the two head commits for this PR's own delta.

Problem and Fix

Problem and Why it HappenedFix
CTM drafts can include image attachments with both a local id and a dataUrl. The start-turn path did not treat those dual-tagged attachments as uploads, so order and persistence broke for mobile screenshots.Treat dual-tagged attachments as uploads, strip local-only fields before persistence, and dispatch server IDs while preserving order with already-persisted attachments.
Hermes 250829098 (RN 0.85.3) does not implement Array.prototype.toSorted. CTM queue UI calls it from deriveThreadQueueWorkflowState / ThreadQueueControl, so queuing a reply or finishing a turn can crash with TypeError: undefined is not a function.Add @t3tools/shared/ArraycopySorted ([...values].sort) and use it on mobile-reachable call sites (threadWorkflows, ThreadRelationshipsBanner, use-thread-selection, CTM model.ts).
Orchestration-v2 subagent shells appeared in the mobile Home list, unlike the desktop sidebar.Skip threads with lineage.relationshipToParent === "subagent" when grouping Home rows; keep fork threads.
Unstable Home native-stack options and callbacks re-entered setOptions and could hit maximum update depth through PreventRemoveProvider on CTM device launches.Memoize iOS Home header options (filter menu inputs as deps; handlers via ref) and stabilize Settings / New Task callbacks and title option objects.
A dropped thread.archived shell delta (or a mis-tagged full snapshot) could keep an archived thread listed as active on Home even after the reconnect heal applied a fresh snapshot.Add normalizeShellThreadMembership and apply it to every full snapshot (reducer enrichment refreshes and reconnect heals) so active/archive membership always derives from archivedAt. The HTTP heal, forced socket snapshot, and stale-snapshot rejection it pairs with live in v2-base.

Validation

  • Targeted tests: client-runtime attachment command tests; Home subagent filter tests (including fork negative control); shared Array tests; shell-sync / shellReducer membership tests.
  • vp check (0 errors) and full vp run typecheck on the rebuilt branch.
  • Device: archived threads from a paired CTM environment leave Home after reconnect/heal.
  • Device: Release Hermes com.mwolson.t3code.v2.dev from local orchestrator-v2 integration; queued reply send after active turn finished without crash; Home list usable after nav stability fix.

Notes

Note

Stabilize iOS draft attachments, Hermes array sort, and Home screen for mobile

This is a large orchestrator-v2 stabilization PR with dozens of changes across mobile, web, server, and desktop. Key highlights:

  • iOS draft attachments: persistAttachments now correctly maps upload results back to their source positions and strips client-only fields (id, previewUri) before sending to the server.
  • Hermes sort fix: Replaces Array.prototype.toSorted (unsupported on Hermes) with a shared copySorted utility throughout mobile thread sorting.
  • Home screen (Android): Adds a floating new-task FAB, custom branded header with inline search, and persists collapsed project groups via preferences atoms.
  • Draft hero UX: Web chat view gains a centered composer for empty drafts with animated docking transitions and a DraftHeroHeadline project picker.
  • Thread feed scroll correction: ThreadFeed now auto-corrects scroll position when content underflows the viewport and shows a full-screen loading overlay during hydration.
  • iOS terminal stability: TerminalInputSequence normalizes all return keys to carriage return (\r); autoFocus prop added to control keyboard focus.
  • Shell state synchronization: makeEnvironmentShellState no longer paints cached snapshots immediately; starts in synchronizing and waits for an HTTP heal or authoritative socket snapshot.
  • Thread resume completion marker: Server and client cooperate on a synchronized marker so warm-start clients exit the syncing state faster.
  • Android terminal: Full native terminal canvas (TerminalCanvasView, GhosttyBridge) with JNI bindings, selection, scroll, and theme support.
  • Incoming share flow (iOS/Android): IncomingShareProvider and IncomingShareInbox serialize share ingestion, merge content into composer drafts idempotently, and clean up temporary files.
  • Legal pages: Marketing site gains Privacy Policy, Terms of Service, and Security Policy pages with a shared LegalPage layout component.
  • Risk: IndexedDB schema bumped from v2 to v4; upgrade path adds new object stores but no migration for existing server-config/vcs-refs data (cold start for those caches).

Macroscope summarized 47dc628.


Note

Medium Risk
Touches desktop launcher/signing behavior, auto-update state, and substantial mobile native/Expo configuration; misconfiguration could affect local iOS builds, store screenshots CI, or renderer chrome, but changes are mostly additive with tests on key desktop paths.

Overview
Adds a manual GitHub workflow to capture and validate iOS and Android store showcase screenshots (pnpm screenshots:mobile), upload artifacts, and ignore generated .showcase/ / artifacts/app-store/screenshots/ paths.

Desktop changes improve the macOS dev launcher (branded bundle with a separate launcher executable that execs in-bundle Electron, launcher version bump), context menu positioning scaled by webContents zoom, native fullscreen state exposed to the renderer via IPC/preload, nightly update release notes (setFullChangelog + HTML/markdown normalization into update state), and WSL Node engine validation during probe.

Marketing adds a shared legal document layout, index plus privacy/terms/security pages, footer links, and Grok CLI messaging/assets on the homepage (with minor harness/layout tweaks).

Mobile expands Expo config: repo-root brand assets, Personal Team local iOS builds (optional bundle id, stripped widgets/share/SiWA entitlements), more Android plugins (Gradle heap, predictive back, modern menus/alerts, crash log), DM Sans registered under native PostScript names, and a new Android T3ComposerEditor native view (chips, paste images, theming). iOS markdown shadow node now rebuilds attributed content from current children instead of stale measure-time cache. Composer iOS fonts align to DMSans-Regular / DMSans-Medium.

Also bumps electron-builder, adds minimal root app.json, extends Macroscope Effect service conventions (dependency acquisition / runtime boundaries), and minor asset/doc updates.

Reviewed by Cursor Bugbot for commit 47dc628. Bugbot is set up for automated code reviews on this repo. Configure here.

juliusmarmingeand others added 17 commits July 7, 2026 15:55
…gg#3781)
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
…pingdotgg#3795)
Co-authored-by: Julius Marminge <julius@mac.lan>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
…tgg#3823)
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: Horus Lugo <horusgoul@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: maria-rcks <maria@kuuro.net>
Co-authored-by: Shivam Sharma <91240327+shivamhwp@users.noreply.github.com>
Co-authored-by: Ben Davis <45952064+bmdavis419@users.noreply.github.com>
Co-authored-by: Alex <me@pixp.cc>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: Julius Marminge <julius@mac.lan>
Co-authored-by: codex <codex@users.noreply.github.com>
@coderabbitai

coderabbitaiBot commented Jul 12, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 8bbf5543-c8a1-4f1c-8bfe-1d903c77b419

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Jul 12, 2026
Comment threadapps/mobile/src/features/home/HomeHeader.tsx
@mwolson
mwolson marked this pull request as ready for review July 12, 2026 21:35
Comment threadpackages/shared/src/Array.ts Outdated
@macroscopeapp

macroscopeappBot commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

25 blocking correctness issues found. Diff is too large for automated approval analysis. A human reviewer should evaluate this PR.

You can customize Macroscope's approvability policy. Learn more.

@mwolson
mwolsonforce-pushed the fix/ios-v2-attachment-persistence branch from 2857eb3 to 76a88a0CompareJuly 12, 2026 21:41
@mwolsonmwolson changed the title fix(mobile): Stabilize CTM iOS draft attachments, Hermes sort, and Home[orchestrator-v2] fix(mobile): Stabilize CTM iOS draft attachments, Hermes sort, and HomeJul 12, 2026
Capture RCTFatal message and stack to Documents via a native handler so
Release Hermes aborts leave last-crash.json without a device console.
Harden the JS ErrorUtils path with a minimal write-first record, durable
fsync writes, breadcrumb max-wait flush, and an Expo AppDelegate plugin.
Skip NativeStackScreenOptions setOptions when content is unchanged so
Thread catch-up re-renders do not loop through PreventRemoveProvider and
hit maximum update depth.
CI Mobile Native Static Analysis failed on a multi-line if where the
opening brace was on the following line.
Completes the pingdotgg#4055 port in the v2-base merge: draft routes carry a
pre-allocated thread id, and the conditional subscription blocked
promotion to live shell data until remount. Flagged by Grok review.

@cursorcursorBot left a comment

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.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

There are 4 total unresolved issues (including 3 from previous reviews).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 47dc628. Configure here.


Function("markShowcaseReady") { (scene: String) in
let readyPath = NSHomeDirectory() + "/Library/Caches/T3ShowcaseReadyScene"
try? scene.write(toFile: readyPath, atomically: true, encoding: .utf8)

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.

Crash breadcrumb fsync path removed

Medium Severity

The writeSyncText function, which provided durable last-chance crash log writes, was removed from T3NativeControlsModule. This breaks the breadcrumbPersist mechanism, which still expects this native fsync path. As a result, last-minute breadcrumbs may be lost during iOS fatals, impacting crash diagnostics.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 47dc628. Configure here.

@mwolson

Copy link
Copy Markdown
ContributorAuthor

Closing for now; may reattempt later after the iOS fixes have landed on main, and have been backmerged to codex-turn-mapping.

@mwolsonmwolson closed this Jul 20, 2026
juliusmarminge added a commit that referenced this pull request Jul 20, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
maria-rcks pushed a commit that referenced this pull request Aug 3, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 4, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 4, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 5, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 7, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 10, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 11, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 12, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 14, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 14, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 15, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 17, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 28, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 28, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 28, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 29, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 29, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 29, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 29, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 30, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 30, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Sep 1, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Sep 2, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

20 participants

@mwolson@juliusmarminge@avocardow@Prgm-code@jakeleventhal@VedankPurohit@twistedgrim@t3dotgg@kridaydave@D3OXY@dmstoykov@HugoVizcainoSantana@EricTsai83@AmoonPod@BunnyGamezsc@olivoil@Fazalkadivar21@maxwellyoung@nateEc@jamesx0416
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

[orchestrator-v2] fix(mobile): Stabilize iOS draft attachments, Hermes sort, and Home - #3923

Closed
mwolson wants to merge 138 commits into
pingdotgg:t3code/codex-turn-mappingfrom
mwolson:fix/ios-v2-attachment-persistence
Closed

[orchestrator-v2] fix(mobile): Stabilize iOS draft attachments, Hermes sort, and Home#3923
mwolson wants to merge 138 commits into
pingdotgg:t3code/codex-turn-mappingfrom
mwolson:fix/ios-v2-attachment-persistence

Conversation

@mwolson

@mwolsonmwolson commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Keep CTM mobile draft image attachments working when they carry both a local id and a dataUrl.
  • Avoid a Hermes fatal in the queue UI by replacing missing Array.prototype.toSorted with a shared copy-sort helper.
  • Hide orchestration-v2 subagent threads from the mobile Home list (forks stay visible).
  • Stabilize Home native-stack options and callbacks so ordinary Home updates do not re-enter navigation through PreventRemoveProvider.
  • Normalize V2 shell active/archive membership from archivedAt so archived threads do not stick on the Home list after a missed archive delta.

Base

This branch is now built on mwolson/t3codev2-base, a merge of the shared iOS/mobile fixes line (ios-fixes-main) into t3code/codex-turn-mapping. Because GitHub diffs against t3code/codex-turn-mapping, the PR diff includes that merge (mobile keyboard/feed fixes, shell reconnect heal, serverConfig/vcsRefs caching, and the V2 thread resume completion marker) in addition to the two commits listed below. Review the two head commits for this PR's own delta.

Problem and Fix

Problem and Why it HappenedFix
CTM drafts can include image attachments with both a local id and a dataUrl. The start-turn path did not treat those dual-tagged attachments as uploads, so order and persistence broke for mobile screenshots.Treat dual-tagged attachments as uploads, strip local-only fields before persistence, and dispatch server IDs while preserving order with already-persisted attachments.
Hermes 250829098 (RN 0.85.3) does not implement Array.prototype.toSorted. CTM queue UI calls it from deriveThreadQueueWorkflowState / ThreadQueueControl, so queuing a reply or finishing a turn can crash with TypeError: undefined is not a function.Add @t3tools/shared/ArraycopySorted ([...values].sort) and use it on mobile-reachable call sites (threadWorkflows, ThreadRelationshipsBanner, use-thread-selection, CTM model.ts).
Orchestration-v2 subagent shells appeared in the mobile Home list, unlike the desktop sidebar.Skip threads with lineage.relationshipToParent === "subagent" when grouping Home rows; keep fork threads.
Unstable Home native-stack options and callbacks re-entered setOptions and could hit maximum update depth through PreventRemoveProvider on CTM device launches.Memoize iOS Home header options (filter menu inputs as deps; handlers via ref) and stabilize Settings / New Task callbacks and title option objects.
A dropped thread.archived shell delta (or a mis-tagged full snapshot) could keep an archived thread listed as active on Home even after the reconnect heal applied a fresh snapshot.Add normalizeShellThreadMembership and apply it to every full snapshot (reducer enrichment refreshes and reconnect heals) so active/archive membership always derives from archivedAt. The HTTP heal, forced socket snapshot, and stale-snapshot rejection it pairs with live in v2-base.

Validation

  • Targeted tests: client-runtime attachment command tests; Home subagent filter tests (including fork negative control); shared Array tests; shell-sync / shellReducer membership tests.
  • vp check (0 errors) and full vp run typecheck on the rebuilt branch.
  • Device: archived threads from a paired CTM environment leave Home after reconnect/heal.
  • Device: Release Hermes com.mwolson.t3code.v2.dev from local orchestrator-v2 integration; queued reply send after active turn finished without crash; Home list usable after nav stability fix.

Notes

Note

Stabilize iOS draft attachments, Hermes array sort, and Home screen for mobile

This is a large orchestrator-v2 stabilization PR with dozens of changes across mobile, web, server, and desktop. Key highlights:

  • iOS draft attachments: persistAttachments now correctly maps upload results back to their source positions and strips client-only fields (id, previewUri) before sending to the server.
  • Hermes sort fix: Replaces Array.prototype.toSorted (unsupported on Hermes) with a shared copySorted utility throughout mobile thread sorting.
  • Home screen (Android): Adds a floating new-task FAB, custom branded header with inline search, and persists collapsed project groups via preferences atoms.
  • Draft hero UX: Web chat view gains a centered composer for empty drafts with animated docking transitions and a DraftHeroHeadline project picker.
  • Thread feed scroll correction: ThreadFeed now auto-corrects scroll position when content underflows the viewport and shows a full-screen loading overlay during hydration.
  • iOS terminal stability: TerminalInputSequence normalizes all return keys to carriage return (\r); autoFocus prop added to control keyboard focus.
  • Shell state synchronization: makeEnvironmentShellState no longer paints cached snapshots immediately; starts in synchronizing and waits for an HTTP heal or authoritative socket snapshot.
  • Thread resume completion marker: Server and client cooperate on a synchronized marker so warm-start clients exit the syncing state faster.
  • Android terminal: Full native terminal canvas (TerminalCanvasView, GhosttyBridge) with JNI bindings, selection, scroll, and theme support.
  • Incoming share flow (iOS/Android): IncomingShareProvider and IncomingShareInbox serialize share ingestion, merge content into composer drafts idempotently, and clean up temporary files.
  • Legal pages: Marketing site gains Privacy Policy, Terms of Service, and Security Policy pages with a shared LegalPage layout component.
  • Risk: IndexedDB schema bumped from v2 to v4; upgrade path adds new object stores but no migration for existing server-config/vcs-refs data (cold start for those caches).

Macroscope summarized 47dc628.


Note

Medium Risk
Touches desktop launcher/signing behavior, auto-update state, and substantial mobile native/Expo configuration; misconfiguration could affect local iOS builds, store screenshots CI, or renderer chrome, but changes are mostly additive with tests on key desktop paths.

Overview
Adds a manual GitHub workflow to capture and validate iOS and Android store showcase screenshots (pnpm screenshots:mobile), upload artifacts, and ignore generated .showcase/ / artifacts/app-store/screenshots/ paths.

Desktop changes improve the macOS dev launcher (branded bundle with a separate launcher executable that execs in-bundle Electron, launcher version bump), context menu positioning scaled by webContents zoom, native fullscreen state exposed to the renderer via IPC/preload, nightly update release notes (setFullChangelog + HTML/markdown normalization into update state), and WSL Node engine validation during probe.

Marketing adds a shared legal document layout, index plus privacy/terms/security pages, footer links, and Grok CLI messaging/assets on the homepage (with minor harness/layout tweaks).

Mobile expands Expo config: repo-root brand assets, Personal Team local iOS builds (optional bundle id, stripped widgets/share/SiWA entitlements), more Android plugins (Gradle heap, predictive back, modern menus/alerts, crash log), DM Sans registered under native PostScript names, and a new Android T3ComposerEditor native view (chips, paste images, theming). iOS markdown shadow node now rebuilds attributed content from current children instead of stale measure-time cache. Composer iOS fonts align to DMSans-Regular / DMSans-Medium.

Also bumps electron-builder, adds minimal root app.json, extends Macroscope Effect service conventions (dependency acquisition / runtime boundaries), and minor asset/doc updates.

Reviewed by Cursor Bugbot for commit 47dc628. Bugbot is set up for automated code reviews on this repo. Configure here.

juliusmarmingeand others added 17 commits July 7, 2026 15:55
…gg#3781)
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
…pingdotgg#3795)
Co-authored-by: Julius Marminge <julius@mac.lan>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
…tgg#3823)
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: Horus Lugo <horusgoul@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: maria-rcks <maria@kuuro.net>
Co-authored-by: Shivam Sharma <91240327+shivamhwp@users.noreply.github.com>
Co-authored-by: Ben Davis <45952064+bmdavis419@users.noreply.github.com>
Co-authored-by: Alex <me@pixp.cc>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: Julius Marminge <julius@mac.lan>
Co-authored-by: codex <codex@users.noreply.github.com>
@coderabbitai

coderabbitaiBot commented Jul 12, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 8bbf5543-c8a1-4f1c-8bfe-1d903c77b419

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Jul 12, 2026
Comment threadapps/mobile/src/features/home/HomeHeader.tsx
@mwolson
mwolson marked this pull request as ready for review July 12, 2026 21:35
Comment threadpackages/shared/src/Array.ts Outdated
@macroscopeapp

macroscopeappBot commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

25 blocking correctness issues found. Diff is too large for automated approval analysis. A human reviewer should evaluate this PR.

You can customize Macroscope's approvability policy. Learn more.

@mwolson
mwolsonforce-pushed the fix/ios-v2-attachment-persistence branch from 2857eb3 to 76a88a0CompareJuly 12, 2026 21:41
@mwolsonmwolson changed the title fix(mobile): Stabilize CTM iOS draft attachments, Hermes sort, and Home[orchestrator-v2] fix(mobile): Stabilize CTM iOS draft attachments, Hermes sort, and HomeJul 12, 2026
Capture RCTFatal message and stack to Documents via a native handler so
Release Hermes aborts leave last-crash.json without a device console.
Harden the JS ErrorUtils path with a minimal write-first record, durable
fsync writes, breadcrumb max-wait flush, and an Expo AppDelegate plugin.
Skip NativeStackScreenOptions setOptions when content is unchanged so
Thread catch-up re-renders do not loop through PreventRemoveProvider and
hit maximum update depth.
CI Mobile Native Static Analysis failed on a multi-line if where the
opening brace was on the following line.
Completes the pingdotgg#4055 port in the v2-base merge: draft routes carry a
pre-allocated thread id, and the conditional subscription blocked
promotion to live shell data until remount. Flagged by Grok review.

@cursorcursorBot left a comment

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.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

There are 4 total unresolved issues (including 3 from previous reviews).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 47dc628. Configure here.


Function("markShowcaseReady") { (scene: String) in
let readyPath = NSHomeDirectory() + "/Library/Caches/T3ShowcaseReadyScene"
try? scene.write(toFile: readyPath, atomically: true, encoding: .utf8)

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.

Crash breadcrumb fsync path removed

Medium Severity

The writeSyncText function, which provided durable last-chance crash log writes, was removed from T3NativeControlsModule. This breaks the breadcrumbPersist mechanism, which still expects this native fsync path. As a result, last-minute breadcrumbs may be lost during iOS fatals, impacting crash diagnostics.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 47dc628. Configure here.

@mwolson

Copy link
Copy Markdown
ContributorAuthor

Closing for now; may reattempt later after the iOS fixes have landed on main, and have been backmerged to codex-turn-mapping.

@mwolsonmwolson closed this Jul 20, 2026
juliusmarminge added a commit that referenced this pull request Jul 20, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
maria-rcks pushed a commit that referenced this pull request Aug 3, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 4, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 4, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 5, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 7, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 10, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 11, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 12, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 14, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 14, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 15, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 17, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 28, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 28, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 28, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 29, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 29, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 29, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 29, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 30, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 30, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Sep 1, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Sep 2, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

20 participants

@mwolson@juliusmarminge@avocardow@Prgm-code@jakeleventhal@VedankPurohit@twistedgrim@t3dotgg@kridaydave@D3OXY@dmstoykov@HugoVizcainoSantana@EricTsai83@AmoonPod@BunnyGamezsc@olivoil@Fazalkadivar21@maxwellyoung@nateEc@jamesx0416
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

[orchestrator-v2] fix(mobile): Stabilize iOS draft attachments, Hermes sort, and Home - #3923

Closed
mwolson wants to merge 138 commits into
pingdotgg:t3code/codex-turn-mappingfrom
mwolson:fix/ios-v2-attachment-persistence
Closed

[orchestrator-v2] fix(mobile): Stabilize iOS draft attachments, Hermes sort, and Home#3923
mwolson wants to merge 138 commits into
pingdotgg:t3code/codex-turn-mappingfrom
mwolson:fix/ios-v2-attachment-persistence

Conversation

@mwolson

@mwolsonmwolson commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Keep CTM mobile draft image attachments working when they carry both a local id and a dataUrl.
  • Avoid a Hermes fatal in the queue UI by replacing missing Array.prototype.toSorted with a shared copy-sort helper.
  • Hide orchestration-v2 subagent threads from the mobile Home list (forks stay visible).
  • Stabilize Home native-stack options and callbacks so ordinary Home updates do not re-enter navigation through PreventRemoveProvider.
  • Normalize V2 shell active/archive membership from archivedAt so archived threads do not stick on the Home list after a missed archive delta.

Base

This branch is now built on mwolson/t3codev2-base, a merge of the shared iOS/mobile fixes line (ios-fixes-main) into t3code/codex-turn-mapping. Because GitHub diffs against t3code/codex-turn-mapping, the PR diff includes that merge (mobile keyboard/feed fixes, shell reconnect heal, serverConfig/vcsRefs caching, and the V2 thread resume completion marker) in addition to the two commits listed below. Review the two head commits for this PR's own delta.

Problem and Fix

Problem and Why it HappenedFix
CTM drafts can include image attachments with both a local id and a dataUrl. The start-turn path did not treat those dual-tagged attachments as uploads, so order and persistence broke for mobile screenshots.Treat dual-tagged attachments as uploads, strip local-only fields before persistence, and dispatch server IDs while preserving order with already-persisted attachments.
Hermes 250829098 (RN 0.85.3) does not implement Array.prototype.toSorted. CTM queue UI calls it from deriveThreadQueueWorkflowState / ThreadQueueControl, so queuing a reply or finishing a turn can crash with TypeError: undefined is not a function.Add @t3tools/shared/ArraycopySorted ([...values].sort) and use it on mobile-reachable call sites (threadWorkflows, ThreadRelationshipsBanner, use-thread-selection, CTM model.ts).
Orchestration-v2 subagent shells appeared in the mobile Home list, unlike the desktop sidebar.Skip threads with lineage.relationshipToParent === "subagent" when grouping Home rows; keep fork threads.
Unstable Home native-stack options and callbacks re-entered setOptions and could hit maximum update depth through PreventRemoveProvider on CTM device launches.Memoize iOS Home header options (filter menu inputs as deps; handlers via ref) and stabilize Settings / New Task callbacks and title option objects.
A dropped thread.archived shell delta (or a mis-tagged full snapshot) could keep an archived thread listed as active on Home even after the reconnect heal applied a fresh snapshot.Add normalizeShellThreadMembership and apply it to every full snapshot (reducer enrichment refreshes and reconnect heals) so active/archive membership always derives from archivedAt. The HTTP heal, forced socket snapshot, and stale-snapshot rejection it pairs with live in v2-base.

Validation

  • Targeted tests: client-runtime attachment command tests; Home subagent filter tests (including fork negative control); shared Array tests; shell-sync / shellReducer membership tests.
  • vp check (0 errors) and full vp run typecheck on the rebuilt branch.
  • Device: archived threads from a paired CTM environment leave Home after reconnect/heal.
  • Device: Release Hermes com.mwolson.t3code.v2.dev from local orchestrator-v2 integration; queued reply send after active turn finished without crash; Home list usable after nav stability fix.

Notes

Note

Stabilize iOS draft attachments, Hermes array sort, and Home screen for mobile

This is a large orchestrator-v2 stabilization PR with dozens of changes across mobile, web, server, and desktop. Key highlights:

  • iOS draft attachments: persistAttachments now correctly maps upload results back to their source positions and strips client-only fields (id, previewUri) before sending to the server.
  • Hermes sort fix: Replaces Array.prototype.toSorted (unsupported on Hermes) with a shared copySorted utility throughout mobile thread sorting.
  • Home screen (Android): Adds a floating new-task FAB, custom branded header with inline search, and persists collapsed project groups via preferences atoms.
  • Draft hero UX: Web chat view gains a centered composer for empty drafts with animated docking transitions and a DraftHeroHeadline project picker.
  • Thread feed scroll correction: ThreadFeed now auto-corrects scroll position when content underflows the viewport and shows a full-screen loading overlay during hydration.
  • iOS terminal stability: TerminalInputSequence normalizes all return keys to carriage return (\r); autoFocus prop added to control keyboard focus.
  • Shell state synchronization: makeEnvironmentShellState no longer paints cached snapshots immediately; starts in synchronizing and waits for an HTTP heal or authoritative socket snapshot.
  • Thread resume completion marker: Server and client cooperate on a synchronized marker so warm-start clients exit the syncing state faster.
  • Android terminal: Full native terminal canvas (TerminalCanvasView, GhosttyBridge) with JNI bindings, selection, scroll, and theme support.
  • Incoming share flow (iOS/Android): IncomingShareProvider and IncomingShareInbox serialize share ingestion, merge content into composer drafts idempotently, and clean up temporary files.
  • Legal pages: Marketing site gains Privacy Policy, Terms of Service, and Security Policy pages with a shared LegalPage layout component.
  • Risk: IndexedDB schema bumped from v2 to v4; upgrade path adds new object stores but no migration for existing server-config/vcs-refs data (cold start for those caches).

Macroscope summarized 47dc628.


Note

Medium Risk
Touches desktop launcher/signing behavior, auto-update state, and substantial mobile native/Expo configuration; misconfiguration could affect local iOS builds, store screenshots CI, or renderer chrome, but changes are mostly additive with tests on key desktop paths.

Overview
Adds a manual GitHub workflow to capture and validate iOS and Android store showcase screenshots (pnpm screenshots:mobile), upload artifacts, and ignore generated .showcase/ / artifacts/app-store/screenshots/ paths.

Desktop changes improve the macOS dev launcher (branded bundle with a separate launcher executable that execs in-bundle Electron, launcher version bump), context menu positioning scaled by webContents zoom, native fullscreen state exposed to the renderer via IPC/preload, nightly update release notes (setFullChangelog + HTML/markdown normalization into update state), and WSL Node engine validation during probe.

Marketing adds a shared legal document layout, index plus privacy/terms/security pages, footer links, and Grok CLI messaging/assets on the homepage (with minor harness/layout tweaks).

Mobile expands Expo config: repo-root brand assets, Personal Team local iOS builds (optional bundle id, stripped widgets/share/SiWA entitlements), more Android plugins (Gradle heap, predictive back, modern menus/alerts, crash log), DM Sans registered under native PostScript names, and a new Android T3ComposerEditor native view (chips, paste images, theming). iOS markdown shadow node now rebuilds attributed content from current children instead of stale measure-time cache. Composer iOS fonts align to DMSans-Regular / DMSans-Medium.

Also bumps electron-builder, adds minimal root app.json, extends Macroscope Effect service conventions (dependency acquisition / runtime boundaries), and minor asset/doc updates.

Reviewed by Cursor Bugbot for commit 47dc628. Bugbot is set up for automated code reviews on this repo. Configure here.

juliusmarmingeand others added 17 commits July 7, 2026 15:55
…gg#3781)
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
…pingdotgg#3795)
Co-authored-by: Julius Marminge <julius@mac.lan>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
…tgg#3823)
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: Horus Lugo <horusgoul@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: maria-rcks <maria@kuuro.net>
Co-authored-by: Shivam Sharma <91240327+shivamhwp@users.noreply.github.com>
Co-authored-by: Ben Davis <45952064+bmdavis419@users.noreply.github.com>
Co-authored-by: Alex <me@pixp.cc>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: Julius Marminge <julius@mac.lan>
Co-authored-by: codex <codex@users.noreply.github.com>
@coderabbitai

coderabbitaiBot commented Jul 12, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 8bbf5543-c8a1-4f1c-8bfe-1d903c77b419

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Jul 12, 2026
Comment threadapps/mobile/src/features/home/HomeHeader.tsx
@mwolson
mwolson marked this pull request as ready for review July 12, 2026 21:35
Comment threadpackages/shared/src/Array.ts Outdated
@macroscopeapp

macroscopeappBot commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

25 blocking correctness issues found. Diff is too large for automated approval analysis. A human reviewer should evaluate this PR.

You can customize Macroscope's approvability policy. Learn more.

@mwolson
mwolsonforce-pushed the fix/ios-v2-attachment-persistence branch from 2857eb3 to 76a88a0CompareJuly 12, 2026 21:41
@mwolsonmwolson changed the title fix(mobile): Stabilize CTM iOS draft attachments, Hermes sort, and Home[orchestrator-v2] fix(mobile): Stabilize CTM iOS draft attachments, Hermes sort, and HomeJul 12, 2026
Capture RCTFatal message and stack to Documents via a native handler so
Release Hermes aborts leave last-crash.json without a device console.
Harden the JS ErrorUtils path with a minimal write-first record, durable
fsync writes, breadcrumb max-wait flush, and an Expo AppDelegate plugin.
Skip NativeStackScreenOptions setOptions when content is unchanged so
Thread catch-up re-renders do not loop through PreventRemoveProvider and
hit maximum update depth.
CI Mobile Native Static Analysis failed on a multi-line if where the
opening brace was on the following line.
Completes the pingdotgg#4055 port in the v2-base merge: draft routes carry a
pre-allocated thread id, and the conditional subscription blocked
promotion to live shell data until remount. Flagged by Grok review.

@cursorcursorBot left a comment

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.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

There are 4 total unresolved issues (including 3 from previous reviews).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 47dc628. Configure here.


Function("markShowcaseReady") { (scene: String) in
let readyPath = NSHomeDirectory() + "/Library/Caches/T3ShowcaseReadyScene"
try? scene.write(toFile: readyPath, atomically: true, encoding: .utf8)

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.

Crash breadcrumb fsync path removed

Medium Severity

The writeSyncText function, which provided durable last-chance crash log writes, was removed from T3NativeControlsModule. This breaks the breadcrumbPersist mechanism, which still expects this native fsync path. As a result, last-minute breadcrumbs may be lost during iOS fatals, impacting crash diagnostics.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 47dc628. Configure here.

@mwolson

Copy link
Copy Markdown
ContributorAuthor

Closing for now; may reattempt later after the iOS fixes have landed on main, and have been backmerged to codex-turn-mapping.

@mwolsonmwolson closed this Jul 20, 2026
juliusmarminge added a commit that referenced this pull request Jul 20, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
maria-rcks pushed a commit that referenced this pull request Aug 3, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 4, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 4, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 5, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 7, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 10, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 11, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 12, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 14, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 14, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 15, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 17, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 28, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 28, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 28, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 29, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 29, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 29, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 29, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 30, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 30, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Sep 1, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Sep 2, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

20 participants

@mwolson@juliusmarminge@avocardow@Prgm-code@jakeleventhal@VedankPurohit@twistedgrim@t3dotgg@kridaydave@D3OXY@dmstoykov@HugoVizcainoSantana@EricTsai83@AmoonPod@BunnyGamezsc@olivoil@Fazalkadivar21@maxwellyoung@nateEc@jamesx0416
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

[orchestrator-v2] fix(mobile): Stabilize iOS draft attachments, Hermes sort, and Home - #3923

Closed
mwolson wants to merge 138 commits into
pingdotgg:t3code/codex-turn-mappingfrom
mwolson:fix/ios-v2-attachment-persistence
Closed

[orchestrator-v2] fix(mobile): Stabilize iOS draft attachments, Hermes sort, and Home#3923
mwolson wants to merge 138 commits into
pingdotgg:t3code/codex-turn-mappingfrom
mwolson:fix/ios-v2-attachment-persistence

Conversation

@mwolson

@mwolsonmwolson commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Keep CTM mobile draft image attachments working when they carry both a local id and a dataUrl.
  • Avoid a Hermes fatal in the queue UI by replacing missing Array.prototype.toSorted with a shared copy-sort helper.
  • Hide orchestration-v2 subagent threads from the mobile Home list (forks stay visible).
  • Stabilize Home native-stack options and callbacks so ordinary Home updates do not re-enter navigation through PreventRemoveProvider.
  • Normalize V2 shell active/archive membership from archivedAt so archived threads do not stick on the Home list after a missed archive delta.

Base

This branch is now built on mwolson/t3codev2-base, a merge of the shared iOS/mobile fixes line (ios-fixes-main) into t3code/codex-turn-mapping. Because GitHub diffs against t3code/codex-turn-mapping, the PR diff includes that merge (mobile keyboard/feed fixes, shell reconnect heal, serverConfig/vcsRefs caching, and the V2 thread resume completion marker) in addition to the two commits listed below. Review the two head commits for this PR's own delta.

Problem and Fix

Problem and Why it HappenedFix
CTM drafts can include image attachments with both a local id and a dataUrl. The start-turn path did not treat those dual-tagged attachments as uploads, so order and persistence broke for mobile screenshots.Treat dual-tagged attachments as uploads, strip local-only fields before persistence, and dispatch server IDs while preserving order with already-persisted attachments.
Hermes 250829098 (RN 0.85.3) does not implement Array.prototype.toSorted. CTM queue UI calls it from deriveThreadQueueWorkflowState / ThreadQueueControl, so queuing a reply or finishing a turn can crash with TypeError: undefined is not a function.Add @t3tools/shared/ArraycopySorted ([...values].sort) and use it on mobile-reachable call sites (threadWorkflows, ThreadRelationshipsBanner, use-thread-selection, CTM model.ts).
Orchestration-v2 subagent shells appeared in the mobile Home list, unlike the desktop sidebar.Skip threads with lineage.relationshipToParent === "subagent" when grouping Home rows; keep fork threads.
Unstable Home native-stack options and callbacks re-entered setOptions and could hit maximum update depth through PreventRemoveProvider on CTM device launches.Memoize iOS Home header options (filter menu inputs as deps; handlers via ref) and stabilize Settings / New Task callbacks and title option objects.
A dropped thread.archived shell delta (or a mis-tagged full snapshot) could keep an archived thread listed as active on Home even after the reconnect heal applied a fresh snapshot.Add normalizeShellThreadMembership and apply it to every full snapshot (reducer enrichment refreshes and reconnect heals) so active/archive membership always derives from archivedAt. The HTTP heal, forced socket snapshot, and stale-snapshot rejection it pairs with live in v2-base.

Validation

  • Targeted tests: client-runtime attachment command tests; Home subagent filter tests (including fork negative control); shared Array tests; shell-sync / shellReducer membership tests.
  • vp check (0 errors) and full vp run typecheck on the rebuilt branch.
  • Device: archived threads from a paired CTM environment leave Home after reconnect/heal.
  • Device: Release Hermes com.mwolson.t3code.v2.dev from local orchestrator-v2 integration; queued reply send after active turn finished without crash; Home list usable after nav stability fix.

Notes

Note

Stabilize iOS draft attachments, Hermes array sort, and Home screen for mobile

This is a large orchestrator-v2 stabilization PR with dozens of changes across mobile, web, server, and desktop. Key highlights:

  • iOS draft attachments: persistAttachments now correctly maps upload results back to their source positions and strips client-only fields (id, previewUri) before sending to the server.
  • Hermes sort fix: Replaces Array.prototype.toSorted (unsupported on Hermes) with a shared copySorted utility throughout mobile thread sorting.
  • Home screen (Android): Adds a floating new-task FAB, custom branded header with inline search, and persists collapsed project groups via preferences atoms.
  • Draft hero UX: Web chat view gains a centered composer for empty drafts with animated docking transitions and a DraftHeroHeadline project picker.
  • Thread feed scroll correction: ThreadFeed now auto-corrects scroll position when content underflows the viewport and shows a full-screen loading overlay during hydration.
  • iOS terminal stability: TerminalInputSequence normalizes all return keys to carriage return (\r); autoFocus prop added to control keyboard focus.
  • Shell state synchronization: makeEnvironmentShellState no longer paints cached snapshots immediately; starts in synchronizing and waits for an HTTP heal or authoritative socket snapshot.
  • Thread resume completion marker: Server and client cooperate on a synchronized marker so warm-start clients exit the syncing state faster.
  • Android terminal: Full native terminal canvas (TerminalCanvasView, GhosttyBridge) with JNI bindings, selection, scroll, and theme support.
  • Incoming share flow (iOS/Android): IncomingShareProvider and IncomingShareInbox serialize share ingestion, merge content into composer drafts idempotently, and clean up temporary files.
  • Legal pages: Marketing site gains Privacy Policy, Terms of Service, and Security Policy pages with a shared LegalPage layout component.
  • Risk: IndexedDB schema bumped from v2 to v4; upgrade path adds new object stores but no migration for existing server-config/vcs-refs data (cold start for those caches).

Macroscope summarized 47dc628.


Note

Medium Risk
Touches desktop launcher/signing behavior, auto-update state, and substantial mobile native/Expo configuration; misconfiguration could affect local iOS builds, store screenshots CI, or renderer chrome, but changes are mostly additive with tests on key desktop paths.

Overview
Adds a manual GitHub workflow to capture and validate iOS and Android store showcase screenshots (pnpm screenshots:mobile), upload artifacts, and ignore generated .showcase/ / artifacts/app-store/screenshots/ paths.

Desktop changes improve the macOS dev launcher (branded bundle with a separate launcher executable that execs in-bundle Electron, launcher version bump), context menu positioning scaled by webContents zoom, native fullscreen state exposed to the renderer via IPC/preload, nightly update release notes (setFullChangelog + HTML/markdown normalization into update state), and WSL Node engine validation during probe.

Marketing adds a shared legal document layout, index plus privacy/terms/security pages, footer links, and Grok CLI messaging/assets on the homepage (with minor harness/layout tweaks).

Mobile expands Expo config: repo-root brand assets, Personal Team local iOS builds (optional bundle id, stripped widgets/share/SiWA entitlements), more Android plugins (Gradle heap, predictive back, modern menus/alerts, crash log), DM Sans registered under native PostScript names, and a new Android T3ComposerEditor native view (chips, paste images, theming). iOS markdown shadow node now rebuilds attributed content from current children instead of stale measure-time cache. Composer iOS fonts align to DMSans-Regular / DMSans-Medium.

Also bumps electron-builder, adds minimal root app.json, extends Macroscope Effect service conventions (dependency acquisition / runtime boundaries), and minor asset/doc updates.

Reviewed by Cursor Bugbot for commit 47dc628. Bugbot is set up for automated code reviews on this repo. Configure here.

juliusmarmingeand others added 17 commits July 7, 2026 15:55
…gg#3781)
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
…pingdotgg#3795)
Co-authored-by: Julius Marminge <julius@mac.lan>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
…tgg#3823)
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: Horus Lugo <horusgoul@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: maria-rcks <maria@kuuro.net>
Co-authored-by: Shivam Sharma <91240327+shivamhwp@users.noreply.github.com>
Co-authored-by: Ben Davis <45952064+bmdavis419@users.noreply.github.com>
Co-authored-by: Alex <me@pixp.cc>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: Julius Marminge <julius@mac.lan>
Co-authored-by: codex <codex@users.noreply.github.com>
@coderabbitai

coderabbitaiBot commented Jul 12, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 8bbf5543-c8a1-4f1c-8bfe-1d903c77b419

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Jul 12, 2026
Comment threadapps/mobile/src/features/home/HomeHeader.tsx
@mwolson
mwolson marked this pull request as ready for review July 12, 2026 21:35
Comment threadpackages/shared/src/Array.ts Outdated
@macroscopeapp

macroscopeappBot commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

25 blocking correctness issues found. Diff is too large for automated approval analysis. A human reviewer should evaluate this PR.

You can customize Macroscope's approvability policy. Learn more.

@mwolson
mwolsonforce-pushed the fix/ios-v2-attachment-persistence branch from 2857eb3 to 76a88a0CompareJuly 12, 2026 21:41
@mwolsonmwolson changed the title fix(mobile): Stabilize CTM iOS draft attachments, Hermes sort, and Home[orchestrator-v2] fix(mobile): Stabilize CTM iOS draft attachments, Hermes sort, and HomeJul 12, 2026
Capture RCTFatal message and stack to Documents via a native handler so
Release Hermes aborts leave last-crash.json without a device console.
Harden the JS ErrorUtils path with a minimal write-first record, durable
fsync writes, breadcrumb max-wait flush, and an Expo AppDelegate plugin.
Skip NativeStackScreenOptions setOptions when content is unchanged so
Thread catch-up re-renders do not loop through PreventRemoveProvider and
hit maximum update depth.
CI Mobile Native Static Analysis failed on a multi-line if where the
opening brace was on the following line.
Completes the pingdotgg#4055 port in the v2-base merge: draft routes carry a
pre-allocated thread id, and the conditional subscription blocked
promotion to live shell data until remount. Flagged by Grok review.

@cursorcursorBot left a comment

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.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

There are 4 total unresolved issues (including 3 from previous reviews).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 47dc628. Configure here.


Function("markShowcaseReady") { (scene: String) in
let readyPath = NSHomeDirectory() + "/Library/Caches/T3ShowcaseReadyScene"
try? scene.write(toFile: readyPath, atomically: true, encoding: .utf8)

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.

Crash breadcrumb fsync path removed

Medium Severity

The writeSyncText function, which provided durable last-chance crash log writes, was removed from T3NativeControlsModule. This breaks the breadcrumbPersist mechanism, which still expects this native fsync path. As a result, last-minute breadcrumbs may be lost during iOS fatals, impacting crash diagnostics.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 47dc628. Configure here.

@mwolson

Copy link
Copy Markdown
ContributorAuthor

Closing for now; may reattempt later after the iOS fixes have landed on main, and have been backmerged to codex-turn-mapping.

@mwolsonmwolson closed this Jul 20, 2026
juliusmarminge added a commit that referenced this pull request Jul 20, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
maria-rcks pushed a commit that referenced this pull request Aug 3, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 4, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 4, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 5, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 7, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 10, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 11, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 12, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 14, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 14, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 15, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 17, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 28, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 28, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 28, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 29, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 29, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 29, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 29, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 30, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 30, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Sep 1, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Sep 2, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

20 participants

@mwolson@juliusmarminge@avocardow@Prgm-code@jakeleventhal@VedankPurohit@twistedgrim@t3dotgg@kridaydave@D3OXY@dmstoykov@HugoVizcainoSantana@EricTsai83@AmoonPod@BunnyGamezsc@olivoil@Fazalkadivar21@maxwellyoung@nateEc@jamesx0416
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

[orchestrator-v2] fix(mobile): Stabilize iOS draft attachments, Hermes sort, and Home - #3923

Closed
mwolson wants to merge 138 commits into
pingdotgg:t3code/codex-turn-mappingfrom
mwolson:fix/ios-v2-attachment-persistence
Closed

[orchestrator-v2] fix(mobile): Stabilize iOS draft attachments, Hermes sort, and Home#3923
mwolson wants to merge 138 commits into
pingdotgg:t3code/codex-turn-mappingfrom
mwolson:fix/ios-v2-attachment-persistence

Conversation

@mwolson

@mwolsonmwolson commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Keep CTM mobile draft image attachments working when they carry both a local id and a dataUrl.
  • Avoid a Hermes fatal in the queue UI by replacing missing Array.prototype.toSorted with a shared copy-sort helper.
  • Hide orchestration-v2 subagent threads from the mobile Home list (forks stay visible).
  • Stabilize Home native-stack options and callbacks so ordinary Home updates do not re-enter navigation through PreventRemoveProvider.
  • Normalize V2 shell active/archive membership from archivedAt so archived threads do not stick on the Home list after a missed archive delta.

Base

This branch is now built on mwolson/t3codev2-base, a merge of the shared iOS/mobile fixes line (ios-fixes-main) into t3code/codex-turn-mapping. Because GitHub diffs against t3code/codex-turn-mapping, the PR diff includes that merge (mobile keyboard/feed fixes, shell reconnect heal, serverConfig/vcsRefs caching, and the V2 thread resume completion marker) in addition to the two commits listed below. Review the two head commits for this PR's own delta.

Problem and Fix

Problem and Why it HappenedFix
CTM drafts can include image attachments with both a local id and a dataUrl. The start-turn path did not treat those dual-tagged attachments as uploads, so order and persistence broke for mobile screenshots.Treat dual-tagged attachments as uploads, strip local-only fields before persistence, and dispatch server IDs while preserving order with already-persisted attachments.
Hermes 250829098 (RN 0.85.3) does not implement Array.prototype.toSorted. CTM queue UI calls it from deriveThreadQueueWorkflowState / ThreadQueueControl, so queuing a reply or finishing a turn can crash with TypeError: undefined is not a function.Add @t3tools/shared/ArraycopySorted ([...values].sort) and use it on mobile-reachable call sites (threadWorkflows, ThreadRelationshipsBanner, use-thread-selection, CTM model.ts).
Orchestration-v2 subagent shells appeared in the mobile Home list, unlike the desktop sidebar.Skip threads with lineage.relationshipToParent === "subagent" when grouping Home rows; keep fork threads.
Unstable Home native-stack options and callbacks re-entered setOptions and could hit maximum update depth through PreventRemoveProvider on CTM device launches.Memoize iOS Home header options (filter menu inputs as deps; handlers via ref) and stabilize Settings / New Task callbacks and title option objects.
A dropped thread.archived shell delta (or a mis-tagged full snapshot) could keep an archived thread listed as active on Home even after the reconnect heal applied a fresh snapshot.Add normalizeShellThreadMembership and apply it to every full snapshot (reducer enrichment refreshes and reconnect heals) so active/archive membership always derives from archivedAt. The HTTP heal, forced socket snapshot, and stale-snapshot rejection it pairs with live in v2-base.

Validation

  • Targeted tests: client-runtime attachment command tests; Home subagent filter tests (including fork negative control); shared Array tests; shell-sync / shellReducer membership tests.
  • vp check (0 errors) and full vp run typecheck on the rebuilt branch.
  • Device: archived threads from a paired CTM environment leave Home after reconnect/heal.
  • Device: Release Hermes com.mwolson.t3code.v2.dev from local orchestrator-v2 integration; queued reply send after active turn finished without crash; Home list usable after nav stability fix.

Notes

Note

Stabilize iOS draft attachments, Hermes array sort, and Home screen for mobile

This is a large orchestrator-v2 stabilization PR with dozens of changes across mobile, web, server, and desktop. Key highlights:

  • iOS draft attachments: persistAttachments now correctly maps upload results back to their source positions and strips client-only fields (id, previewUri) before sending to the server.
  • Hermes sort fix: Replaces Array.prototype.toSorted (unsupported on Hermes) with a shared copySorted utility throughout mobile thread sorting.
  • Home screen (Android): Adds a floating new-task FAB, custom branded header with inline search, and persists collapsed project groups via preferences atoms.
  • Draft hero UX: Web chat view gains a centered composer for empty drafts with animated docking transitions and a DraftHeroHeadline project picker.
  • Thread feed scroll correction: ThreadFeed now auto-corrects scroll position when content underflows the viewport and shows a full-screen loading overlay during hydration.
  • iOS terminal stability: TerminalInputSequence normalizes all return keys to carriage return (\r); autoFocus prop added to control keyboard focus.
  • Shell state synchronization: makeEnvironmentShellState no longer paints cached snapshots immediately; starts in synchronizing and waits for an HTTP heal or authoritative socket snapshot.
  • Thread resume completion marker: Server and client cooperate on a synchronized marker so warm-start clients exit the syncing state faster.
  • Android terminal: Full native terminal canvas (TerminalCanvasView, GhosttyBridge) with JNI bindings, selection, scroll, and theme support.
  • Incoming share flow (iOS/Android): IncomingShareProvider and IncomingShareInbox serialize share ingestion, merge content into composer drafts idempotently, and clean up temporary files.
  • Legal pages: Marketing site gains Privacy Policy, Terms of Service, and Security Policy pages with a shared LegalPage layout component.
  • Risk: IndexedDB schema bumped from v2 to v4; upgrade path adds new object stores but no migration for existing server-config/vcs-refs data (cold start for those caches).

Macroscope summarized 47dc628.


Note

Medium Risk
Touches desktop launcher/signing behavior, auto-update state, and substantial mobile native/Expo configuration; misconfiguration could affect local iOS builds, store screenshots CI, or renderer chrome, but changes are mostly additive with tests on key desktop paths.

Overview
Adds a manual GitHub workflow to capture and validate iOS and Android store showcase screenshots (pnpm screenshots:mobile), upload artifacts, and ignore generated .showcase/ / artifacts/app-store/screenshots/ paths.

Desktop changes improve the macOS dev launcher (branded bundle with a separate launcher executable that execs in-bundle Electron, launcher version bump), context menu positioning scaled by webContents zoom, native fullscreen state exposed to the renderer via IPC/preload, nightly update release notes (setFullChangelog + HTML/markdown normalization into update state), and WSL Node engine validation during probe.

Marketing adds a shared legal document layout, index plus privacy/terms/security pages, footer links, and Grok CLI messaging/assets on the homepage (with minor harness/layout tweaks).

Mobile expands Expo config: repo-root brand assets, Personal Team local iOS builds (optional bundle id, stripped widgets/share/SiWA entitlements), more Android plugins (Gradle heap, predictive back, modern menus/alerts, crash log), DM Sans registered under native PostScript names, and a new Android T3ComposerEditor native view (chips, paste images, theming). iOS markdown shadow node now rebuilds attributed content from current children instead of stale measure-time cache. Composer iOS fonts align to DMSans-Regular / DMSans-Medium.

Also bumps electron-builder, adds minimal root app.json, extends Macroscope Effect service conventions (dependency acquisition / runtime boundaries), and minor asset/doc updates.

Reviewed by Cursor Bugbot for commit 47dc628. Bugbot is set up for automated code reviews on this repo. Configure here.

juliusmarmingeand others added 17 commits July 7, 2026 15:55
…gg#3781)
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
…pingdotgg#3795)
Co-authored-by: Julius Marminge <julius@mac.lan>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
…tgg#3823)
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: Horus Lugo <horusgoul@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: maria-rcks <maria@kuuro.net>
Co-authored-by: Shivam Sharma <91240327+shivamhwp@users.noreply.github.com>
Co-authored-by: Ben Davis <45952064+bmdavis419@users.noreply.github.com>
Co-authored-by: Alex <me@pixp.cc>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: Julius Marminge <julius@mac.lan>
Co-authored-by: codex <codex@users.noreply.github.com>
@coderabbitai

coderabbitaiBot commented Jul 12, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 8bbf5543-c8a1-4f1c-8bfe-1d903c77b419

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Jul 12, 2026
Comment threadapps/mobile/src/features/home/HomeHeader.tsx
@mwolson
mwolson marked this pull request as ready for review July 12, 2026 21:35
Comment threadpackages/shared/src/Array.ts Outdated
@macroscopeapp

macroscopeappBot commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

25 blocking correctness issues found. Diff is too large for automated approval analysis. A human reviewer should evaluate this PR.

You can customize Macroscope's approvability policy. Learn more.

@mwolson
mwolsonforce-pushed the fix/ios-v2-attachment-persistence branch from 2857eb3 to 76a88a0CompareJuly 12, 2026 21:41
@mwolsonmwolson changed the title fix(mobile): Stabilize CTM iOS draft attachments, Hermes sort, and Home[orchestrator-v2] fix(mobile): Stabilize CTM iOS draft attachments, Hermes sort, and HomeJul 12, 2026
Capture RCTFatal message and stack to Documents via a native handler so
Release Hermes aborts leave last-crash.json without a device console.
Harden the JS ErrorUtils path with a minimal write-first record, durable
fsync writes, breadcrumb max-wait flush, and an Expo AppDelegate plugin.
Skip NativeStackScreenOptions setOptions when content is unchanged so
Thread catch-up re-renders do not loop through PreventRemoveProvider and
hit maximum update depth.
CI Mobile Native Static Analysis failed on a multi-line if where the
opening brace was on the following line.
Completes the pingdotgg#4055 port in the v2-base merge: draft routes carry a
pre-allocated thread id, and the conditional subscription blocked
promotion to live shell data until remount. Flagged by Grok review.

@cursorcursorBot left a comment

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.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

There are 4 total unresolved issues (including 3 from previous reviews).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 47dc628. Configure here.


Function("markShowcaseReady") { (scene: String) in
let readyPath = NSHomeDirectory() + "/Library/Caches/T3ShowcaseReadyScene"
try? scene.write(toFile: readyPath, atomically: true, encoding: .utf8)

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.

Crash breadcrumb fsync path removed

Medium Severity

The writeSyncText function, which provided durable last-chance crash log writes, was removed from T3NativeControlsModule. This breaks the breadcrumbPersist mechanism, which still expects this native fsync path. As a result, last-minute breadcrumbs may be lost during iOS fatals, impacting crash diagnostics.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 47dc628. Configure here.

@mwolson

Copy link
Copy Markdown
ContributorAuthor

Closing for now; may reattempt later after the iOS fixes have landed on main, and have been backmerged to codex-turn-mapping.

@mwolsonmwolson closed this Jul 20, 2026
juliusmarminge added a commit that referenced this pull request Jul 20, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
maria-rcks pushed a commit that referenced this pull request Aug 3, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 4, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 4, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 5, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 7, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 10, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 11, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 12, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 14, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 14, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 15, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 17, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 28, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 28, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 28, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 29, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 29, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 29, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 29, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 30, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 30, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Sep 1, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Sep 2, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

20 participants

@mwolson@juliusmarminge@avocardow@Prgm-code@jakeleventhal@VedankPurohit@twistedgrim@t3dotgg@kridaydave@D3OXY@dmstoykov@HugoVizcainoSantana@EricTsai83@AmoonPod@BunnyGamezsc@olivoil@Fazalkadivar21@maxwellyoung@nateEc@jamesx0416
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

[orchestrator-v2] fix(mobile): Stabilize iOS draft attachments, Hermes sort, and Home - #3923

Closed
mwolson wants to merge 138 commits into
pingdotgg:t3code/codex-turn-mappingfrom
mwolson:fix/ios-v2-attachment-persistence
Closed

[orchestrator-v2] fix(mobile): Stabilize iOS draft attachments, Hermes sort, and Home#3923
mwolson wants to merge 138 commits into
pingdotgg:t3code/codex-turn-mappingfrom
mwolson:fix/ios-v2-attachment-persistence

Conversation

@mwolson

@mwolsonmwolson commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Keep CTM mobile draft image attachments working when they carry both a local id and a dataUrl.
  • Avoid a Hermes fatal in the queue UI by replacing missing Array.prototype.toSorted with a shared copy-sort helper.
  • Hide orchestration-v2 subagent threads from the mobile Home list (forks stay visible).
  • Stabilize Home native-stack options and callbacks so ordinary Home updates do not re-enter navigation through PreventRemoveProvider.
  • Normalize V2 shell active/archive membership from archivedAt so archived threads do not stick on the Home list after a missed archive delta.

Base

This branch is now built on mwolson/t3codev2-base, a merge of the shared iOS/mobile fixes line (ios-fixes-main) into t3code/codex-turn-mapping. Because GitHub diffs against t3code/codex-turn-mapping, the PR diff includes that merge (mobile keyboard/feed fixes, shell reconnect heal, serverConfig/vcsRefs caching, and the V2 thread resume completion marker) in addition to the two commits listed below. Review the two head commits for this PR's own delta.

Problem and Fix

Problem and Why it HappenedFix
CTM drafts can include image attachments with both a local id and a dataUrl. The start-turn path did not treat those dual-tagged attachments as uploads, so order and persistence broke for mobile screenshots.Treat dual-tagged attachments as uploads, strip local-only fields before persistence, and dispatch server IDs while preserving order with already-persisted attachments.
Hermes 250829098 (RN 0.85.3) does not implement Array.prototype.toSorted. CTM queue UI calls it from deriveThreadQueueWorkflowState / ThreadQueueControl, so queuing a reply or finishing a turn can crash with TypeError: undefined is not a function.Add @t3tools/shared/ArraycopySorted ([...values].sort) and use it on mobile-reachable call sites (threadWorkflows, ThreadRelationshipsBanner, use-thread-selection, CTM model.ts).
Orchestration-v2 subagent shells appeared in the mobile Home list, unlike the desktop sidebar.Skip threads with lineage.relationshipToParent === "subagent" when grouping Home rows; keep fork threads.
Unstable Home native-stack options and callbacks re-entered setOptions and could hit maximum update depth through PreventRemoveProvider on CTM device launches.Memoize iOS Home header options (filter menu inputs as deps; handlers via ref) and stabilize Settings / New Task callbacks and title option objects.
A dropped thread.archived shell delta (or a mis-tagged full snapshot) could keep an archived thread listed as active on Home even after the reconnect heal applied a fresh snapshot.Add normalizeShellThreadMembership and apply it to every full snapshot (reducer enrichment refreshes and reconnect heals) so active/archive membership always derives from archivedAt. The HTTP heal, forced socket snapshot, and stale-snapshot rejection it pairs with live in v2-base.

Validation

  • Targeted tests: client-runtime attachment command tests; Home subagent filter tests (including fork negative control); shared Array tests; shell-sync / shellReducer membership tests.
  • vp check (0 errors) and full vp run typecheck on the rebuilt branch.
  • Device: archived threads from a paired CTM environment leave Home after reconnect/heal.
  • Device: Release Hermes com.mwolson.t3code.v2.dev from local orchestrator-v2 integration; queued reply send after active turn finished without crash; Home list usable after nav stability fix.

Notes

Note

Stabilize iOS draft attachments, Hermes array sort, and Home screen for mobile

This is a large orchestrator-v2 stabilization PR with dozens of changes across mobile, web, server, and desktop. Key highlights:

  • iOS draft attachments: persistAttachments now correctly maps upload results back to their source positions and strips client-only fields (id, previewUri) before sending to the server.
  • Hermes sort fix: Replaces Array.prototype.toSorted (unsupported on Hermes) with a shared copySorted utility throughout mobile thread sorting.
  • Home screen (Android): Adds a floating new-task FAB, custom branded header with inline search, and persists collapsed project groups via preferences atoms.
  • Draft hero UX: Web chat view gains a centered composer for empty drafts with animated docking transitions and a DraftHeroHeadline project picker.
  • Thread feed scroll correction: ThreadFeed now auto-corrects scroll position when content underflows the viewport and shows a full-screen loading overlay during hydration.
  • iOS terminal stability: TerminalInputSequence normalizes all return keys to carriage return (\r); autoFocus prop added to control keyboard focus.
  • Shell state synchronization: makeEnvironmentShellState no longer paints cached snapshots immediately; starts in synchronizing and waits for an HTTP heal or authoritative socket snapshot.
  • Thread resume completion marker: Server and client cooperate on a synchronized marker so warm-start clients exit the syncing state faster.
  • Android terminal: Full native terminal canvas (TerminalCanvasView, GhosttyBridge) with JNI bindings, selection, scroll, and theme support.
  • Incoming share flow (iOS/Android): IncomingShareProvider and IncomingShareInbox serialize share ingestion, merge content into composer drafts idempotently, and clean up temporary files.
  • Legal pages: Marketing site gains Privacy Policy, Terms of Service, and Security Policy pages with a shared LegalPage layout component.
  • Risk: IndexedDB schema bumped from v2 to v4; upgrade path adds new object stores but no migration for existing server-config/vcs-refs data (cold start for those caches).

Macroscope summarized 47dc628.


Note

Medium Risk
Touches desktop launcher/signing behavior, auto-update state, and substantial mobile native/Expo configuration; misconfiguration could affect local iOS builds, store screenshots CI, or renderer chrome, but changes are mostly additive with tests on key desktop paths.

Overview
Adds a manual GitHub workflow to capture and validate iOS and Android store showcase screenshots (pnpm screenshots:mobile), upload artifacts, and ignore generated .showcase/ / artifacts/app-store/screenshots/ paths.

Desktop changes improve the macOS dev launcher (branded bundle with a separate launcher executable that execs in-bundle Electron, launcher version bump), context menu positioning scaled by webContents zoom, native fullscreen state exposed to the renderer via IPC/preload, nightly update release notes (setFullChangelog + HTML/markdown normalization into update state), and WSL Node engine validation during probe.

Marketing adds a shared legal document layout, index plus privacy/terms/security pages, footer links, and Grok CLI messaging/assets on the homepage (with minor harness/layout tweaks).

Mobile expands Expo config: repo-root brand assets, Personal Team local iOS builds (optional bundle id, stripped widgets/share/SiWA entitlements), more Android plugins (Gradle heap, predictive back, modern menus/alerts, crash log), DM Sans registered under native PostScript names, and a new Android T3ComposerEditor native view (chips, paste images, theming). iOS markdown shadow node now rebuilds attributed content from current children instead of stale measure-time cache. Composer iOS fonts align to DMSans-Regular / DMSans-Medium.

Also bumps electron-builder, adds minimal root app.json, extends Macroscope Effect service conventions (dependency acquisition / runtime boundaries), and minor asset/doc updates.

Reviewed by Cursor Bugbot for commit 47dc628. Bugbot is set up for automated code reviews on this repo. Configure here.

juliusmarmingeand others added 17 commits July 7, 2026 15:55
…gg#3781)
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
…pingdotgg#3795)
Co-authored-by: Julius Marminge <julius@mac.lan>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
…tgg#3823)
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: Horus Lugo <horusgoul@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: maria-rcks <maria@kuuro.net>
Co-authored-by: Shivam Sharma <91240327+shivamhwp@users.noreply.github.com>
Co-authored-by: Ben Davis <45952064+bmdavis419@users.noreply.github.com>
Co-authored-by: Alex <me@pixp.cc>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: Julius Marminge <julius@mac.lan>
Co-authored-by: codex <codex@users.noreply.github.com>
@coderabbitai

coderabbitaiBot commented Jul 12, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 8bbf5543-c8a1-4f1c-8bfe-1d903c77b419

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Jul 12, 2026
Comment threadapps/mobile/src/features/home/HomeHeader.tsx
@mwolson
mwolson marked this pull request as ready for review July 12, 2026 21:35
Comment threadpackages/shared/src/Array.ts Outdated
@macroscopeapp

macroscopeappBot commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

25 blocking correctness issues found. Diff is too large for automated approval analysis. A human reviewer should evaluate this PR.

You can customize Macroscope's approvability policy. Learn more.

@mwolson
mwolsonforce-pushed the fix/ios-v2-attachment-persistence branch from 2857eb3 to 76a88a0CompareJuly 12, 2026 21:41
@mwolsonmwolson changed the title fix(mobile): Stabilize CTM iOS draft attachments, Hermes sort, and Home[orchestrator-v2] fix(mobile): Stabilize CTM iOS draft attachments, Hermes sort, and HomeJul 12, 2026
Capture RCTFatal message and stack to Documents via a native handler so
Release Hermes aborts leave last-crash.json without a device console.
Harden the JS ErrorUtils path with a minimal write-first record, durable
fsync writes, breadcrumb max-wait flush, and an Expo AppDelegate plugin.
Skip NativeStackScreenOptions setOptions when content is unchanged so
Thread catch-up re-renders do not loop through PreventRemoveProvider and
hit maximum update depth.
CI Mobile Native Static Analysis failed on a multi-line if where the
opening brace was on the following line.
Completes the pingdotgg#4055 port in the v2-base merge: draft routes carry a
pre-allocated thread id, and the conditional subscription blocked
promotion to live shell data until remount. Flagged by Grok review.

@cursorcursorBot left a comment

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.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

There are 4 total unresolved issues (including 3 from previous reviews).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 47dc628. Configure here.


Function("markShowcaseReady") { (scene: String) in
let readyPath = NSHomeDirectory() + "/Library/Caches/T3ShowcaseReadyScene"
try? scene.write(toFile: readyPath, atomically: true, encoding: .utf8)

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.

Crash breadcrumb fsync path removed

Medium Severity

The writeSyncText function, which provided durable last-chance crash log writes, was removed from T3NativeControlsModule. This breaks the breadcrumbPersist mechanism, which still expects this native fsync path. As a result, last-minute breadcrumbs may be lost during iOS fatals, impacting crash diagnostics.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 47dc628. Configure here.

@mwolson

Copy link
Copy Markdown
ContributorAuthor

Closing for now; may reattempt later after the iOS fixes have landed on main, and have been backmerged to codex-turn-mapping.

@mwolsonmwolson closed this Jul 20, 2026
juliusmarminge added a commit that referenced this pull request Jul 20, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
maria-rcks pushed a commit that referenced this pull request Aug 3, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 4, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 4, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 5, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 7, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 10, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 11, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 12, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 14, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 14, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 15, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 17, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 28, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 28, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 28, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 29, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 29, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 29, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 29, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 30, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Aug 30, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Sep 1, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
juliusmarminge added a commit that referenced this pull request Sep 2, 2026
Reuses the focused compatibility approach from closed PR #3923 and covers the remaining hardware-keyboard reverse iteration.
Co-authored-by: codex <codex@users.noreply.github.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

20 participants

@mwolson@juliusmarminge@avocardow@Prgm-code@jakeleventhal@VedankPurohit@twistedgrim@t3dotgg@kridaydave@D3OXY@dmstoykov@HugoVizcainoSantana@EricTsai83@AmoonPod@BunnyGamezsc@olivoil@Fazalkadivar21@maxwellyoung@nateEc@jamesx0416