mirror of
https://github.com/block/buzz.git
synced 2026-11-09 02:41:57 +00:00
Pin each chat's PR so panels stop converging on one PR
Two live effects made different chats' work panels show the same PR: the windowed message fetch ages the posted PR link out of the loaded history (losing the strongest per-chat signal), and agents reuse a worktree across chats in one project, so branch discovery resolves several chats to the same pull request. Each chat now pins the PR it resolves (localStorage): a link posted in the chat always wins and re-pins, the pin covers revisits after the link leaves the window, and branch discovery only runs for chats with no posted link and no pin. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -143,3 +143,33 @@ export function useChatWorkAutomation(chatId: string): ChatWorkAutomation {
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
const PR_STORAGE_PREFIX = "buzz:chat-work-pr:v1";
|
||||
|
||||
/**
|
||||
* The PR pinned to a chat. Posted links age out of the windowed message
|
||||
* fetch and branch discovery can resolve several chats sharing a reused
|
||||
* worktree to the same PR — the pin keeps each chat on the PR it actually
|
||||
* resolved first, with posted links always overriding.
|
||||
*/
|
||||
export function readChatPinnedPr(chatId: string): string | null {
|
||||
if (typeof window === "undefined") {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return window.localStorage.getItem(`${PR_STORAGE_PREFIX}:${chatId}`);
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export function writeChatPinnedPr(chatId: string, href: string) {
|
||||
if (typeof window === "undefined") {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
window.localStorage.setItem(`${PR_STORAGE_PREFIX}:${chatId}`, href);
|
||||
} catch {
|
||||
// Best-effort.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,8 +11,10 @@ import {
|
||||
} from "lucide-react";
|
||||
|
||||
import {
|
||||
readChatPinnedPr,
|
||||
updateChatWorkAutomation,
|
||||
useChatWorkAutomation,
|
||||
writeChatPinnedPr,
|
||||
} from "@/features/chats/lib/chatWorkAutomation";
|
||||
import {
|
||||
type GithubCheckSummary,
|
||||
@@ -83,11 +85,20 @@ export function ChatWorkPanel({
|
||||
// hidden panel stops polling entirely.
|
||||
const monitorActive =
|
||||
open || automation.autoFixCi || automation.addressComments;
|
||||
// Pin resolution order: a link posted in THIS chat wins, then the chat's
|
||||
// previously pinned PR, then branch discovery — discovery alone is
|
||||
// ambiguous when agents reuse a worktree across chats in one project.
|
||||
const pinnedHref = React.useMemo(() => readChatPinnedPr(chatId), [chatId]);
|
||||
const discoveredPrQuery = useGithubPrForBranchQuery(
|
||||
monitorActive && !prHref ? projectPath : null,
|
||||
monitorActive && !prHref && !pinnedHref ? projectPath : null,
|
||||
branch,
|
||||
);
|
||||
const effectiveHref = prHref ?? discoveredPrQuery.data ?? null;
|
||||
const effectiveHref = prHref ?? pinnedHref ?? discoveredPrQuery.data ?? null;
|
||||
React.useEffect(() => {
|
||||
if (effectiveHref && effectiveHref !== readChatPinnedPr(chatId)) {
|
||||
writeChatPinnedPr(chatId, effectiveHref);
|
||||
}
|
||||
}, [chatId, effectiveHref]);
|
||||
const preview = effectiveHref
|
||||
? parseSupportedLinkPreview(effectiveHref)
|
||||
: null;
|
||||
|
||||
Reference in New Issue
Block a user