Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
cdd17e9
fix(web): make new thread workspace intent explicit
yaacovcorcos Jul 24, 2026
0d6eb37
fix(web): serialize distinct new thread intents
yaacovcorcos Jul 24, 2026
55e35d6
test(web): type exact workspace branch mocks
yaacovcorcos Jul 24, 2026
3c2e0cb
fix(web): preserve new thread request ordering
yaacovcorcos Jul 24, 2026
8879bde
Merge origin/main into safer new thread workspace
yaacovcorcos Jul 24, 2026
abd7487
fix(web): preserve latest new thread intent
yaacovcorcos Jul 24, 2026
cb40a5e
fix(web): coordinate all new thread navigation
yaacovcorcos Jul 24, 2026
f65fadc
fix(web): preserve latest navigation across preparation
yaacovcorcos Jul 24, 2026
2e19126
fix(web): close remaining navigation races
yaacovcorcos Jul 24, 2026
4ee913b
Merge remote-tracking branch 'origin/main' into agent/safer-new-threa…
yaacovcorcos Jul 24, 2026
0358885
Merge remote-tracking branch 'origin/main' into agent/safer-new-threa…
yaacovcorcos Jul 24, 2026
bc3d97f
chore: clean merged sidebar imports
yaacovcorcos Jul 24, 2026
45c77b1
Merge remote-tracking branch 'origin/main' into agent/safer-new-threa…
yaacovcorcos Jul 24, 2026
8684022
fix(web): close terminal and route ownership gaps
yaacovcorcos Jul 24, 2026
b679d0c
fix(web): coordinate every new-thread route intent
yaacovcorcos Jul 24, 2026
79c7c88
Merge remote-tracking branch 'origin/main' into agent/safer-new-threa…
yaacovcorcos Jul 24, 2026
c2832a4
fix(web): enforce route ownership before history commits
yaacovcorcos Jul 24, 2026
a2ff780
test(web): use typed routes in navigation guard proof
yaacovcorcos Jul 24, 2026
71da7ee
fix(web): release committed navigation ownership
yaacovcorcos Jul 24, 2026
35dfc78
Merge remote-tracking branch 'origin/main' into agent/safer-new-threa…
yaacovcorcos Jul 24, 2026
a96d3c6
Merge remote-tracking branch 'origin/main' into agent/safer-new-threa…
yaacovcorcos Jul 24, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions KEYBINDINGS.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ Invalid rules are ignored. Invalid config files are ignored. Warnings are logged
- `terminal.split`: split terminal (in focused terminal context by default)
- `terminal.new`: create new terminal (in focused terminal context by default)
- `terminal.close`: close/kill the focused terminal (in focused terminal context by default)
- `chat.new`: create a new chat thread preserving the active thread's branch/worktree state
- `chat.new`: create a new chat thread using the target project's configured workspace default
- `chat.newLocal`: create a new chat thread for the active project in a new environment (local/worktree determined by app settings (default `local`))
- `chat.newTerminal`: create a new terminal-first thread preserving the active thread's branch/worktree state
- `chat.newTerminal`: create a new terminal-first thread using the target project's configured workspace default; if a configured worktree has no concrete path, safely fall back to the project's local checkout
- `composer.focus.toggle`: focus or blur the chat prompt composer
- `editor.openFavorite`: open current project/worktree in the last-used editor
- `script.{id}.run`: run a project script by id (for example `script.test.run`)
Expand Down
6 changes: 6 additions & 0 deletions apps/web/src/components/AppSnapCoordinator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ import { transientAlertManager } from "../notifications/transientAlert";
import { useSplitViewStore } from "../splitViewStore";
import { useStore } from "../store";
import { useTerminalStateStore } from "../terminalStateStore";
import {
coordinateExternalRouteNavigation,
draftNavigationSlotKey,
} from "../lib/stagedDraftNavigation";

const MAX_REMEMBERED_CAPTURE_IDS = 100;
const APPSNAP_LISTENER_ACTIVITY_KEY = "appsnap:listener";
Expand Down Expand Up @@ -327,6 +331,8 @@ export function AppSnapCoordinator() {

const activateExistingTarget = useCallback(
async (target: AppSnapThreadTarget) => {
const mayActivate = await coordinateExternalRouteNavigation(draftNavigationSlotKey());
if (!mayActivate) return;
openChatThreadPage(target.threadId);
// Same thread is only "already active" when the split pane matches too;
// a capture aimed at another pane still needs activation below.
Expand Down
6 changes: 5 additions & 1 deletion apps/web/src/components/BranchToolbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ export default function BranchToolbar({
});

const setThreadWorkspace = useCallback(
(patch: ThreadWorkspacePatch) => {
(patch: ThreadWorkspacePatch, options?: { preserveDraftWorkspaceOrigin?: boolean }) => {
if (!activeThreadId) return;
const branch = patch.branch !== undefined ? patch.branch : activeThreadBranch;
const worktreePath =
Expand Down Expand Up @@ -328,13 +328,17 @@ export default function BranchToolbar({
branch,
worktreePath,
envMode: nextDraftEnvMode,
...(options?.preserveDraftWorkspaceOrigin && draftThread
? { workspaceOrigin: draftThread.workspaceOrigin }
: {}),
});
},
[
activeThreadId,
activeThreadBranch,
serverThread?.session,
activeWorktreePath,
draftThread,
hasServerThread,
setThreadWorkspaceAction,
serverThread?.associatedWorktreePath,
Expand Down
15 changes: 12 additions & 3 deletions apps/web/src/components/BranchToolbarBranchSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,10 @@ interface BranchToolbarBranchSelectorProps {
effectiveEnvMode: EnvMode;
envLocked: boolean;
hasServerThread: boolean;
onSetThreadWorkspace: (patch: ThreadWorkspacePatch) => void;
onSetThreadWorkspace: (
patch: ThreadWorkspacePatch,
options?: { preserveDraftWorkspaceOrigin?: boolean },
) => void;
onCheckoutPullRequestRequest?: (reference: string) => void;
onComposerFocusRequest?: () => void;
variant?: BranchSelectorVariant;
Expand Down Expand Up @@ -510,7 +513,10 @@ export function BranchToolbarBranchSelector({
return;
}

onSetThreadWorkspace({ branch: currentGitBranch, worktreePath: null });
onSetThreadWorkspace(
{ branch: currentGitBranch, worktreePath: null },
{ preserveDraftWorkspaceOrigin: true },
);
}, [
activeThreadBranch,
activeWorktreePath,
Expand Down Expand Up @@ -736,7 +742,10 @@ export function BranchToolbarBranchSelector({
) {
return;
}
onSetThreadWorkspace({ branch: currentGitBranch, worktreePath: null });
onSetThreadWorkspace(
{ branch: currentGitBranch, worktreePath: null },
{ preserveDraftWorkspaceOrigin: true },
);
}, [
activeThreadBranch,
activeWorktreePath,
Expand Down
Loading
Loading