Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
27 changes: 16 additions & 11 deletions apps/app/src/features/chat/components/chat-input-composer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ export function ChatInputComposer({
...orpcQueryUtils.git.branch.queryOptions({ input: { cwd: cwd ?? "" } }),
enabled: cwd !== undefined,
});
const currentBranch = branch.data?.current;
const { acknowledgeRecovery, prompt, steer, turnInProgress, store } = useChatSession();
const status = useStore(store, (state) => state.session.status);
const activeTurnId = useStore(store, (state) => state.session.activeTurnId);
Expand Down Expand Up @@ -234,17 +235,21 @@ export function ChatInputComposer({
</PromptInputToolbar>
</ChatInputProvider>
</Card>
{branch.data?.current ? (
<CardFrameFooter className="py-2">
<span
className="text-muted-foreground flex items-center gap-1.5 px-3 text-xs"
title="Current git branch"
>
<GitBranchIcon aria-hidden="true" className="size-3.5 shrink-0" />
<span className="truncate">{branch.data.current}</span>
</span>
</CardFrameFooter>
) : null}
<CardFrameFooter className="px-3 py-2">
<span
className="text-muted-foreground flex h-4 min-w-0 items-center gap-1.5 text-xs"
title={currentBranch ? "Current git branch" : undefined}
>
{branch.isPending ? (
<span aria-hidden="true" className="bg-muted h-2 w-24 animate-pulse rounded-sm" />
) : currentBranch ? (
<>
<GitBranchIcon aria-hidden="true" className="size-3.5 shrink-0" />
<span className="truncate">{currentBranch}</span>
</>
) : null}
</span>
</CardFrameFooter>
</CardFrame>
);
}
13 changes: 13 additions & 0 deletions apps/app/src/routes/session/$sessionId.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,17 @@ export const Route = createFileRoute("/session/$sessionId")({
loaderDeps: ({ search }) => search,
loader: async ({ context, params, deps }) => {
const { session } = context.orpcQueryUtils;
const prefetchBranch = async (projectId: string) => {
const projects = await context.queryClient.ensureQueryData(
context.orpcQueryUtils.project.list.queryOptions(),
);
const cwd = projects.find((project) => project.id === projectId)?.path;
if (cwd) {
void context.queryClient.prefetchQuery(
context.orpcQueryUtils.git.branch.queryOptions({ input: { cwd } }),
);
}
};

// Fast path: the link handed us a whole ref, so prepare can go first. We
// return what the server answers with, not what the URL claimed.
Expand All @@ -43,6 +54,7 @@ export const Route = createFileRoute("/session/$sessionId")({
harnessAgentId: deps.harness,
sessionId: params.sessionId,
};
void prefetchBranch(hinted.projectId);
const prepared = await session.prepare.call({ ref: hinted }).catch((error: unknown) => {
// A bad hint and a session the harness has forgotten both fall through
// to the lookup; only this line tells them apart afterwards.
Expand All @@ -69,6 +81,7 @@ export const Route = createFileRoute("/session/$sessionId")({
// native history was cleaned up fails here — surface it instead of leaving
// a silently dead chat. The page still renders, so keep the console trail
// for diagnosis after the toast auto-dismisses.
void prefetchBranch(ref.projectId);
await session.prepare.call({ ref }).catch((error: unknown) => {
console.error("Failed to prepare session", error);
toast.error(
Expand Down
Loading