Skip to content

Surface pending tasks in mobile home and draft flow - #3670

Merged
juliusmarminge merged 8 commits into
mainfrom
t3code/92d0f1f6-c5c5-4400-9d63-5e62b109203e
Jul 3, 2026
Merged

Surface pending tasks in mobile home and draft flow#3670
juliusmarminge merged 8 commits into
mainfrom
t3code/92d0f1f6-c5c5-4400-9d63-5e62b109203e

Conversation

@juliusmarminge

@juliusmarminge juliusmarminge commented Jul 3, 2026

Copy link
Copy Markdown
Member

Summary

  • Shows queued pending tasks in the mobile home and thread sidebar lists, grouped with their parent project alongside active threads.
  • Adds actions to open, edit, and delete pending tasks from the list UI.
  • Extends the new-task draft flow so offline tasks are queued to the outbox and can later be resumed or resent from the draft screen.
  • Refines thread composer styling and preserves draft state for pending-task edits and workspace start-from-origin settings.

Testing

  • Not run (not requested).
  • Project checks required by repo policy were not run in this summary.

Note

Medium Risk
Changes thread-outbox delivery, persistence schema, and turn-identifier reuse for pending tasks; incorrect gating could duplicate threads or drop queued work, though the PR adds targeted tests and edit locks.

Overview
Queued new tasks now appear in the mobile home and thread sidebar lists (ahead of threads, grouped by project), with rows to open, edit, or delete unsent outbox items.

The new-task draft path enqueues when the environment is disconnected (queue affordance vs start), resumes editing via pendingTaskId, and adds a Start from origin worktree option. Pending edits use a dedicated draft key, hold the outbox drain while open, and flush changes back on dismiss.

The thread outbox gains a creation payload (schema v3), in-place updates, and drain rules that treat new-thread creations separately (wait until shell is live, skip incomplete payloads, remove when the thread already exists). Immediate send and drain share buildProjectThreadStartTurnInput so online and offline delivery match.

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

Note

Surface pending tasks in mobile home screen and new task draft flow

  • Adds PendingTaskListRow to home and sidebar lists so queued (unsent) tasks appear alongside threads, grouped by project, with tap-to-edit and long-press delete actions.
  • Extends the outbox model with a creation payload (schema v3) and a new update operation so pending thread-creation tasks can be stored, edited, and redelivered when a shell comes online.
  • NewTaskDraftScreen now queues a task in the outbox when the environment is offline, supports editing previously queued tasks, and shows a queue icon on the start button when offline.
  • NewTaskFlowProvider gains beginEditingPendingTask/finishEditingPendingTask lifecycle, a startFromOrigin toggle for worktree mode, and holds the outbox drain while a task is being edited.
  • The outbox drain (useThreadOutboxDrain) dispatches queued creations once the project shell is live, skips messages under active editing, and removes tasks whose project is missing.
  • Risk: Schema version bump to 3 means persisted outbox messages written by older clients won't include creation metadata; the decoder accepts older versions gracefully.

Macroscope summarized 34f3a2c.

@coderabbitai

coderabbitai Bot commented Jul 3, 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: ef114159-9305-4698-b959-604e9cab8a6c

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
  • Commit unit tests in branch t3code/92d0f1f6-c5c5-4400-9d63-5e62b109203e

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

@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XXL 1,000+ changed lines (additions + deletions). labels Jul 3, 2026

@cursor cursor Bot 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 4 potential issues.

Autofix Details

Bugbot Autofix prepared fixes for all 4 issues found in the latest run.

  • ✅ Fixed: Pending edit survives draft pop
    • Added cancelEditingPendingTask that triggers the flush (clears editingPendingTaskRef, editingPendingTask state, and editingQueuedMessageId) and called it from a cleanup effect in NewTaskDraftScreen so editing state is properly cleared when the draft screen unmounts.
  • ✅ Fixed: Deleted pending resurrected on dismiss
    • The flush now checks findQueuedPendingTask before re-enqueuing so deleted tasks are not resurrected, and confirmDeletePendingTask now calls setEditingQueuedMessageId(null) to immediately unblock the drain.
  • ✅ Fixed: Route project skipped after re-entry
    • Added a cleanup effect that resets appliedInitialProjectKeyRef to null on unmount so re-entering the draft screen with the same project correctly applies it via setProject.
  • ✅ Fixed: Flush unblocks drain before enqueue
    • Deferred setEditingQueuedMessageId(null) into the .finally() callback of enqueueThreadOutboxMessage so the drain guard remains active until the updated message is persisted.

Create PR

Or push these changes by commenting:

@cursor push 5a9eae43c1
Preview (5a9eae43c1)
diff --git a/apps/mobile/src/features/home/usePendingTaskListActions.ts b/apps/mobile/src/features/home/usePendingTaskListActions.ts
--- a/apps/mobile/src/features/home/usePendingTaskListActions.ts
+++ b/apps/mobile/src/features/home/usePendingTaskListActions.ts
@@ -4,6 +4,7 @@
 
 import { removeThreadOutboxMessage } from "../../state/thread-outbox";
 import type { PendingNewTask } from "../../state/use-pending-new-tasks";
+import { setEditingQueuedMessageId } from "../../state/use-thread-outbox";
 
 export function usePendingTaskListActions(): {
   readonly openPendingTask: (pendingTask: PendingNewTask) => void;
@@ -35,6 +36,7 @@
           text: "Delete",
           style: "destructive",
           onPress: () => {
+            setEditingQueuedMessageId(null);
             void removeThreadOutboxMessage(pendingTask.message).catch((error) => {
               Alert.alert(
                 "Could not delete pending task",

diff --git a/apps/mobile/src/features/threads/NewTaskDraftScreen.tsx b/apps/mobile/src/features/threads/NewTaskDraftScreen.tsx
--- a/apps/mobile/src/features/threads/NewTaskDraftScreen.tsx
+++ b/apps/mobile/src/features/threads/NewTaskDraftScreen.tsx
@@ -80,14 +80,26 @@
   const promptInputRef = useRef<ComposerEditorHandle>(null);
   const loadedBranchesProjectKeyRef = useRef<string | null>(null);
   const appliedInitialProjectKeyRef = useRef<string | null>(null);
+  useEffect(() => {
+    return () => {
+      appliedInitialProjectKeyRef.current = null;
+    };
+  }, []);
 
-  const { beginEditingPendingTask, editingPendingTask } = flow;
+  const { beginEditingPendingTask, cancelEditingPendingTask, editingPendingTask } = flow;
   useEffect(() => {
     if (props.pendingTaskId && editingPendingTask?.messageId !== props.pendingTaskId) {
       beginEditingPendingTask(props.pendingTaskId);
     }
   }, [beginEditingPendingTask, editingPendingTask?.messageId, props.pendingTaskId]);
 
+  useEffect(() => {
+    if (!props.pendingTaskId) return;
+    return () => {
+      cancelEditingPendingTask();
+    };
+  }, [props.pendingTaskId, cancelEditingPendingTask]);
+
   const borderColor = useThemeColor("--color-border");
   const bodyText = useScaledTextRole("body");
   const sheetFadeOpaque = colorScheme === "dark" ? "rgba(14,14,14,0.98)" : "rgba(242,242,247,0.98)";

diff --git a/apps/mobile/src/features/threads/new-task-flow-provider.tsx b/apps/mobile/src/features/threads/new-task-flow-provider.tsx
--- a/apps/mobile/src/features/threads/new-task-flow-provider.tsx
+++ b/apps/mobile/src/features/threads/new-task-flow-provider.tsx
@@ -135,6 +135,7 @@
   readonly setStartFromOrigin: (value: boolean) => void;
   readonly beginEditingPendingTask: (messageId: string) => void;
   readonly finishEditingPendingTask: () => void;
+  readonly cancelEditingPendingTask: () => void;
   readonly buildPendingTaskMessage: (metadata: TurnCommandMetadata) => QueuedThreadMessage | null;
   readonly setPrompt: (value: string) => void;
   readonly replaceAttachments: (attachments: ReadonlyArray<DraftComposerImageAttachment>) => void;
@@ -603,8 +604,8 @@
     setEditingQueuedMessageId(null);
   }, []);
 
-  // Leaving the flow mid-edit (sheet dismissed) saves the current edits back
-  // into the queued task so nothing typed here is lost.
+  // Leaving the flow mid-edit (sheet dismissed or draft screen popped) saves
+  // the current edits back into the queued task so nothing typed here is lost.
   const editingFlushRef = useRef<(() => void) | null>(null);
   useEffect(() => {
     editingFlushRef.current = () => {
@@ -613,21 +614,38 @@
         return;
       }
       editingPendingTaskRef.current = null;
-      const message = buildPendingTaskMessage({
-        threadId: editing.threadId,
-        commandId: editing.commandId,
-        messageId: editing.messageId,
-        createdAt: editing.createdAt,
-      });
+      setEditingPendingTask(null);
+
+      // If the task was deleted externally, skip re-enqueuing.
+      const stillQueued = findQueuedPendingTask(editing.messageId);
+
+      const message = stillQueued
+        ? buildPendingTaskMessage({
+            threadId: editing.threadId,
+            commandId: editing.commandId,
+            messageId: editing.messageId,
+            createdAt: editing.createdAt,
+          })
+        : null;
+
+      clearComposerDraft(pendingTaskDraftKey(editing.messageId));
+
       if (message) {
-        void enqueueThreadOutboxMessage(message).catch((error) => {
-          console.warn("[new-task] failed to save edited pending task", error);
-        });
+        void enqueueThreadOutboxMessage(message)
+          .catch((error) => {
+            console.warn("[new-task] failed to save edited pending task", error);
+          })
+          .finally(() => {
+            setEditingQueuedMessageId(null);
+          });
+      } else {
+        setEditingQueuedMessageId(null);
       }
-      clearComposerDraft(pendingTaskDraftKey(editing.messageId));
-      setEditingQueuedMessageId(null);
     };
   }, [buildPendingTaskMessage]);
+  const cancelEditingPendingTask = useCallback(() => {
+    editingFlushRef.current?.();
+  }, []);
   useEffect(
     () => () => {
       editingFlushRef.current?.();
@@ -673,6 +691,7 @@
       setStartFromOrigin,
       beginEditingPendingTask,
       finishEditingPendingTask,
+      cancelEditingPendingTask,
       buildPendingTaskMessage,
       setPrompt,
       replaceAttachments,
@@ -694,6 +713,7 @@
       branchQuery,
       branchesLoading,
       buildPendingTaskMessage,
+      cancelEditingPendingTask,
       editingPendingTask,
       environments,
       expandedProvider,

You can send follow-ups to the cloud agent here.

Comment thread apps/mobile/src/features/threads/NewTaskDraftScreen.tsx Outdated
Comment thread apps/mobile/src/features/home/usePendingTaskListActions.ts
Comment thread apps/mobile/src/features/threads/NewTaskDraftScreen.tsx
Comment thread apps/mobile/src/features/threads/new-task-flow-provider.tsx Outdated
Comment thread apps/mobile/src/features/threads/NewTaskDraftScreen.tsx
} from "./thread-outbox-model";
import { useThreadOutboxMessages } from "./use-thread-outbox";

/** A queued new-task creation, shaped for thread-list presentation. */

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.

🟠 High state/use-pending-new-tasks.ts:11

PendingNewTask exposes only the queued message and creation.projectId, forcing buildHomeThreadGroups to re-resolve each pending task against the live projects snapshot. When an environment is offline or its project metadata has not loaded yet, the project lookup fails, so buildHomeThreadGroups drops those tasks entirely — queued tasks vanish from Home/Sidebar precisely while they are waiting for reconnection. Consider persisting enough project metadata (title and grouping fields) on PendingNewTask so pending tasks remain visible without a live project lookup.

Also found in 2 other location(s)

apps/mobile/src/features/home/homeThreadList.ts:95

buildHomeThreadGroups drops any pending task whose creation.projectId no longer appears in input.projects (groupKeyByProjectKey.get(...) returns nothing and the loop just continues). The new home screen now treats pendingTasks.length &gt; 0 as enough to suppress the true empty state, so if a queued task belongs to a project that was removed or has not been loaded yet, the screen shows an empty thread list and the user loses the only UI path to reopen or delete that pending draft.

apps/mobile/src/features/home/HomeScreen.tsx:322

hasAnyThreads at line 322 treats any queued pendingTasks as if the Home list has displayable content, but buildHomeThreadGroups() only shows a pending task when its creation.projectId still matches a project in props.projects. If the task belongs to a deleted/missing project or to a filtered-out environment, projectGroups stays empty while hasAnyThreads is still true, so the screen skips the real empty/loading state and renders the generic list-empty branch instead. Users can end up seeing No threads yet/No threads in … while their queued task is invisible and the normal add-connection/loading messaging is suppressed.

🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file @apps/mobile/src/state/use-pending-new-tasks.ts around line 11:

`PendingNewTask` exposes only the queued `message` and `creation.projectId`, forcing `buildHomeThreadGroups` to re-resolve each pending task against the live `projects` snapshot. When an environment is offline or its project metadata has not loaded yet, the project lookup fails, so `buildHomeThreadGroups` drops those tasks entirely — queued tasks vanish from Home/Sidebar precisely while they are waiting for reconnection. Consider persisting enough project metadata (title and grouping fields) on `PendingNewTask` so pending tasks remain visible without a live project lookup.

Also found in 2 other location(s):
- apps/mobile/src/features/home/homeThreadList.ts:95 -- `buildHomeThreadGroups` drops any pending task whose `creation.projectId` no longer appears in `input.projects` (`groupKeyByProjectKey.get(...)` returns nothing and the loop just `continue`s). The new home screen now treats `pendingTasks.length > 0` as enough to suppress the true empty state, so if a queued task belongs to a project that was removed or has not been loaded yet, the screen shows an empty thread list and the user loses the only UI path to reopen or delete that pending draft.
- apps/mobile/src/features/home/HomeScreen.tsx:322 -- `hasAnyThreads` at line `322` treats any queued `pendingTasks` as if the Home list has displayable content, but `buildHomeThreadGroups()` only shows a pending task when its `creation.projectId` still matches a project in `props.projects`. If the task belongs to a deleted/missing project or to a filtered-out environment, `projectGroups` stays empty while `hasAnyThreads` is still `true`, so the screen skips the real empty/loading state and renders the generic list-empty branch instead. Users can end up seeing `No threads yet`/`No threads in …` while their queued task is invisible and the normal add-connection/loading messaging is suppressed.

Comment thread apps/mobile/src/state/use-thread-outbox-drain.ts Outdated
Comment thread apps/mobile/src/features/threads/new-task-flow-provider.tsx
Comment thread apps/mobile/src/state/thread-outbox-model.ts
@macroscopeapp

macroscopeapp Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

5 blocking correctness issues found. This PR introduces a new feature for surfacing pending tasks with substantial new logic across multiple files. Multiple high-severity unresolved review comments identify potential bugs including data loss scenarios and race conditions that warrant human review before merging.

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

@juliusmarminge

Copy link
Copy Markdown
Member Author

@cursor push 5a9eae4

@cursor cursor Bot 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.

Autofix Details

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: Delete races pending edit flush
    • Fixed both races by (1) deferring setEditingQueuedMessageId(null) until removeThreadOutboxMessage resolves so the drain cannot send a deleting message, and (2) tracking pending deletions in a shared Set so the editor's unmount flush bails out instead of re-enqueuing a task whose async removal is in progress.

Create PR

Or push these changes by commenting:

@cursor push 1736b9ecc2
Preview (1736b9ecc2)
diff --git a/apps/mobile/src/features/home/usePendingTaskListActions.ts b/apps/mobile/src/features/home/usePendingTaskListActions.ts
--- a/apps/mobile/src/features/home/usePendingTaskListActions.ts
+++ b/apps/mobile/src/features/home/usePendingTaskListActions.ts
@@ -2,7 +2,11 @@
 import { useCallback } from "react";
 import { Alert } from "react-native";
 
-import { removeThreadOutboxMessage } from "../../state/thread-outbox";
+import {
+  clearPendingDeletion,
+  markPendingDeletion,
+  removeThreadOutboxMessage,
+} from "../../state/thread-outbox";
 import type { PendingNewTask } from "../../state/use-pending-new-tasks";
 import { setEditingQueuedMessageId } from "../../state/use-thread-outbox";
 
@@ -36,13 +40,18 @@
           text: "Delete",
           style: "destructive",
           onPress: () => {
-            setEditingQueuedMessageId(null);
-            void removeThreadOutboxMessage(pendingTask.message).catch((error) => {
-              Alert.alert(
-                "Could not delete pending task",
-                error instanceof Error ? error.message : "The pending task could not be removed.",
-              );
-            });
+            markPendingDeletion(pendingTask.message.messageId);
+            void removeThreadOutboxMessage(pendingTask.message)
+              .catch((error) => {
+                Alert.alert(
+                  "Could not delete pending task",
+                  error instanceof Error ? error.message : "The pending task could not be removed.",
+                );
+              })
+              .finally(() => {
+                clearPendingDeletion(pendingTask.message.messageId);
+                setEditingQueuedMessageId(null);
+              });
           },
         },
       ],

diff --git a/apps/mobile/src/features/threads/new-task-flow-provider.tsx b/apps/mobile/src/features/threads/new-task-flow-provider.tsx
--- a/apps/mobile/src/features/threads/new-task-flow-provider.tsx
+++ b/apps/mobile/src/features/threads/new-task-flow-provider.tsx
@@ -41,6 +41,7 @@
 import {
   enqueueThreadOutboxMessage,
   flattenQueuedThreadMessages,
+  isPendingDeletion,
   threadOutboxManager,
   type QueuedThreadMessage,
 } from "../../state/thread-outbox";
@@ -616,6 +617,13 @@
       editingPendingTaskRef.current = null;
       setEditingPendingTask(null);
 
+      // If a deletion is in progress, bail out and let the delete handler
+      // manage the editing lock and cleanup.
+      if (isPendingDeletion(editing.messageId)) {
+        clearComposerDraft(pendingTaskDraftKey(editing.messageId));
+        return;
+      }
+
       // If the task was deleted externally, skip re-enqueuing.
       const stillQueued = findQueuedPendingTask(editing.messageId);
 

diff --git a/apps/mobile/src/state/thread-outbox.ts b/apps/mobile/src/state/thread-outbox.ts
--- a/apps/mobile/src/state/thread-outbox.ts
+++ b/apps/mobile/src/state/thread-outbox.ts
@@ -27,3 +27,17 @@
 export function clearThreadOutboxEnvironment(environmentId: EnvironmentId): Promise<void> {
   return threadOutboxManager.clearEnvironment(environmentId);
 }
+
+const pendingDeletionMessageIds = new Set<string>();
+
+export function markPendingDeletion(messageId: string): void {
+  pendingDeletionMessageIds.add(messageId);
+}
+
+export function clearPendingDeletion(messageId: string): void {
+  pendingDeletionMessageIds.delete(messageId);
+}
+
+export function isPendingDeletion(messageId: string): boolean {
+  return pendingDeletionMessageIds.has(messageId);
+}

You can send follow-ups to the cloud agent here.

Comment thread apps/mobile/src/features/home/usePendingTaskListActions.ts Outdated
Comment thread apps/mobile/src/features/threads/NewTaskDraftScreen.tsx
Comment thread apps/mobile/src/features/home/usePendingTaskListActions.ts
return true;
}, []);

const buildPendingTaskMessage = useCallback(

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.

🟠 High threads/new-task-flow-provider.tsx:562

buildPendingTaskMessage reads selectedProject for environmentId, projectId, projectTitle, and projectCwd, but during an editing session the user can switch environments before closing the sheet. The flush path then rewrites the queued task with fields from the newly selected project, silently moving it to a different environment/repository. The rebuilt message should preserve those fields from the original editingPendingTask instead of the live selectedProject.

Also found in 1 other location(s)

apps/mobile/src/state/use-thread-outbox-drain.ts:258

sendQueuedCreation rebuilds the bootstrap payload with project.workspaceRoot instead of the queued snapshot in creation.projectCwd. If the project path changes after the task was queued, the offline outbox no longer sends the same command that was originally saved and can create the thread/worktree from the wrong directory. The queued message already persists creation.projectCwd, so this regression is introduced at the resend path.

🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file @apps/mobile/src/features/threads/new-task-flow-provider.tsx around line 562:

`buildPendingTaskMessage` reads `selectedProject` for `environmentId`, `projectId`, `projectTitle`, and `projectCwd`, but during an editing session the user can switch environments before closing the sheet. The flush path then rewrites the queued task with fields from the newly selected project, silently moving it to a different environment/repository. The rebuilt message should preserve those fields from the original `editingPendingTask` instead of the live `selectedProject`.

Also found in 1 other location(s):
- apps/mobile/src/state/use-thread-outbox-drain.ts:258 -- `sendQueuedCreation` rebuilds the bootstrap payload with `project.workspaceRoot` instead of the queued snapshot in `creation.projectCwd`. If the project path changes after the task was queued, the offline outbox no longer sends the same command that was originally saved and can create the thread/worktree from the wrong directory. The queued message already persists `creation.projectCwd`, so this regression is introduced at the resend path.

Comment thread apps/mobile/src/features/threads/NewTaskDraftScreen.tsx

@cursor cursor Bot 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 3 potential issues.

Autofix Details

Bugbot Autofix prepared fixes for all 3 issues found in the latest run.

  • ✅ Fixed: Drain drops visible pending tasks
    • Changed sendQueuedCreation to accept a projectCwd string and the drain now falls back to creation.projectCwd instead of dropping the message when the project shell is absent from the catalog.
  • ✅ Fixed: Wrong project while editing pending
    • Prevented selectedProject from falling back to projectsForEnvironment[0] when editingPendingTask is set, so buildPendingTaskMessage and handleStart cannot target the wrong project.
  • ✅ Fixed: Pending open never retries load
    • Added queuedMessages to the effect dependency list so it retries when the outbox hydrates, moved attemptedPendingTaskIdRef assignment to after success, and deferred navigation until the outbox has content.

Create PR

Or push these changes by commenting:

@cursor push 8432c98136
Preview (8432c98136)
diff --git a/apps/mobile/src/features/threads/NewTaskDraftScreen.tsx b/apps/mobile/src/features/threads/NewTaskDraftScreen.tsx
--- a/apps/mobile/src/features/threads/NewTaskDraftScreen.tsx
+++ b/apps/mobile/src/features/threads/NewTaskDraftScreen.tsx
@@ -34,7 +34,12 @@
 import { useScaledTextRole } from "../settings/appearance/useScaledTextRole";
 import { getComposerDraftSnapshot } from "../../state/use-composer-drafts";
 import { useProjects } from "../../state/entities";
-import { enqueueThreadOutboxMessage, removeThreadOutboxMessage } from "../../state/thread-outbox";
+import {
+  enqueueThreadOutboxMessage,
+  flattenQueuedThreadMessages,
+  removeThreadOutboxMessage,
+} from "../../state/thread-outbox";
+import { useThreadOutboxMessages } from "../../state/use-thread-outbox";
 import { useRemoteConnectionStatus } from "../../state/use-remote-environment-registry";
 import { branchBadgeLabel, useNewTaskFlow } from "./new-task-flow-provider";
 import { useCreateProjectThread } from "./use-project-actions";
@@ -84,6 +89,7 @@
   }, []);
 
   const { beginEditingPendingTask, cancelEditingPendingTask, editingPendingTask } = flow;
+  const queuedMessages = useThreadOutboxMessages();
   const attemptedPendingTaskIdRef = useRef<string | null>(null);
   useEffect(() => {
     if (!props.pendingTaskId || editingPendingTask?.messageId === props.pendingTaskId) {
@@ -94,12 +100,21 @@
     if (attemptedPendingTaskIdRef.current === props.pendingTaskId) {
       return;
     }
+    if (beginEditingPendingTask(props.pendingTaskId)) {
+      attemptedPendingTaskIdRef.current = props.pendingTaskId;
+      return;
+    }
+    // The task was not found. If the outbox atom is still empty, persisted
+    // messages may not have hydrated yet — wait for the next atom update.
+    const hasOutboxContent =
+      flattenQueuedThreadMessages(queuedMessages).length > 0;
+    if (!hasOutboxContent) {
+      return;
+    }
+    // The outbox has content but this task is absent — it was sent or deleted.
     attemptedPendingTaskIdRef.current = props.pendingTaskId;
-    if (!beginEditingPendingTask(props.pendingTaskId)) {
-      // The queued task no longer exists (sent or deleted before opening).
-      navigation.dispatch(StackActions.replace("NewTask"));
-    }
-  }, [beginEditingPendingTask, editingPendingTask?.messageId, navigation, props.pendingTaskId]);
+    navigation.dispatch(StackActions.replace("NewTask"));
+  }, [beginEditingPendingTask, editingPendingTask?.messageId, navigation, props.pendingTaskId, queuedMessages]);
 
   useEffect(() => {
     if (!props.pendingTaskId) return;

diff --git a/apps/mobile/src/features/threads/new-task-flow-provider.tsx b/apps/mobile/src/features/threads/new-task-flow-provider.tsx
--- a/apps/mobile/src/features/threads/new-task-flow-provider.tsx
+++ b/apps/mobile/src/features/threads/new-task-flow-provider.tsx
@@ -262,8 +262,7 @@
     projectsForEnvironment.find(
       (project) => scopedProjectKey(project.environmentId, project.id) === selectedProjectKey,
     ) ??
-    projectsForEnvironment[0] ??
-    null;
+    (editingPendingTask !== null ? null : (projectsForEnvironment[0] ?? null));
   const selectedEnvironmentServerConfig = useEnvironmentServerConfig(
     selectedProject?.environmentId ?? null,
   );

diff --git a/apps/mobile/src/state/use-thread-outbox-drain.ts b/apps/mobile/src/state/use-thread-outbox-drain.ts
--- a/apps/mobile/src/state/use-thread-outbox-drain.ts
+++ b/apps/mobile/src/state/use-thread-outbox-drain.ts
@@ -244,7 +244,7 @@
     async (
       queuedMessage: QueuedThreadMessage,
       creation: QueuedThreadCreation,
-      project: EnvironmentProject,
+      projectCwd: string,
     ) => {
       const modelSelection = queuedMessage.modelSelection;
       if (modelSelection === undefined) {
@@ -255,7 +255,7 @@
         environmentId: queuedMessage.environmentId,
         input: buildProjectThreadStartTurnInput({
           projectId: creation.projectId,
-          projectCwd: project.workspaceRoot,
+          projectCwd,
           threadId: queuedMessage.threadId,
           commandId: queuedMessage.commandId,
           messageId: queuedMessage.messageId,
@@ -341,13 +341,14 @@
         );
       const creationProject =
         creation !== undefined ? findCreationProject(projects, nextQueuedMessage) : undefined;
+      const creationProjectCwd = creationProject?.workspaceRoot ?? creation?.projectCwd;
       const delivery =
         deliveryAction === "remove"
           ? removeQueuedMessage("[thread-outbox] failed to remove message for a missing thread")
           : creation !== undefined
-            ? creationProject !== undefined
-              ? sendQueuedCreation(nextQueuedMessage, creation, creationProject)
-              : removeQueuedMessage("[thread-outbox] dropped pending task for a missing project")
+            ? creationProjectCwd !== undefined
+              ? sendQueuedCreation(nextQueuedMessage, creation, creationProjectCwd)
+              : Promise.resolve(false)
             : thread !== undefined
               ? sendQueuedMessage(nextQueuedMessage, thread)
               : Promise.resolve(false);

You can send follow-ups to the cloud agent here.

Comment thread apps/mobile/src/state/use-thread-outbox-drain.ts
Comment thread apps/mobile/src/features/threads/new-task-flow-provider.tsx
Comment thread apps/mobile/src/features/threads/NewTaskDraftScreen.tsx
juliusmarminge and others added 5 commits July 3, 2026 11:23
- Show queued new tasks in home and sidebar lists
- Allow reopening, deleting, and editing pending outbox tasks
- Queue drafts offline and preserve draft state per pending task
- Clear editing state when NewTaskDraftScreen unmounts (Bug 1: pending edit
  survives draft pop). Expose cancelEditingPendingTask through the flow
  context, which triggers the flush and clears both the ref and React state.

- Prevent deleted pending tasks from being resurrected on dismiss (Bug 2).
  The flush now checks findQueuedPendingTask before re-enqueuing, and
  confirmDeletePendingTask clears the editing guard immediately.

- Reset appliedInitialProjectKeyRef on unmount so re-entering the draft
  screen with the same project correctly applies it (Bug 3).

- Defer setEditingQueuedMessageId(null) until after enqueueThreadOutboxMessage
  resolves, preventing the drain from sending stale content before the updated
  message is written (Bug 4).

Applied via @cursor push command
- Reflow long imports and callback dependencies
- Keep thread list and outbox tests aligned with formatter output
- Generate worktree branch names with a real hex token so they match the
  t3code/[0-9a-f]{8} pattern and server-side first-turn rename runs
- Snapshot project title/cwd on queued creations and render a fallback
  group so pending tasks stay visible without a live project shell
- Gate queued-creation delivery on a live shell to avoid duplicating a
  thread whose creation succeeded but cleanup failed
- Add serialized update-if-exists to the outbox manager and use it for
  the editor flush so a trailing flush can never resurrect a deleted task
- End the editing session reactively when the queued task disappears,
  and release the edit lock conditionally (and only after removal) when
  deleting from the list
- Keep pending-task editing from falling into the replace(NewTask)
  fallback, and navigate back to the project chooser if the task is gone
- Re-apply route project params when a fresh navigation targets the
  mounted draft screen

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@juliusmarminge
juliusmarminge force-pushed the t3code/92d0f1f6-c5c5-4400-9d63-5e62b109203e branch from 0c9bd1f to bbda5f4 Compare July 3, 2026 18:24
Comment thread apps/mobile/src/lib/uuid.ts
Comment thread apps/mobile/src/state/thread-outbox-model.ts Outdated
Comment thread apps/mobile/src/features/threads/new-task-flow-provider.tsx Outdated
} {
const navigation = useNavigation();

const openPendingTask = useCallback(

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.

🟠 High home/usePendingTaskListActions.ts:15

openPendingTask navigates straight to NewTaskDraft using pendingTask.creation.projectId without verifying the project still exists. When the original project no longer exists locally, the draft flow falls back to projectsForEnvironment[0], so resending the queued task silently sends it against the wrong project. Consider checking the project is still available before navigating, and showing an error or fallback UI if it is not.

Also found in 1 other location(s)

apps/mobile/src/state/use-thread-outbox-drain.ts:258

sendQueuedCreation rebuilds the bootstrap payload with project.workspaceRoot instead of the persisted creation.projectCwd. A queued worktree task is therefore no longer tied to the repository path it was created for: if that project's workspaceRoot changes before the outbox drains, the resend will prepare the worktree in the new cwd and start the thread against the wrong checkout.

🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file @apps/mobile/src/features/home/usePendingTaskListActions.ts around line 15:

`openPendingTask` navigates straight to `NewTaskDraft` using `pendingTask.creation.projectId` without verifying the project still exists. When the original project no longer exists locally, the draft flow falls back to `projectsForEnvironment[0]`, so resending the queued task silently sends it against the wrong project. Consider checking the project is still available before navigating, and showing an error or fallback UI if it is not.

Also found in 1 other location(s):
- apps/mobile/src/state/use-thread-outbox-drain.ts:258 -- `sendQueuedCreation` rebuilds the bootstrap payload with `project.workspaceRoot` instead of the persisted `creation.projectCwd`. A queued worktree task is therefore no longer tied to the repository path it was created for: if that project's `workspaceRoot` changes before the outbox drains, the resend will prepare the worktree in the new cwd and start the thread against the wrong checkout.

- While editing a queued task whose project shell is not loaded, stand in
  with the project metadata snapshotted at enqueue time instead of
  silently falling back to the environment's first project (which
  retargeted the task and its reused turn identifiers)
- Outbox drain prefers the live project workspaceRoot but falls back to
  the snapshotted projectCwd rather than dropping the task
- Treat an empty-string worktree branch as unsendable, matching server
  validation, so the task stays queued instead of being discarded
- Clear the editing draft only after the outbox save succeeds so a
  storage failure keeps the edits for the next open
- Reset the attempted-load marker when an edit session closes so the
  same pending task can be reopened on a still-mounted draft screen
- Derive randomHex from real random bytes so byteLength > 16 honors the
  documented contract

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@cursor cursor Bot 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 3 potential issues.

Autofix Details

Bugbot Autofix prepared fixes for all 3 issues found in the latest run.

  • ✅ Fixed: Failed flush unlocks outbox drain
    • Moved setEditingQueuedMessageId(null) from .finally() into .then() (guarded by editingPendingTaskRef.current === null) so the drain lock is only released on successful save, preventing stale content delivery on failure.
  • ✅ Fixed: Stale flush clears active draft
    • Guarded clearComposerDraft in .then() with a check that editingPendingTaskRef.current?.messageId !== editing.messageId, so the draft is preserved when the user has reopened the same pending task before the earlier flush settles.
  • ✅ Fixed: Invalid cwd triggers outbox send
    • In buildPendingTaskMessage, projectCwd now checks selectedProject.workspaceRoot !== String(selectedProject.id) before persisting, so the fabricated stand-in value (stringified project ID) is stored as undefined instead of a non-path string that would pass the drain's null gate.

Create PR

Or push these changes by commenting:

@cursor push 39d3cb2de2
Preview (39d3cb2de2)
diff --git a/apps/mobile/src/features/threads/new-task-flow-provider.tsx b/apps/mobile/src/features/threads/new-task-flow-provider.tsx
--- a/apps/mobile/src/features/threads/new-task-flow-provider.tsx
+++ b/apps/mobile/src/features/threads/new-task-flow-provider.tsx
@@ -612,7 +612,10 @@
         creation: {
           projectId: selectedProject.id,
           projectTitle: selectedProject.title,
-          projectCwd: selectedProject.workspaceRoot,
+          projectCwd:
+            selectedProject.workspaceRoot !== String(selectedProject.id)
+              ? selectedProject.workspaceRoot
+              : undefined,
           workspaceMode: mode,
           branch: workspaceSelection?.branch ?? null,
           worktreePath: mode === "worktree" ? null : (workspaceSelection?.worktreePath ?? null),
@@ -679,13 +682,15 @@
         // save keeps it around so the edits rehydrate on the next open).
         void updateThreadOutboxMessage(message)
           .then(() => {
-            clearComposerDraft(pendingTaskDraftKey(editing.messageId));
+            if (editingPendingTaskRef.current === null) {
+              setEditingQueuedMessageId(null);
+            }
+            if (editingPendingTaskRef.current?.messageId !== editing.messageId) {
+              clearComposerDraft(pendingTaskDraftKey(editing.messageId));
+            }
           })
           .catch((error) => {
             console.warn("[new-task] failed to save edited pending task", error);
-          })
-          .finally(() => {
-            setEditingQueuedMessageId(null);
           });
       } else {
         clearComposerDraft(pendingTaskDraftKey(editing.messageId));

You can send follow-ups to the cloud agent here.

Comment thread apps/mobile/src/features/threads/new-task-flow-provider.tsx Outdated
Comment thread apps/mobile/src/features/threads/new-task-flow-provider.tsx Outdated
Comment thread apps/mobile/src/features/threads/new-task-flow-provider.tsx Outdated
Comment thread apps/mobile/src/features/threads/new-task-flow-provider.tsx Outdated
- Hold the drain lock (and keep the draft) when the outbox save fails or
  the edits are currently unsendable, so a stale queued payload can never
  auto-send content the user just changed or removed
- Guard the flush completion with a module-scope editing-session
  generation so an in-flight save from a dismissed session cannot clear
  the draft or drain lock owned by a newer session (including one in a
  fresh provider instance)
- Never persist the stand-in project's placeholder title/cwd back into
  the queued creation; snapshot fields pass through unchanged so the
  drain cannot dispatch a fabricated workspace path

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@cursor cursor Bot 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.

Fix All in Cursor

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: Edit lock handoff enables stale send
    • When the flush path finds an unsendable edit (empty prompt), the outbox row's text is now cleared via updateThreadOutboxMessage so that isQueuedThreadCreationSendable returns false even if the single-slot drain lock is later overwritten by opening another pending task.

Create PR

Or push these changes by commenting:

@cursor push 7c800d3db5
Preview (7c800d3db5)
diff --git a/apps/mobile/src/features/threads/new-task-flow-provider.tsx b/apps/mobile/src/features/threads/new-task-flow-provider.tsx
--- a/apps/mobile/src/features/threads/new-task-flow-provider.tsx
+++ b/apps/mobile/src/features/threads/new-task-flow-provider.tsx
@@ -700,9 +700,11 @@
 
       if (!message) {
         // The edits are currently unsendable (e.g. the prompt was cleared).
-        // Keep both the draft and the drain lock: the stale queued payload
-        // must not auto-send content the user just removed, and reopening the
-        // task resumes from the saved draft.
+        // Blank the outbox text so the entry itself fails
+        // `isQueuedThreadCreationSendable` — the drain lock alone is not
+        // sufficient because opening another pending task overwrites the
+        // single-slot lock atom and would release this one.
+        void updateThreadOutboxMessage({ ...editing, text: "" });
         return;
       }

You can send follow-ups to the cloud agent here.

Reviewed by Cursor Bugbot for commit 2c7d991. Configure here.

Comment thread apps/mobile/src/features/threads/new-task-flow-provider.tsx
Comment thread apps/mobile/src/features/threads/new-task-flow-provider.tsx Outdated
- The editing/held drain lock is now a set of message ids, so opening a
  new pending task no longer overwrites the lock still protecting a
  dismissed task whose latest edits could not be written back (which let
  the drain send its stale original content)
- Track the active editing message id at module scope so an in-flight
  flush releases exactly its own lock: a reopened session for the same
  task keeps ownership, while unrelated sessions no longer block release
- Stand-in projects no longer fabricate a workspace root from the
  project id; branch queries skip the empty value instead of issuing VCS
  calls against a non-path

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* back yet (delivering those would send stale content). Editing sessions hold
* their message id here and release it once the queued payload is current.
*/
export const editingQueuedMessageIdsAtom = Atom.make<Readonly<Record<MessageId, true>>>({}).pipe(

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.

🟠 High state/use-thread-outbox.ts:29

editingQueuedMessageIdsAtom is a pure in-memory atom (Atom.keepAlive), but the queued outbox messages and the edit drafts it protects are persisted. If the user closes an edit without saving (leaving a draft and lock in composer-drafts) and then restarts the app, this atom resets to {} while the stale queued message remains on disk. The outbox drain only checks editingQueuedMessageIds[nextQueuedMessage.messageId], so on startup it no longer skips that messageId and auto-delivers the old payload — the stale content the user removed or edited. The edit lock needs to survive restarts so the drain keeps skipping a messageId whose draft is still unsaved.

🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file @apps/mobile/src/state/use-thread-outbox.ts around line 29:

`editingQueuedMessageIdsAtom` is a pure in-memory atom (`Atom.keepAlive`), but the queued outbox messages and the edit drafts it protects are persisted. If the user closes an edit without saving (leaving a draft and lock in `composer-drafts`) and then restarts the app, this atom resets to `{}` while the stale queued message remains on disk. The outbox drain only checks `editingQueuedMessageIds[nextQueuedMessage.messageId]`, so on startup it no longer skips that `messageId` and auto-delivers the old payload — the stale content the user removed or edited. The edit lock needs to survive restarts so the drain keeps skipping a `messageId` whose draft is still unsaved.

: Promise.resolve(false);
? removeQueuedMessage("[thread-outbox] failed to remove message for a missing thread")
: creation !== undefined
? creationProjectCwd !== null

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.

🟠 High state/use-thread-outbox-drain.ts:355

When the shell is "live" but the project snapshot has not yet loaded (findCreationProject returns undefined), the drain drops the queued creation via removeQueuedMessage("[thread-outbox] dropped pending task for a missing project") instead of waiting. A live connection can transiently expose an empty project list, so this permanently deletes a pending task whose project simply hasn't appeared yet. Consider treating a missing live project the same as a not-yet-loaded shell — continue to wait instead of removing the message.

Also found in 1 other location(s)

apps/mobile/src/features/threads/new-task-flow-provider.tsx:585

beginEditingPendingTask() checks isComposerDraftEmpty(getComposerDraftSnapshot(draftKey)) before the persisted composer drafts are guaranteed to be loaded. After an app restart, a pending-task edit draft can still exist on disk, but getComposerDraftSnapshot() initially sees an empty in-memory atom, so lines 585-598 rehydrate the draft from the stale queued message and overwrite the user's newer persisted edits. When ensureComposerDraftsLoaded() finishes later, it merges persisted drafts under the already-written in-memory draft, so the newer saved edits are lost.

🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file @apps/mobile/src/state/use-thread-outbox-drain.ts around line 355:

When the shell is `"live"` but the project snapshot has not yet loaded (`findCreationProject` returns `undefined`), the drain drops the queued creation via `removeQueuedMessage("[thread-outbox] dropped pending task for a missing project")` instead of waiting. A live connection can transiently expose an empty project list, so this permanently deletes a pending task whose project simply hasn't appeared yet. Consider treating a missing live project the same as a not-yet-loaded shell — `continue` to wait instead of removing the message.

Also found in 1 other location(s):
- apps/mobile/src/features/threads/new-task-flow-provider.tsx:585 -- `beginEditingPendingTask()` checks `isComposerDraftEmpty(getComposerDraftSnapshot(draftKey))` before the persisted composer drafts are guaranteed to be loaded. After an app restart, a pending-task edit draft can still exist on disk, but `getComposerDraftSnapshot()` initially sees an empty in-memory atom, so lines 585-598 rehydrate the draft from the stale queued message and overwrite the user's newer persisted edits. When `ensureComposerDraftsLoaded()` finishes later, it merges persisted drafts under the already-written in-memory draft, so the newer saved edits are lost.

@juliusmarminge
juliusmarminge merged commit 4ac094f into main Jul 3, 2026
16 checks passed
@juliusmarminge
juliusmarminge deleted the t3code/92d0f1f6-c5c5-4400-9d63-5e62b109203e branch July 3, 2026 20:32
1337hero pushed a commit to 1337hero/t3code that referenced this pull request Jul 4, 2026
adamfgr pushed a commit to agriffiths-bots/t3code that referenced this pull request Jul 4, 2026
* Upgrade Vite Plus and enable bundled dev opt-in (pingdotgg#3679)

* Surface pending tasks in mobile home and draft flow (pingdotgg#3670)

---------

Co-authored-by: Julius Marminge <julius0216@outlook.com>
shivamhwp added a commit that referenced this pull request Jul 6, 2026
Resolves conflicts from #3687 (thread list/navigation rework), #3670
(pending tasks), and #3679 (Vite Plus upgrade):

- ThreadNavigationDrawer.tsx: accept main's deletion; drawer navigation
  is replaced by native back-swipe and the reworked thread lists
- ThreadRouteScreen.tsx: keep Android in-flow header alongside main's
  deep-link Home escape for the iOS compact header
- HomeRouteScreen.tsx: keep AndroidHomeFabLayout wrapper, add main's
  pending-task props
- NewTaskDraftScreen.tsx: keep shared promptEditor/startButton, port
  main's iOS headline text style and queue-task button states
- thread-list-items.tsx: take main's header structure (chevron removed
  on all platforms); Android folder-state favicon already merged
- ThreadDetailScreen.tsx: union imports, drop unused gesture-handler
- pnpm-workspace.yaml/lockfile: keep expo-modules-jsi pin comment,
  regenerate lockfile via pnpm install

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
tarik02 referenced this pull request in tarik02-org/t3code Jul 13, 2026
* Add middle-click close for right panel tabs (#3161)

Co-authored-by: Julius Marminge <jmarminge@gmail.com>

* fix: warm WSL before preflight in WSL-only backend mode (#3588)

* Add Claude Sonnet 5 as the default Claude model (#3620)

* Restore the ultrathink frame border effect (#3625)

* fix(dev): Fix electron dev launch and add test (#3662)

* Add adaptive split-view layout for iPad/mobile workspace (#3514)

Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: Julius Marminge <julius@mac.lan>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>

* fix(mobile): compile patched native pods from source on EAS (#3667)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>

* Make the thread composer read as elevated liquid glass (#3668)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>

* Upgrade Vite Plus and enable bundled dev opt-in (#3679)

* Surface pending tasks in mobile home and draft flow (#3670)

* fix(mobile): combined test branch — scroll, back-swipe, thread lists, computer switching (#3687)

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>

* Add repo-root favicon.svg so t3 code shows its own icon (#3683)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>

* Load thread snapshots over HTTP before live sync (#3719)

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>

* Fix mobile legend anchor under automatic iOS insets (#3684)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>

* Improve live activity routing and diagnostics (#3685)

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>

* Prevent Add Project sheet from collapsing on relayout (#3759)

* Use variant-specific splash icons in mobile app (#3762)

* Fix Expo widget asset wiring order (#3763)

* Extend Done display to 15 minutes and show up to 5 Live Activity banner rows (#3761)

* Clear VCS presentation state on finish (#3764)

* Lead with the outcome when no agents are active in the Live Activity (#3768)

* Add T3 Connect onboarding for mobile and web (#3765)

* Revert "Add T3 Connect onboarding for mobile and web" (#3776)

* Expose Clerk Google sign-in env vars to Expo (#3772)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>

* Set up Cursor Cloud dev environment (web + Android toolchain) (#3755)

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Theo Browne <t3dotgg@users.noreply.github.com>

* Revert "Revert "Add T3 Connect onboarding for mobile and web"" (#3777)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>

* Use rounded depth logo for production splash screen (#3780)

Co-authored-by: Cursor Agent <cursoragent@cursor.com>

* fix(release): stage pnpm 11 allowBuilds for desktop installs (#3781)

Co-authored-by: Cursor Agent <cursoragent@cursor.com>

* Upgrade Clerk toolchain to latest versions (#3785)

* fix(release): bump electron-builder so pnpm 11 deduped deps land in the asar (#3790)

* Fix desktop native optional dependency packaging (#3816)

* [codex] Upgrade Clerk stack (#3821)

Co-authored-by: codex <codex@users.noreply.github.com>

* [codex] Preserve worktree metadata during branch sync (#3822)

Co-authored-by: codex <codex@users.noreply.github.com>

* feat(client): persist offline environment data and mobile preferences (#3795)

Co-authored-by: Julius Marminge <julius@mac.lan>
Co-authored-by: codex <codex@users.noreply.github.com>

* [codex] Label max and ultra reasoning (#3824)

Co-authored-by: codex <codex@users.noreply.github.com>

* fix(mobile): embed fonts and render project favicons reliably (#3823)

Co-authored-by: codex <codex@users.noreply.github.com>

* Show compact PR number badges in mobile thread rows (#3827)

Co-authored-by: codex <codex@users.noreply.github.com>

* Expose mobile PR indicator labels to accessibility (#3828)

Co-authored-by: codex <codex@users.noreply.github.com>

* Fix truncated chat error alert layout (#3899)

* fix(marketing): show platform-appropriate commit shortcut on the website (#3644)

* [codex] Add Android mobile support (#3579)

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: Hugo Blom <6117705+huxcrux@users.noreply.github.com>
Co-authored-by: Julius Marminge <jmarminge@gmail.com>
Co-authored-by: Utkarsh Patil <73941998+UtkarshUsername@users.noreply.github.com>
Co-authored-by: Julius Marminge <julius0216@outlook.com>
Co-authored-by: Theo Browne <me@t3.gg>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: Julius Marminge <julius@mac.lan>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Theo Browne <t3dotgg@users.noreply.github.com>
Co-authored-by: Rowan <rowan@cardow.co>
Co-authored-by: Patricio Gómez Meneses <107218376+Prgm-code@users.noreply.github.com>
Co-authored-by: Jake Leventhal <jakeleventhal@me.com>
Co-authored-by: Vedank Purohit <VedankPurohit2@gmail.com>
Co-authored-by: Horus Lugo <horusgoul@gmail.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>
github-actions Bot added a commit to omarcresp/t3code-flake that referenced this pull request Jul 27, 2026
## What's Changed
* Add middle-click close for right panel tabs by @huxcrux in https://github.com/pingdotgg/t3code/pull/3161
* fix: warm WSL before preflight in WSL-only backend mode by @UtkarshUsername in https://github.com/pingdotgg/t3code/pull/3588
* Add Claude Sonnet 5 as the default Claude model by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3620
* Restore the ultrathink frame border effect by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3625
* fix(dev): Fix electron dev launch and add test by @t3dotgg in https://github.com/pingdotgg/t3code/pull/3662
* Add adaptive split-view layout for iPad/mobile workspace by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3514
* fix(mobile): compile patched native pods from source on EAS by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3667
* Make the thread composer read as elevated liquid glass by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3668
* Upgrade Vite Plus and enable bundled dev opt-in by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3679
* Surface pending tasks in mobile home and draft flow by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3670
* fix(mobile): combined test branch — scroll, back-swipe, thread lists, computer switching by @t3dotgg in https://github.com/pingdotgg/t3code/pull/3687
* Add repo-root favicon.svg so t3 code shows its own icon by @t3dotgg in https://github.com/pingdotgg/t3code/pull/3683
* Load thread snapshots over HTTP before live sync by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3719
* Fix mobile legend anchor under automatic iOS insets by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3684
* Improve live activity routing and diagnostics by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3685
* Prevent Add Project sheet from collapsing on relayout by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3759
* Use variant-specific splash icons in mobile app by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3762
* Fix Expo widget asset wiring order by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3763
* Extend Done display to 15 minutes and show up to 5 Live Activity banner rows by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3761
* Clear VCS presentation state on finish by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3764
* Lead with the outcome when no agents are active in the Live Activity by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3768
* Add T3 Connect onboarding for mobile and web by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3765
* Revert "Add T3 Connect onboarding for mobile and web" by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3776
* Expose Clerk Google sign-in env vars to Expo by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3772
* Set up Cursor Cloud dev environment (web + Android toolchain) by @t3dotgg in https://github.com/pingdotgg/t3code/pull/3755
* Revert "Revert "Add T3 Connect onboarding for mobile and web"" by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3777
* Use rounded depth logo for production splash screen by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3780
* fix(release): stage pnpm 11 allowBuilds for desktop installs by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3781
* Upgrade Clerk toolchain to latest versions by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3785
* fix(release): bump electron-builder so pnpm 11 deduped deps land in the asar by @avocardow in https://github.com/pingdotgg/t3code/pull/3790
* Fix desktop native optional dependency packaging by @Prgm-code in https://github.com/pingdotgg/t3code/pull/3816
* [codex] Upgrade Clerk stack by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3821
* [codex] Preserve worktree metadata during branch sync by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3822
* feat(client): persist offline environment data and mobile preferences by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3795
* [codex] Label max and ultra reasoning by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3824
* fix(mobile): embed fonts and render project favicons reliably by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3823
* Show compact PR number badges in mobile thread rows by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3827
* Expose mobile PR indicator labels to accessibility by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3828
* Fix truncated chat error alert layout by @jakeleventhal in https://github.com/pingdotgg/t3code/pull/3899
* fix(marketing): show platform-appropriate commit shortcut on the website by @VedankPurohit in https://github.com/pingdotgg/t3code/pull/3644
* [codex] Add Android mobile support by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3579
* Use client-side fallbacks for missing project favicons by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3959
* Skip stale working-task notifications by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3961
* Prepare Android beta branding and review diff UI by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3967
* perf(web): duty-cycle status animations and remove fixed noise overlay by @t3dotgg in https://github.com/pingdotgg/t3code/pull/3978
* fix(docs): correct CI task-runner commands in ci.md by @kridaydave in https://github.com/pingdotgg/t3code/pull/3990
* fix(docs): repair broken source links in architecture overview by @kridaydave in https://github.com/pingdotgg/t3code/pull/3991
* fix(docs): replace stale codething-mvp absolute paths with repo-relative links by @kridaydave in https://github.com/pingdotgg/t3code/pull/3992
* docs: Add T3 Code Legal Docs by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3972
* Fix Legal modal header crash by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4000
* [codex] Fix onboarding connection status by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4001
* Isolate native diff highlight grammar state by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4029
* Fix macOS fullscreen titlebar spacing by @D3OXY in https://github.com/pingdotgg/t3code/pull/4019
* Prevent duplicate project workspace roots by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3829
* Normalize over-indented markdown list items by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4020
* Resolve localhost preview URLs for remote environments by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4011
* fix(mobile): Send composer images in upload wire format by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4035
* Fix iOS terminal Enter input encoding by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4043
* Add native mobile share target support by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4021
* [codex] Expand real-route app store screenshot harness by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4014
* fix(server): use CLAUDE_CONFIG_DIR instead of HOME for Claude instanc… by @dmstoykov in https://github.com/pingdotgg/t3code/pull/4017
* Fix dropped events during initial thread snapshot by @D3OXY in https://github.com/pingdotgg/t3code/pull/4079
* feat: show nightly update changelog tooltip by @HugoVizcainoSantana in https://github.com/pingdotgg/t3code/pull/3832
* fix(git): treat selected commit paths literally by @EricTsai83 in https://github.com/pingdotgg/t3code/pull/3998
* fix(server): stabilize non-repository Git diagnostics by @EricTsai83 in https://github.com/pingdotgg/t3code/pull/4077
* Refresh app icons across release variants by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4080
* Update marketing GitHub star count by @AmoonPod in https://github.com/pingdotgg/t3code/pull/4088
* fix(marketing): correct Cursor icon color by @AmoonPod in https://github.com/pingdotgg/t3code/pull/4090
* Normalize protocol-relative remote host input as https by @kridaydave in https://github.com/pingdotgg/t3code/pull/3971
* fix(cursor): default binary path to cursor-agent (avoid path conflict w/ grok) by @BunnyGamezsc in https://github.com/pingdotgg/t3code/pull/4094
* Fix documented task-runner commands (bun run -> vp) by @kridaydave in https://github.com/pingdotgg/t3code/pull/3965
* Allow preview panel to grow on wide displays by @olivoil in https://github.com/pingdotgg/t3code/pull/4044
* fix: prevent initial right-click from selecting a context menu item by @Fazalkadivar21 in https://github.com/pingdotgg/t3code/pull/3877
* Fix duplicate keybinding rule when replacing with an existing rule by @kridaydave in https://github.com/pingdotgg/t3code/pull/3969
* fix(server): image upload crashed dispatchCommand with a stack overflow by @t3dotgg in https://github.com/pingdotgg/t3code/pull/3952
* Remove unused code parameter from describePreviewError by @kridaydave in https://github.com/pingdotgg/t3code/pull/3970
* [codex] prevent ACP assistant ID collisions after restarts by @maxwellyoung in https://github.com/pingdotgg/t3code/pull/3932
* fix(web): inset Windows desktop scrollbars from resize edge by @nateEc in https://github.com/pingdotgg/t3code/pull/4097
* [codex] fix mobile composer Enter behavior by @maxwellyoung in https://github.com/pingdotgg/t3code/pull/3930
* feat(server): include runtime model and effort in Codex developer instructions by @t3dotgg in https://github.com/pingdotgg/t3code/pull/3948
* fix(ux): spamming cmd + , no longer stack opening settings by @jamesx0416 in https://github.com/pingdotgg/t3code/pull/2757
* fix(terminal): strip AppImage runtime env from spawned terminals by @leorivastech in https://github.com/pingdotgg/t3code/pull/3108
* fix(server): thread cwd through Claude capability probe (#2048) by @mvanhorn in https://github.com/pingdotgg/t3code/pull/2124
* [codex] fix: guard invalid web timestamps by @StiensWout in https://github.com/pingdotgg/t3code/pull/3515
* [codex] fix: tolerate invalid latest user message timestamps by @StiensWout in https://github.com/pingdotgg/t3code/pull/3521
* [codex] Fix provider update checks restore defaults by @StiensWout in https://github.com/pingdotgg/t3code/pull/3531
* fix(server): skip undecodable provider runtime rows when listing sessions by @t3dotgg in https://github.com/pingdotgg/t3code/pull/3951
* Share MCP OAuth locks across Codex shadow homes by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4104
* Preserve T3 Code identity in macOS development launcher by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4102
* fix(web): increase contrast of question option descriptions by @xxashxx-svg in https://github.com/pingdotgg/t3code/pull/3867
* feat: draft hero landing on the index route by @yordis in https://github.com/pingdotgg/t3code/pull/4055
* feat: file explorer mention actions and zoom-aware context menus by @yordis in https://github.com/pingdotgg/t3code/pull/4054
* fix(mobile): restore iOS home screen branding by @PixPMusic in https://github.com/pingdotgg/t3code/pull/4025
* perf(client): defer active thread cache writes by @Chrrxs in https://github.com/pingdotgg/t3code/pull/4006
* Default diffs to working changes by @jakeleventhal in https://github.com/pingdotgg/t3code/pull/3974
* Add Grok to marketing site provider list by @Aditya190803 in https://github.com/pingdotgg/t3code/pull/3484
* Fix reopening existing Diff tab by @jakeleventhal in https://github.com/pingdotgg/t3code/pull/3973
* Fix sending messages during active turns by @jakeleventhal in https://github.com/pingdotgg/t3code/pull/3919
* [codex] Route OpenCode missing-session errors through Effect by @StiensWout in https://github.com/pingdotgg/t3code/pull/3608
* [fix/feat:ui] Show default option badge by @sandersonstabo in https://github.com/pingdotgg/t3code/pull/3232
* [fix/feat:ui] Preserve open-in editor brand colors by @sandersonstabo in https://github.com/pingdotgg/t3code/pull/3225
* fix(web): handle macOS Home and End in composer by @GuilhermeVieiraDev in https://github.com/pingdotgg/t3code/pull/2508
* Allow failed remote environments to be removed by @zepi2509 in https://github.com/pingdotgg/t3code/pull/4084
* [codex] canonicalize client timestamps by @maxwellyoung in https://github.com/pingdotgg/t3code/pull/4112
* [fix/feat:ui] Make selected menu checks blue by @sandersonstabo in https://github.com/pingdotgg/t3code/pull/3234
* fix(desktop): Validate WSL node version against engine range after probe success by @UtkarshUsername in https://github.com/pingdotgg/t3code/pull/3621
* Refresh splash screen and favicon branding by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4120
* Add terminal selection copy action by @tarik02 in https://github.com/pingdotgg/t3code/pull/2904
* Add isolated app testing workflow by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4121
* feat(web): themed sidebar header art for nightly and dev builds by @maria-rcks in https://github.com/pingdotgg/t3code/pull/4130
* feat: add headless `t3 connect` setup for SSH hosts by @t3dotgg in https://github.com/pingdotgg/t3code/pull/3749
* Refine T3 Connect authorization surfaces by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4159
* fix: increase OpenCode server startup timeout from 5s to 30s by @UtkarshUsername in https://github.com/pingdotgg/t3code/pull/4132
* fix(shared): delete unused agentAwareness phase predicates by @kridaydave in https://github.com/pingdotgg/t3code/pull/4134
* fix(mobile): Stabilize native stack option updates by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4037
* Make test-t3-app skill discoverable by Claude Code by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4162
* fix(web): improve dev sidebar backdrop contrast & remove version pills by @maria-rcks in https://github.com/pingdotgg/t3code/pull/4166
* Fix draft banner stack overlap by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4164
* Add portable mobile app testing guidance by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4165
* fix(client): use lightweight connection probe by @eeinarsson in https://github.com/pingdotgg/t3code/pull/4137
* fix(server): resolve Claude SDK executable path on Windows npm installs by @nsxdavid in https://github.com/pingdotgg/t3code/pull/3740
* Fix project action preview settings persistence by @keeperxy in https://github.com/pingdotgg/t3code/pull/3842
* fix(desktop): allow clipboard writes in the preview browser by @carlosricojr in https://github.com/pingdotgg/t3code/pull/3889
* fix(web): handle sidebar shortcut before editors by @Bortlesboat in https://github.com/pingdotgg/t3code/pull/3921
* fix(server): recognize Bedrock-backed Claude as authenticated by @PieterVanZyl-Dev in https://github.com/pingdotgg/t3code/pull/3931
* Fix incorrect pluralization of “entry” by @McMelonTV in https://github.com/pingdotgg/t3code/pull/3933
* feat(server): title background-task work-log rows with the task name by @t3dotgg in https://github.com/pingdotgg/t3code/pull/3751
* fix: delegate OpenCode session titles to provider by @tris203 in https://github.com/pingdotgg/t3code/pull/3720
* Archive selected threads from the context menu by @theduke in https://github.com/pingdotgg/t3code/pull/3895
* fix(cli): support force removing projects by @Bortlesboat in https://github.com/pingdotgg/t3code/pull/3922
* fix: allow sidebar to be shrunk when wider than viewport by @shoaib050326 in https://github.com/pingdotgg/t3code/pull/2456
* fix(codex): show web search query and url in tool call details by @GuilhermeVieiraDev in https://github.com/pingdotgg/t3code/pull/2093
* Add Codex launch arguments setting by @jamesx0416 in https://github.com/pingdotgg/t3code/pull/2892
* [orchestration] Clear stale active turn when session becomes inactive by @Andrew-Forster in https://github.com/pingdotgg/t3code/pull/3159
* Regenerate Codex reset credit protocol bindings by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4173
* fix(preview): preserve direct localhost navigation by @Chrrxs in https://github.com/pingdotgg/t3code/pull/3939
* Synchronize mobile threads with authoritative shell snapshots by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4163
* Gate iOS glass layout on native support by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4032
* fix(opencode): resume the OpenCode session on follow-ups instead of starting an empty one by @vdmkotai in https://github.com/pingdotgg/t3code/pull/3617
* fix(server): use CLI for OpenCode health check instead of spawning server by @UtkarshUsername in https://github.com/pingdotgg/t3code/pull/4153
* fix(web): scope timeline minimap hover target to the side gutter by @xxashxx-svg in https://github.com/pingdotgg/t3code/pull/3869
* [codex] show complete approval details by @maxwellyoung in https://github.com/pingdotgg/t3code/pull/4111
* fix(web): paint text selection over composer chips by @yordis in https://github.com/pingdotgg/t3code/pull/4139
* [codex] preserve custom model slugs by @maxwellyoung in https://github.com/pingdotgg/t3code/pull/4168
* fix(web): preview workspace images in the file panel by @Rhiz3K in https://github.com/pingdotgg/t3code/pull/3996
* feat(web): drag files from the explorer into the chat composer by @yordis in https://github.com/pingdotgg/t3code/pull/4140
* fix(desktop): preserve main window bounds by @anirudhsama in https://github.com/pingdotgg/t3code/pull/3851
* perf(orchestration): speed up new-chat propagation and offline catch-up by @RusiruSadathana in https://github.com/pingdotgg/t3code/pull/4177
* Finale: upgrade changed files card to fix various UI issues by @sandersonstabo in https://github.com/pingdotgg/t3code/pull/4113
* Pass CLI OAuth config to hosted web deploy by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4186
* fix(web): always show environment chip for remote projects by @t3dotgg in https://github.com/pingdotgg/t3code/pull/4217
* fix(web): keep composer editable while disconnected by @t3dotgg in https://github.com/pingdotgg/t3code/pull/4241
* fix: better defaults — Claude 1M context, Codex gpt-5.6, worktrees from origin main by @t3dotgg in https://github.com/pingdotgg/t3code/pull/4240
* fix(claude): handle all SDK stream messages; stop spurious work-log warning rows by @t3dotgg in https://github.com/pingdotgg/t3code/pull/4244
* Sidebar v2 beta: flat thread list with a server-backed settled lifecycle by @t3dotgg in https://github.com/pingdotgg/t3code/pull/4026
* fix(settings): validate the add-provider wizard step before advancing (#2813) by @leorivastech in https://github.com/pingdotgg/t3code/pull/3100
* fix(claude): isolate capability probe from user MCP servers by @jbbottoms in https://github.com/pingdotgg/t3code/pull/4015
* Preserve connecting status while a turn starts by @D3OXY in https://github.com/pingdotgg/t3code/pull/4101
* fix(server): stop restoring stale OpenCode models by @nateEc in https://github.com/pingdotgg/t3code/pull/4095
* [codex] keep scoped package references as text by @maxwellyoung in https://github.com/pingdotgg/t3code/pull/4167
* fix(web): default provider selection for users without Codex by @mfazekas in https://github.com/pingdotgg/t3code/pull/4117
* Unify temporary worktree branch naming by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4278
* fix(web): use message-square icon for settled icon-less project threads in sidebar v2 by @UtkarshUsername in https://github.com/pingdotgg/t3code/pull/4279
* Stabilize sidebar settling animations by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4280
* Restore Copy Link in chat link context menu by @caezium in https://github.com/pingdotgg/t3code/pull/4161
* fix(desktop): handle EPIPE errors on stdout/stderr to prevent crash dialog by @UtkarshUsername in https://github.com/pingdotgg/t3code/pull/4213
* Preserve draft thread highlighting during promotion by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4283
* Move mobile working timer into the thread timeline by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4285
* Stabilize PR status lookups and provider session lifecycle by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4281
* fix: open command palette instead of custom dialog for new thread picker in SidebarV2 by @UtkarshUsername in https://github.com/pingdotgg/t3code/pull/4269
* fix(server): don't drop sticky PR fallback when remote URL can't be resolved by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4289
* feat(web): copy branch name via right-click in the branch selector by @t3dotgg in https://github.com/pingdotgg/t3code/pull/4275
* Add remote server updates and standalone service management by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4286
* Refine light-mode sidebar surfaces by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4268
* fix(mobile): don't mark Android VPN/Tailscale as offline when connected by @Wraient in https://github.com/pingdotgg/t3code/pull/3949
* improve and prevent silent thread branch drift and PR fetching by @justsomelegs in https://github.com/pingdotgg/t3code/pull/2284
* Refresh web application surfaces and dark-mode dialogs by @maria-rcks in https://github.com/pingdotgg/t3code/pull/4319
* fix(web): new-thread defaults ignored for remote environments by @t3dotgg in https://github.com/pingdotgg/t3code/pull/4276
* feat: add "Auto" runtime mode — AI-reviewed approvals for Codex and Claude by @t3dotgg in https://github.com/pingdotgg/t3code/pull/4272
* Add shared t3.json project configuration support by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4317
* Unify dialog glass and fix composer overlays by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4365
* fix(web): warn before silent Windows updates by @nateEc in https://github.com/pingdotgg/t3code/pull/4350
* [codex] Move project grouping to General settings by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4313
* [codex] Group project scopes in mobile thread lists by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4314
* [codex] Move mobile project grouping to General settings by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4315
* [codex] Deduplicate connection failure messaging by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4367
* Restore grouped project filtering in Sidebar V2 by @shivamhwp in https://github.com/pingdotgg/t3code/pull/4282
* [codex] restore Sidebar V2 project actions by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4373
* [codex] Group projects in new-thread pickers by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4312
* fix(web): restore dark composer toolbar styling by @maria-rcks in https://github.com/pingdotgg/t3code/pull/4375
* Fix thread tooltip folder icon color by @maria-rcks in https://github.com/pingdotgg/t3code/pull/4383
* fix(server): parse CLI version in update preflight by @t3dotgg in https://github.com/pingdotgg/t3code/pull/4389
* fix(web): sidebar v2 polish — jump hints, working duration, in-flight fade, settled sort by @t3dotgg in https://github.com/pingdotgg/t3code/pull/4274
* Fix logical project grouping labels on mobile by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4391
* Add preview color scheme controls and simplify project grouping by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4385
* fix(cli): publish nightly branded favicons by @maria-rcks in https://github.com/pingdotgg/t3code/pull/4372
* Fix thread loading flash by @t3dotgg in https://github.com/pingdotgg/t3code/pull/4396
* fix(client-runtime): keep a warm thread un-settled despite a merged/closed PR by @t3dotgg in https://github.com/pingdotgg/t3code/pull/4309
* Fix composer context strip alignment and glass shell by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4404
* Polish iOS git progress overlay with glass effects by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4387
* Improve composer glass fallbacks by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4406
* feat(web): collapse large git diffs by default to make chat more readable by @t3dotgg in https://github.com/pingdotgg/t3code/pull/4409
* Stop new threads inheriting checkout/branch from viewed thread by @t3dotgg in https://github.com/pingdotgg/t3code/pull/4411
* fix: tone down branch-mismatch banner by @t3dotgg in https://github.com/pingdotgg/t3code/pull/4416
* fix: Claude Code skills discoverable for the composer $ picker by @t3dotgg in https://github.com/pingdotgg/t3code/pull/4414
* fix(web): keep settled threads reachable when opened directly by @t3dotgg in https://github.com/pingdotgg/t3code/pull/4413
* feat(sidebar-v2): thread snoozing by @t3dotgg in https://github.com/pingdotgg/t3code/pull/4311
* Upgrade Clerk packages and Expo integration by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4440
* Increase light-mode contrast for user message bubbles by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4441
* Restore model picker layout and retain iterative test state by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4450
* Color settled PR labels on hover by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4451
* [codex] Fix glass hover compositing artifacts by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4446
* Add Claude Opus 5 model by @thomaslittle in https://github.com/pingdotgg/t3code/pull/4472
* feat(web): add collapse-all toggle to diff panel by @0x4bs3nt in https://github.com/pingdotgg/t3code/pull/4475
* feat(web): show fast mode as a bolt instead of a "Normal" label by @t3dotgg in https://github.com/pingdotgg/t3code/pull/4488
* feat(dev): keep worktree dev state isolated on T3 Code dev servers by @t3dotgg in https://github.com/pingdotgg/t3code/pull/4555
* feat(dev): Make t3 code dev instances shareable over Tailscale by @t3dotgg in https://github.com/pingdotgg/t3code/pull/4556
* fix(dev): skip browser-blocked ports by @t3dotgg in https://github.com/pingdotgg/t3code/pull/4608
* fix: cut websocket throughput in half by pruning activity payloads by @t3dotgg in https://github.com/pingdotgg/t3code/pull/4622
* perf(mobile): defer work-log detail serialization by @saphid in https://github.com/pingdotgg/t3code/pull/4607
* test: account for lazy thread feed details by @t3dotgg in https://github.com/pingdotgg/t3code/pull/4628
* feat(relay): limit managed tunnels per user by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4530
* Add managed tunnel limits migration by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4635
* Add background preview capture and picture-in-picture support by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4397
* feat(web): prompt stash — cmd+S saves the composer to a per-provider queue by @t3dotgg in https://github.com/pingdotgg/t3code/pull/4453
* [codex] Upgrade Effect and Alchemy betas by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4643
* feat: allow new thread creation through project breadcrumbs by @0x4bs3nt in https://github.com/pingdotgg/t3code/pull/4638
* fix(web): scope PR state to the thread branch by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4460
* Drop redundant Relay user indexes by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4648
* feat(connect): release the Cloudflare tunnel when the environment shuts down by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4531
* Fix Relay Worker RuntimeContext wiring by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4653
* Fix live sidebar resize limits and defer Alchemy runtime context by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4655
* fix(web): constrain branch toolbar context by @maxktz in https://github.com/pingdotgg/t3code/pull/4657
* Keep MCP credentials alive across provider turns by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4659
* fix: close actions dropdown when editing by @0x4bs3nt in https://github.com/pingdotgg/t3code/pull/4660
* fix(preview): stabilize PiP viewport identity by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4661
* Add glass styling for thread tooltips and simplify preview tab handling by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4665
* Use tarball archiving for hosted web deploys by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4669
* fix(server): bound editor discovery during config loading by @maria-rcks in https://github.com/pingdotgg/t3code/pull/4291
* Prevent draft thread detail polling before shell registration by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4670
* feat: add configurable source control writing settings by @maria-rcks in https://github.com/pingdotgg/t3code/pull/4204
* feat(diff-panel): show total line additions and deletions by @0x4bs3nt in https://github.com/pingdotgg/t3code/pull/4674
* Clear provider update actions while updating by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4676
* Fix sidebar highlighting for draft threads by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4679
* Use glass surfaces for web toasts by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4681
* Show origin ref in branch trigger label by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4680
* fix(mobile): match react version to react-native 0.85.3 vendored renderer (19.2.3) by @KrzysztofMoch in https://github.com/pingdotgg/t3code/pull/4675

## New Contributors
* @avocardow made their first contribution in https://github.com/pingdotgg/t3code/pull/3790
* @Prgm-code made their first contribution in https://github.com/pingdotgg/t3code/pull/3816
* @jakeleventhal made their first contribution in https://github.com/pingdotgg/t3code/pull/3899
* @VedankPurohit made their first contribution in https://github.com/pingdotgg/t3code/pull/3644
* @kridaydave made their first contribution in https://github.com/pingdotgg/t3code/pull/3990
* @dmstoykov made their first contribution in https://github.com/pingdotgg/t3code/pull/4017
* @HugoVizcainoSantana made their first contribution in https://github.com/pingdotgg/t3code/pull/3832
* @EricTsai83 made their first contribution in https://github.com/pingdotgg/t3code/pull/3998
* @AmoonPod made their first contribution in https://github.com/pingdotgg/t3code/pull/4088
* @BunnyGamezsc made their first contribution in https://github.com/pingdotgg/t3code/pull/4094
* @olivoil made their first contribution in https://github.com/pingdotgg/t3code/pull/4044
* @Fazalkadivar21 made their first contribution in https://github.com/pingdotgg/t3code/pull/3877
* @maxwellyoung made their first contribution in https://github.com/pingdotgg/t3code/pull/3932
* @nateEc made their first contribution in https://github.com/pingdotgg/t3code/pull/4097
* @leorivastech made their first contribution in https://github.com/pingdotgg/t3code/pull/3108
* @xxashxx-svg made their first contribution in https://github.com/pingdotgg/t3code/pull/3867
* @yordis made their first contribution in https://github.com/pingdotgg/t3code/pull/4055
* @Chrrxs made their first contribution in https://github.com/pingdotgg/t3code/pull/4006
* @Aditya190803 made their first contribution in https://github.com/pingdotgg/t3code/pull/3484
* @zepi2509 made their first contribution in https://github.com/pingdotgg/t3code/pull/4084
* @eeinarsson made their first contribution in https://github.com/pingdotgg/t3code/pull/4137
* @keeperxy made their first contribution in https://github.com/pingdotgg/t3code/pull/3842
* @carlosricojr made their first contribution in https://github.com/pingdotgg/t3code/pull/3889
* @Bortlesboat made their first contribution in https://github.com/pingdotgg/t3code/pull/3921
* @PieterVanZyl-Dev made their first contribution in https://github.com/pingdotgg/t3code/pull/3931
* @McMelonTV made their first contribution in https://github.com/pingdotgg/t3code/pull/3933
* @tris203 made their first contribution in https://github.com/pingdotgg/t3code/pull/3720
* @theduke made their first contribution in https://github.com/pingdotgg/t3code/pull/3895
* @shoaib050326 made their first contribution in https://github.com/pingdotgg/t3code/pull/2456
* @vdmkotai made their first contribution in https://github.com/pingdotgg/t3code/pull/3617
* @Rhiz3K made their first contribution in https://github.com/pingdotgg/t3code/pull/3996
* @anirudhsama made their first contribution in https://github.com/pingdotgg/t3code/pull/3851
* @RusiruSadathana made their first contribution in https://github.com/pingdotgg/t3code/pull/4177
* @jbbottoms made their first contribution in https://github.com/pingdotgg/t3code/pull/4015
* @mfazekas made their first contribution in https://github.com/pingdotgg/t3code/pull/4117
* @caezium made their first contribution in https://github.com/pingdotgg/t3code/pull/4161
* @Wraient made their first contribution in https://github.com/pingdotgg/t3code/pull/3949
* @thomaslittle made their first contribution in https://github.com/pingdotgg/t3code/pull/4472
* @0x4bs3nt made their first contribution in https://github.com/pingdotgg/t3code/pull/4475
* @saphid made their first contribution in https://github.com/pingdotgg/t3code/pull/4607
* @maxktz made their first contribution in https://github.com/pingdotgg/t3code/pull/4657
* @KrzysztofMoch made their first contribution in https://github.com/pingdotgg/t3code/pull/4675

**Full Changelog**: https://github.com/pingdotgg/t3code/compare/v0.0.28...v0.0.29

## What's Changed
* Add middle-click close for right panel tabs by @huxcrux in https://github.com/pingdotgg/t3code/pull/3161
* fix: warm WSL before preflight in WSL-only backend mode by @UtkarshUsername in https://github.com/pingdotgg/t3code/pull/3588
* Add Claude Sonnet 5 as the default Claude model by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3620
* Restore the ultrathink frame border effect by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3625
* fix(dev): Fix electron dev launch and add test by @t3dotgg in https://github.com/pingdotgg/t3code/pull/3662
* Add adaptive split-view layout for iPad/mobile workspace by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3514
* fix(mobile): compile patched native pods from source on EAS by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3667
* Make the thread composer read as elevated liquid glass by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3668
* Upgrade Vite Plus and enable bundled dev opt-in by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3679
* Surface pending tasks in mobile home and draft flow by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3670
* fix(mobile): combined test branch — scroll, back-swipe, thread lists, computer switching by @t3dotgg in https://github.com/pingdotgg/t3code/pull/3687
* Add repo-root favicon.svg so t3 code shows its own icon by @t3dotgg in https://github.com/pingdotgg/t3code/pull/3683
* Load thread snapshots over HTTP before live sync by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3719
* Fix mobile legend anchor under automatic iOS insets by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3684
* Improve live activity routing and diagnostics by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3685
* Prevent Add Project sheet from collapsing on relayout by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3759
* Use variant-specific splash icons in mobile app by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3762
* Fix Expo widget asset wiring order by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3763
* Extend Done display to 15 minutes and show up to 5 Live Activity banner rows by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3761
* Clear VCS presentation state on finish by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3764
* Lead with the outcome when no agents are active in the Live Activity by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3768
* Add T3 Connect onboarding for mobile and web by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3765
* Revert "Add T3 Connect onboarding for mobile and web" by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3776
* Expose Clerk Google sign-in env vars to Expo by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3772
* Set up Cursor Cloud dev environment (web + Android toolchain) by @t3dotgg in https://github.com/pingdotgg/t3code/pull/3755
* Revert "Revert "Add T3 Connect onboarding for mobile and web"" by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3777
* Use rounded depth logo for production splash screen by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3780
* fix(release): stage pnpm 11 allowBuilds for desktop installs by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3781
* Upgrade Clerk toolchain to latest versions by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3785
* fix(release): bump electron-builder so pnpm 11 deduped deps land in the asar by @avocardow in https://github.com/pingdotgg/t3code/pull/3790
* Fix desktop native optional dependency packaging by @Prgm-code in https://github.com/pingdotgg/t3code/pull/3816
* [codex] Upgrade Clerk stack by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3821
* [codex] Preserve worktree metadata during branch sync by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3822
* feat(client): persist offline environment data and mobile preferences by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3795
* [codex] Label max and ultra reasoning by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3824
* fix(mobile): embed fonts and render project favicons reliably by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3823
* Show compact PR number badges in mobile thread rows by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3827
* Expose mobile PR indicator labels to accessibility by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3828
* Fix truncated chat error alert layout by @jakeleventhal in https://github.com/pingdotgg/t3code/pull/3899
* fix(marketing): show platform-appropriate commit shortcut on the website by @VedankPurohit in https://github.com/pingdotgg/t3code/pull/3644
* [codex] Add Android mobile support by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3579
* Use client-side fallbacks for missing project favicons by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3959
* Skip stale working-task notifications by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3961
* Prepare Android beta branding and review diff UI by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3967
* perf(web): duty-cycle status animations and remove fixed noise overlay by @t3dotgg in https://github.com/pingdotgg/t3code/pull/3978
* fix(docs): correct CI task-runner commands in ci.md by @kridaydave in https://github.com/pingdotgg/t3code/pull/3990
* fix(docs): repair broken source links in architecture overview by @kridaydave in https://github.com/pingdotgg/t3code/pull/3991
* fix(docs): replace stale codething-mvp absolute paths with repo-relative links by @kridaydave in https://github.com/pingdotgg/t3code/pull/3992
* docs: Add T3 Code Legal Docs by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3972
* Fix Legal modal header crash by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4000
* [codex] Fix onboarding connection status by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4001
* Isolate native diff highlight grammar state by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4029
* Fix macOS fullscreen titlebar spacing by @D3OXY in https://github.com/pingdotgg/t3code/pull/4019
* Prevent duplicate project workspace roots by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/3829
* Normalize over-indented markdown list items by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4020
* Resolve localhost preview URLs for remote environments by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4011
* fix(mobile): Send composer images in upload wire format by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4035
* Fix iOS terminal Enter input encoding by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4043
* Add native mobile share target support by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4021
* [codex] Expand real-route app store screenshot harness by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4014
* fix(server): use CLAUDE_CONFIG_DIR instead of HOME for Claude instanc… by @dmstoykov in https://github.com/pingdotgg/t3code/pull/4017
* Fix dropped events during initial thread snapshot by @D3OXY in https://github.com/pingdotgg/t3code/pull/4079
* feat: show nightly update changelog tooltip by @HugoVizcainoSantana in https://github.com/pingdotgg/t3code/pull/3832
* fix(git): treat selected commit paths literally by @EricTsai83 in https://github.com/pingdotgg/t3code/pull/3998
* fix(server): stabilize non-repository Git diagnostics by @EricTsai83 in https://github.com/pingdotgg/t3code/pull/4077
* Refresh app icons across release variants by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4080
* Update marketing GitHub star count by @AmoonPod in https://github.com/pingdotgg/t3code/pull/4088
* fix(marketing): correct Cursor icon color by @AmoonPod in https://github.com/pingdotgg/t3code/pull/4090
* Normalize protocol-relative remote host input as https by @kridaydave in https://github.com/pingdotgg/t3code/pull/3971
* fix(cursor): default binary path to cursor-agent (avoid path conflict w/ grok) by @BunnyGamezsc in https://github.com/pingdotgg/t3code/pull/4094
* Fix documented task-runner commands (bun run -> vp) by @kridaydave in https://github.com/pingdotgg/t3code/pull/3965
* Allow preview panel to grow on wide displays by @olivoil in https://github.com/pingdotgg/t3code/pull/4044
* fix: prevent initial right-click from selecting a context menu item by @Fazalkadivar21 in https://github.com/pingdotgg/t3code/pull/3877
* Fix duplicate keybinding rule when replacing with an existing rule by @kridaydave in https://github.com/pingdotgg/t3code/pull/3969
* fix(server): image upload crashed dispatchCommand with a stack overflow by @t3dotgg in https://github.com/pingdotgg/t3code/pull/3952
* Remove unused code parameter from describePreviewError by @kridaydave in https://github.com/pingdotgg/t3code/pull/3970
* [codex] prevent ACP assistant ID collisions after restarts by @maxwellyoung in https://github.com/pingdotgg/t3code/pull/3932
* fix(web): inset Windows desktop scrollbars from resize edge by @nateEc in https://github.com/pingdotgg/t3code/pull/4097
* [codex] fix mobile composer Enter behavior by @maxwellyoung in https://github.com/pingdotgg/t3code/pull/3930
* feat(server): include runtime model and effort in Codex developer instructions by @t3dotgg in https://github.com/pingdotgg/t3code/pull/3948
* fix(ux): spamming cmd + , no longer stack opening settings by @jamesx0416 in https://github.com/pingdotgg/t3code/pull/2757
* fix(terminal): strip AppImage runtime env from spawned terminals by @leorivastech in https://github.com/pingdotgg/t3code/pull/3108
* fix(server): thread cwd through Claude capability probe (#2048) by @mvanhorn in https://github.com/pingdotgg/t3code/pull/2124
* [codex] fix: guard invalid web timestamps by @StiensWout in https://github.com/pingdotgg/t3code/pull/3515
* [codex] fix: tolerate invalid latest user message timestamps by @StiensWout in https://github.com/pingdotgg/t3code/pull/3521
* [codex] Fix provider update checks restore defaults by @StiensWout in https://github.com/pingdotgg/t3code/pull/3531
* fix(server): skip undecodable provider runtime rows when listing sessions by @t3dotgg in https://github.com/pingdotgg/t3code/pull/3951
* Share MCP OAuth locks across Codex shadow homes by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4104
* Preserve T3 Code identity in macOS development launcher by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4102
* fix(web): increase contrast of question option descriptions by @xxashxx-svg in https://github.com/pingdotgg/t3code/pull/3867
* feat: draft hero landing on the index route by @yordis in https://github.com/pingdotgg/t3code/pull/4055
* feat: file explorer mention actions and zoom-aware context menus by @yordis in https://github.com/pingdotgg/t3code/pull/4054
* fix(mobile): restore iOS home screen branding by @PixPMusic in https://github.com/pingdotgg/t3code/pull/4025
* perf(client): defer active thread cache writes by @Chrrxs in https://github.com/pingdotgg/t3code/pull/4006
* Default diffs to working changes by @jakeleventhal in https://github.com/pingdotgg/t3code/pull/3974
* Add Grok to marketing site provider list by @Aditya190803 in https://github.com/pingdotgg/t3code/pull/3484
* Fix reopening existing Diff tab by @jakeleventhal in https://github.com/pingdotgg/t3code/pull/3973
* Fix sending messages during active turns by @jakeleventhal in https://github.com/pingdotgg/t3code/pull/3919
* [codex] Route OpenCode missing-session errors through Effect by @StiensWout in https://github.com/pingdotgg/t3code/pull/3608
* [fix/feat:ui] Show default option badge by @sandersonstabo in https://github.com/pingdotgg/t3code/pull/3232
* [fix/feat:ui] Preserve open-in editor brand colors by @sandersonstabo in https://github.com/pingdotgg/t3code/pull/3225
* fix(web): handle macOS Home and End in composer by @GuilhermeVieiraDev in https://github.com/pingdotgg/t3code/pull/2508
* Allow failed remote environments to be removed by @zepi2509 in https://github.com/pingdotgg/t3code/pull/4084
* [codex] canonicalize client timestamps by @maxwellyoung in https://github.com/pingdotgg/t3code/pull/4112
* [fix/feat:ui] Make selected menu checks blue by @sandersonstabo in https://github.com/pingdotgg/t3code/pull/3234
* fix(desktop): Validate WSL node version against engine range after probe success by @UtkarshUsername in https://github.com/pingdotgg/t3code/pull/3621
* Refresh splash screen and favicon branding by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4120
* Add terminal selection copy action by @tarik02 in https://github.com/pingdotgg/t3code/pull/2904
* Add isolated app testing workflow by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4121
* feat(web): themed sidebar header art for nightly and dev builds by @maria-rcks in https://github.com/pingdotgg/t3code/pull/4130
* feat: add headless `t3 connect` setup for SSH hosts by @t3dotgg in https://github.com/pingdotgg/t3code/pull/3749
* Refine T3 Connect authorization surfaces by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4159
* fix: increase OpenCode server startup timeout from 5s to 30s by @UtkarshUsername in https://github.com/pingdotgg/t3code/pull/4132
* fix(shared): delete unused agentAwareness phase predicates by @kridaydave in https://github.com/pingdotgg/t3code/pull/4134
* fix(mobile): Stabilize native stack option updates by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4037
* Make test-t3-app skill discoverable by Claude Code by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4162
* fix(web): improve dev sidebar backdrop contrast & remove version pills by @maria-rcks in https://github.com/pingdotgg/t3code/pull/4166
* Fix draft banner stack overlap by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4164
* Add portable mobile app testing guidance by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4165
* fix(client): use lightweight connection probe by @eeinarsson in https://github.com/pingdotgg/t3code/pull/4137
* fix(server): resolve Claude SDK executable path on Windows npm installs by @nsxdavid in https://github.com/pingdotgg/t3code/pull/3740
* Fix project action preview settings persistence by @keeperxy in https://github.com/pingdotgg/t3code/pull/3842
* fix(desktop): allow clipboard writes in the preview browser by @carlosricojr in https://github.com/pingdotgg/t3code/pull/3889
* fix(web): handle sidebar shortcut before editors by @Bortlesboat in https://github.com/pingdotgg/t3code/pull/3921
* fix(server): recognize Bedrock-backed Claude as authenticated by @PieterVanZyl-Dev in https://github.com/pingdotgg/t3code/pull/3931
* Fix incorrect pluralization of “entry” by @McMelonTV in https://github.com/pingdotgg/t3code/pull/3933
* feat(server): title background-task work-log rows with the task name by @t3dotgg in https://github.com/pingdotgg/t3code/pull/3751
* fix: delegate OpenCode session titles to provider by @tris203 in https://github.com/pingdotgg/t3code/pull/3720
* Archive selected threads from the context menu by @theduke in https://github.com/pingdotgg/t3code/pull/3895
* fix(cli): support force removing projects by @Bortlesboat in https://github.com/pingdotgg/t3code/pull/3922
* fix: allow sidebar to be shrunk when wider than viewport by @shoaib050326 in https://github.com/pingdotgg/t3code/pull/2456
* fix(codex): show web search query and url in tool call details by @GuilhermeVieiraDev in https://github.com/pingdotgg/t3code/pull/2093
* Add Codex launch arguments setting by @jamesx0416 in https://github.com/pingdotgg/t3code/pull/2892
* [orchestration] Clear stale active turn when session becomes inactive by @Andrew-Forster in https://github.com/pingdotgg/t3code/pull/3159
* Regenerate Codex reset credit protocol bindings by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4173
* fix(preview): preserve direct localhost navigation by @Chrrxs in https://github.com/pingdotgg/t3code/pull/3939
* Synchronize mobile threads with authoritative shell snapshots by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4163
* Gate iOS glass layout on native support by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4032
* fix(opencode): resume the OpenCode session on follow-ups instead of starting an empty one by @vdmkotai in https://github.com/pingdotgg/t3code/pull/3617
* fix(server): use CLI for OpenCode health check instead of spawning server by @UtkarshUsername in https://github.com/pingdotgg/t3code/pull/4153
* fix(web): scope timeline minimap hover target to the side gutter by @xxashxx-svg in https://github.com/pingdotgg/t3code/pull/3869
* [codex] show complete approval details by @maxwellyoung in https://github.com/pingdotgg/t3code/pull/4111
* fix(web): paint text selection over composer chips by @yordis in https://github.com/pingdotgg/t3code/pull/4139
* [codex] preserve custom model slugs by @maxwellyoung in https://github.com/pingdotgg/t3code/pull/4168
* fix(web): preview workspace images in the file panel by @Rhiz3K in https://github.com/pingdotgg/t3code/pull/3996
* feat(web): drag files from the explorer into the chat composer by @yordis in https://github.com/pingdotgg/t3code/pull/4140
* fix(desktop): preserve main window bounds by @anirudhsama in https://github.com/pingdotgg/t3code/pull/3851
* perf(orchestration): speed up new-chat propagation and offline catch-up by @RusiruSadathana in https://github.com/pingdotgg/t3code/pull/4177
* Finale: upgrade changed files card to fix various UI issues by @sandersonstabo in https://github.com/pingdotgg/t3code/pull/4113
* Pass CLI OAuth config to hosted web deploy by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4186
* fix(web): always show environment chip for remote projects by @t3dotgg in https://github.com/pingdotgg/t3code/pull/4217
* fix(web): keep composer editable while disconnected by @t3dotgg in https://github.com/pingdotgg/t3code/pull/4241
* fix: better defaults — Claude 1M context, Codex gpt-5.6, worktrees from origin main by @t3dotgg in https://github.com/pingdotgg/t3code/pull/4240
* fix(claude): handle all SDK stream messages; stop spurious work-log warning rows by @t3dotgg in https://github.com/pingdotgg/t3code/pull/4244
* Sidebar v2 beta: flat thread list with a server-backed settled lifecycle by @t3dotgg in https://github.com/pingdotgg/t3code/pull/4026
* fix(settings): validate the add-provider wizard step before advancing (#2813) by @leorivastech in https://github.com/pingdotgg/t3code/pull/3100
* fix(claude): isolate capability probe from user MCP servers by @jbbottoms in https://github.com/pingdotgg/t3code/pull/4015
* Preserve connecting status while a turn starts by @D3OXY in https://github.com/pingdotgg/t3code/pull/4101
* fix(server): stop restoring stale OpenCode models by @nateEc in https://github.com/pingdotgg/t3code/pull/4095
* [codex] keep scoped package references as text by @maxwellyoung in https://github.com/pingdotgg/t3code/pull/4167
* fix(web): default provider selection for users without Codex by @mfazekas in https://github.com/pingdotgg/t3code/pull/4117
* Unify temporary worktree branch naming by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4278
* fix(web): use message-square icon for settled icon-less project threads in sidebar v2 by @UtkarshUsername in https://github.com/pingdotgg/t3code/pull/4279
* Stabilize sidebar settling animations by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4280
* Restore Copy Link in chat link context menu by @caezium in https://github.com/pingdotgg/t3code/pull/4161
* fix(desktop): handle EPIPE errors on stdout/stderr to prevent crash dialog by @UtkarshUsername in https://github.com/pingdotgg/t3code/pull/4213
* Preserve draft thread highlighting during promotion by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4283
* Move mobile working timer into the thread timeline by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4285
* Stabilize PR status lookups and provider session lifecycle by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4281
* fix: open command palette instead of custom dialog for new thread picker in SidebarV2 by @UtkarshUsername in https://github.com/pingdotgg/t3code/pull/4269
* fix(server): don't drop sticky PR fallback when remote URL can't be resolved by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4289
* feat(web): copy branch name via right-click in the branch selector by @t3dotgg in https://github.com/pingdotgg/t3code/pull/4275
* Add remote server updates and standalone service management by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4286
* Refine light-mode sidebar surfaces by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4268
* fix(mobile): don't mark Android VPN/Tailscale as offline when connected by @Wraient in https://github.com/pingdotgg/t3code/pull/3949
* improve and prevent silent thread branch drift and PR fetching by @justsomelegs in https://github.com/pingdotgg/t3code/pull/2284
* Refresh web application surfaces and dark-mode dialogs by @maria-rcks in https://github.com/pingdotgg/t3code/pull/4319
* fix(web): new-thread defaults ignored for remote environments by @t3dotgg in https://github.com/pingdotgg/t3code/pull/4276
* feat: add "Auto" runtime mode — AI-reviewed approvals for Codex and Claude by @t3dotgg in https://github.com/pingdotgg/t3code/pull/4272
* Add shared t3.json project configuration support by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4317
* Unify dialog glass and fix composer overlays by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4365
* fix(web): warn before silent Windows updates by @nateEc in https://github.com/pingdotgg/t3code/pull/4350
* [codex] Move project grouping to General settings by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4313
* [codex] Group project scopes in mobile thread lists by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4314
* [codex] Move mobile project grouping to General settings by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4315
* [codex] Deduplicate connection failure messaging by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4367
* Restore grouped project filtering in Sidebar V2 by @shivamhwp in https://github.com/pingdotgg/t3code/pull/4282
* [codex] restore Sidebar V2 project actions by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4373
* [codex] Group projects in new-thread pickers by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4312
* fix(web): restore dark composer toolbar styling by @maria-rcks in https://github.com/pingdotgg/t3code/pull/4375
* Fix thread tooltip folder icon color by @maria-rcks in https://github.com/pingdotgg/t3code/pull/4383
* fix(server): parse CLI version in update preflight by @t3dotgg in https://github.com/pingdotgg/t3code/pull/4389
* fix(web): sidebar v2 polish — jump hints, working duration, in-flight fade, settled sort by @t3dotgg in https://github.com/pingdotgg/t3code/pull/4274
* Fix logical project grouping labels on mobile by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4391
* Add preview color scheme controls and simplify project grouping by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4385
* fix(cli): publish nightly branded favicons by @maria-rcks in https://github.com/pingdotgg/t3code/pull/4372
* Fix thread loading flash by @t3dotgg in https://github.com/pingdotgg/t3code/pull/4396
* fix(client-runtime): keep a warm thread un-settled despite a merged/closed PR by @t3dotgg in https://github.com/pingdotgg/t3code/pull/4309
* Fix composer context strip alignment and glass shell by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4404
* Polish iOS git progress overlay with glass effects by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4387
* Improve composer glass fallbacks by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4406
* feat(web): collapse large git diffs by default to make chat more readable by @t3dotgg in https://github.com/pingdotgg/t3code/pull/4409
* Stop new threads inheriting checkout/branch from viewed thread by @t3dotgg in https://github.com/pingdotgg/t3code/pull/4411
* fix: tone down branch-mismatch banner by @t3dotgg in https://github.com/pingdotgg/t3code/pull/4416
* fix: Claude Code skills discoverable for the composer $ picker by @t3dotgg in https://github.com/pingdotgg/t3code/pull/4414
* fix(web): keep settled threads reachable when opened directly by @t3dotgg in https://github.com/pingdotgg/t3code/pull/4413
* feat(sidebar-v2): thread snoozing by @t3dotgg in https://github.com/pingdotgg/t3code/pull/4311
* Upgrade Clerk packages and Expo integration by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4440
* Increase light-mode contrast for user message bubbles by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4441
* Restore model picker layout and retain iterative test state by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4450
* Color settled PR labels on hover by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4451
* [codex] Fix glass hover compositing artifacts by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4446
* Add Claude Opus 5 model by @thomaslittle in https://github.com/pingdotgg/t3code/pull/4472
* feat(web): add collapse-all toggle to diff panel by @0x4bs3nt in https://github.com/pingdotgg/t3code/pull/4475
* feat(web): show fast mode as a bolt instead of a "Normal" label by @t3dotgg in https://github.com/pingdotgg/t3code/pull/4488
* feat(dev): keep worktree dev state isolated on T3 Code dev servers by @t3dotgg in https://github.com/pingdotgg/t3code/pull/4555
* feat(dev): Make t3 code dev instances shareable over Tailscale by @t3dotgg in https://github.com/pingdotgg/t3code/pull/4556
* fix(dev): skip browser-blocked ports by @t3dotgg in https://github.com/pingdotgg/t3code/pull/4608
* fix: cut websocket throughput in half by pruning activity payloads by @t3dotgg in https://github.com/pingdotgg/t3code/pull/4622
* perf(mobile): defer work-log detail serialization by @saphid in https://github.com/pingdotgg/t3code/pull/4607
* test: account for lazy thread feed details by @t3dotgg in https://github.com/pingdotgg/t3code/pull/4628
* feat(relay): limit managed tunnels per user by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4530
* Add managed tunnel limits migration by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4635
* Add background preview capture and picture-in-picture support by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4397
* feat(web): prompt stash — cmd+S saves the composer to a per-provider queue by @t3dotgg in https://github.com/pingdotgg/t3code/pull/4453
* [codex] Upgrade Effect and Alchemy betas by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4643
* feat: allow new thread creation through project breadcrumbs by @0x4bs3nt in https://github.com/pingdotgg/t3code/pull/4638
* fix(web): scope PR state to the thread branch by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4460
* Drop redundant Relay user indexes by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4648
* feat(connect): release the Cloudflare tunnel when the environment shuts down by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4531
* Fix Relay Worker RuntimeContext wiring by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4653
* Fix live sidebar resize limits and defer Alchemy runtime context by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4655
* fix(web): constrain branch toolbar context by @maxktz in https://github.com/pingdotgg/t3code/pull/4657
* Keep MCP credentials alive across provider turns by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4659
* fix: close actions dropdown when editing by @0x4bs3nt in https://github.com/pingdotgg/t3code/pull/4660
* fix(preview): stabilize PiP viewport identity by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4661
* Add glass styling for thread tooltips and simplify preview tab handling by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4665
* Use tarball archiving for hosted web deploys by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4669
* fix(server): bound editor discovery during config loading by @maria-rcks in https://github.com/pingdotgg/t3code/pull/4291
* Prevent draft thread detail polling before shell registration by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4670
* feat: add configurable source control writing settings by @maria-rcks in https://github.com/pingdotgg/t3code/pull/4204
* feat(diff-panel): show total line additions and deletions by @0x4bs3nt in https://github.com/pingdotgg/t3code/pull/4674
* Clear provider update actions while updating by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4676
* Fix sidebar highlighting for draft threads by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4679
* Use glass surfaces for web toasts by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4681
* Show origin ref in branch trigger label by @juliusmarminge in https://github.com/pingdotgg/t3code/pull/4680
* fix(mobile): match react version to react-native 0.85.3 vendored renderer (19.2.3) by @KrzysztofMoch in https://github.com/pingdotgg/t3code/pull/4675

## New Contributors
* @avocardow made their first contribution in https://github.com/pingdotgg/t3code/pull/3790
* @Prgm-code made their first contribution in https://github.com/pingdotgg/t3code/pull/3816
* @jakeleventhal made their first contribution in https://github.com/pingdotgg/t3code/pull/3899
* @VedankPurohit made their first contribution in https://github.com/pingdotgg/t3code/pull/3644
* @kridaydave made their first contribution in https://github.com/pingdotgg/t3code/pull/3990
* @dmstoykov made their first contribution in https://github.com/pingdotgg/t3code/pull/4017
* @HugoVizcainoSantana made their first contribution in https://github.com/pingdotgg/t3code/pull/3832
* @EricTsai83 made their first contribution in https://github.com/pingdotgg/t3code/pull/3998
* @AmoonPod made their first contribution in https://github.com/pingdotgg/t3code/pull/4088
* @BunnyGamezsc made their first contribution in https://github.com/pingdotgg/t3code/pull/4094
* @olivoil made their first contribution in https://github.com/pingdotgg/t3code/pull/4044
* @Fazalkadivar21 made their first contribution in https://github.com/pingdotgg/t3code/pull/3877
* @maxwellyoung made their first contribution in https://github.com/pingdotgg/t3code/pull/3932
* @nateEc made their first contribution in https://github.com/pingdotgg/t3code/pull/4097
* @leorivastech made their first contribution in https://github.com/pingdotgg/t3code/pull/3108
* @xxashxx-svg made their first contribution in https://github.com/pingdotgg/t3code/pull/3867
* @yordis made their first contribution in https://github.com/pingdotgg/t3code/pull/4055
* @Chrrxs made their first contribution in https://github.com/pingdotgg/t3code/pull/4006
* @Aditya190803 made their first contribution in https://github.com/pingdotgg/t3code/pull/3484
* @zepi2509 made their first contribution …
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL 1,000+ changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants