Add Chats mode#1460
Draft
klopez4212 wants to merge 69 commits into
Draft
Conversation
b912a7b to
66ed9b2
Compare
66ed9b2 to
ed59887
Compare
The shared reqwest client had no timeout, so a stalled connection (e.g. an expired VPN tunnel that blackholes packets) left relay bridge calls pending forever — chat creation and message sends spun indefinitely with no error surfaced. Relay requests now carry a 30s per-request deadline and the shared client gets a 10s connect timeout (connect-phase only, so media streaming stays unbounded). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Two chat-mode harness features: - chat_title observer frames: after the first successful turn in a chat channel, run a tool-less side session (no MCP servers, no system prompt, observer muted so its wire traffic never pollutes the turn's transcript) that titles the conversation, and emit the sanitized result as a chat_title frame for the desktop to apply. - chat backlog replay: chats now subscribe from just after the agent's own last reply (capped at 6h) instead of the startup watermark, so a message sent while the agent was stopped is delivered once the owner activates it, instead of being silently skipped forever. Adds streamed assistant-text capture to AcpClient for side prompts. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A batch of chat-mode UX improvements: - Per-element shimmer on loading markers (label and elapsed time each get an aligned overlay instead of one misaligned combined pass). - Slide-up entrance animation for newly arrived rows (messages and activity markers), recency-gated so opening a chat never cascades. - Consecutive completed shell commands fold into "Ran N commands"; the in-flight command stays visible as its own live row until it lands. - Chats auto-title once the conversation takes shape: agent-generated chat_title frames are preferred, with a lead-in-stripping heuristic as fallback. Titles swap in with the search-placeholder character animation, never override a manual rename, and the sidebar list now follows the metadata title. - The "Working" row gets a dropdown showing the turn's recent raw observer events (reusing RawEventRail). - The agent activation card holds a 20s grace window after activation so it doesn't flash back while the agent boots. - Message scroller: bottom fade as an overlay (masks repaint per frame in WKWebView), removed content-visibility sizing that broke stick-to-bottom, simplified the scroll anchor. - Fix duplicate sibling key that leaked a stacked header per chat switch, and circular sizing that collapsed the animated title. Adds e2e coverage for the first-message flow (send, entrance animation, retitle) and a header-stacking regression test. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A turn can span several user messages — a mid-turn steer, or a batch that merged a replayed backlog message with a fresh one. Chat activity placement anchored the turn to the FIRST of them, so the turn's output (including the reply to the newest message) rendered above the user's latest message, pinning it to the bottom of the conversation. Attach the block to the latest prompt/steer message id instead, and make merged prompts resolve their prompt item to the newest embedded Buzz event section rather than the oldest. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
"Turn started" / "Session ready" rows repeat on every turn without telling the user anything actionable — the Working marker (and its raw-event dropdown) already covers turn liveness. Drop them from the chat timeline and the completed-turn dropdown; their timestamps still feed the "Thought for Xs" duration. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The Chats tab always landed on the new-chat screen. Remember the last-viewed chat per workspace (localStorage) and redirect plain /chats navigations back to it when it still exists. Explicit new-chat navigations carry a projectId in the route search and are never redirected. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
PR links in messages now show a live card instead of the static preview: repo and PR number, PR title, current status (open / draft / merged / closed with a matching state icon), additions in green, deletions in red, and the files-changed count. The whole card links to the PR. Details come from the GitHub REST API via a new Tauri command — anonymous for public repos, with GITHUB_TOKEN/GH_TOKEN attached when the shell that launched the app has one. Any fetch failure (rate limit, private repo without a token, offline) falls back to the existing compact card. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Three chat fixes: - "Working" no longer renders once per turn block: the active-turn store now exposes the live turn ids per channel, so only the actually-live turn shows the marker and completed turns collapse even while a new turn runs (previously a channel-wide boolean re-expanded every old turn and gave each its own Working row). - Agent-authored PR links render a distinct, prominent card (banner layout with repo, status pill, title, and diff stats) instead of the compact chip a pasted link gets. Threaded through a Markdown agentAuthored flag set on agent message rows. - New chats resolve their default agent immediately: quick-start refreshes the managed-agents cache after ensuring Fizz, so the first chat's agent replies render as agent rows instead of member bubbles. The chats e2e now covers the agent card and pins mock message ordering with explicit timestamps (same-second events sorted unstably). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Sidebar chat titles shimmer while the agent works, replacing the spinner (the archive affordance keeps its hover slot). - Chat projects use the Notebook icon family instead of folders (sidebar groups, project picker, new/none rows). - Right-click on any chat offers Rename (dialog writing owner metadata — hidden on shared chats), Pin/Unpin (persisted per workspace; pinned chats sort to the top of their section), and Archive. - Solo chats (you plus one agent) hide the agent's avatar and name so replies read as a plain stream; identities return automatically the moment another agent or person participates. The switching e2e now covers the context menu, pinning order, and rename round-trip. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Two fixes to the working-chat shimmer in the sidebar: - New buzz-shimmer-accent variant: the title keeps its normal text color and a primary-colored band sweeps across it, instead of the default treatment that dims the base text to make the highlight read. - The shimmer class now lives on the truncating span itself (the MarkerLabel pattern), so long names ellipsize normally. The archive slot is zero-width until hover/focus, giving the title the full row and only shrinking to make room for the button on demand. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The Working marker mounts and unmounts with every gap between tool executions; replaying its entrance fade on each reappearance read as blinking instead of a shimmer. Drop the entrance animation on that row and start the shimmer band mid-sweep (negative animation-delay) so even short-lived mounts show the moving band rather than the transparent lead-in. The sidebar archive slot now appears instantly on hover instead of animating its width. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
WKWebView renders the negative calc() animation-delay unreliably, which killed the sweep in the real app while Playwright engines showed it fine. Encode the same mid-sweep start directly in the keyframes (the 50%→50.01% wrap lands while the band is outside the text, so the jump is invisible) and drop the delay. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Adds an opt-in top fade overlay to the message scroller (mirroring its bottom fade) and enables it for chats, so messages dissolve as they scroll under the chat header — the same treatment the sidebar's pinned header applies to channels scrolling beneath it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Chat stream: - Activity markers span the full conversation column (matching the "Thought for Xs" row) instead of capping at 42rem. - Own bubbles drop the redundant "You" header. PR work panel: when the chat's agent posts a pull request, a module docks top-right inside the chat area (conversation and composer shrink to make room) showing the PR's source branch and the live PR card. fetch_github_pull_request now returns head.ref for the branch chip. Branch e2e repairs (both regressions pre-dated today): - "Jump to latest" now re-asserts the bottom until row re-measurement settles — a smooth jump aimed at a stale scrollHeight landed short once grouped rows changed height estimates. - Sidebar dnd gains a keyboard sensor with keyboard-aware collision detection, and channel-assignment drop zones are disabled while a section drag is active. The dnd e2e uses a viewport tall enough that auto-scroll can't move the drop target mid-drag. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A Playwright or build run in the same checkout wrote playwright-report/
test-results/dist, and the dev server's watcher force-reloaded any live
app window on every write — killing in-flight Tauri IPC ("Couldn't find
callback id") and making interactions appear to crash mid-flow.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A pull-request button sits left of the chat settings menu whenever the agent has posted a PR, toggling the top-right work module (tinted primary while open; each chat starts with it visible). The panel's card now uses the standard rich PR card style, matching PR link cards elsewhere. Splits ChatList out of ChatsScreen (file size ceiling) with the shared-chat metadata check moved to lib/chatShared. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The chat title stands alone in the header — the MessageCircle glyph added no information. Other modes keep their icons. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The work module's contents (label, branch chip, PR card) sit in a rounded secondary-background container, the divider against the conversation is gone, and the drawer eases open/closed on its width (300ms ease-out) instead of popping — the panel stays mounted so the close animates too. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The card's default muted background matched the panel's secondary container exactly; it now uses the same background inset as the branch chip so both read as distinct items on the surface. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The branch chip and PR card speak for themselves. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
bg-secondary read too heavy next to the conversation; bg-muted/40 keeps the grouping while blending with the chat background. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Plain dropped GitHub PR links go back to the compact static chip they had before; the live rich card (status, diff stats) now appears only in the chat work drawer — at the same compact-attachment scale as the generic chips — and agent-authored messages keep their banner variant. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The drawer grows to w-96 so the PR card's stats fit, and the container wash is gone: the branch chip and card use the same attachment styling as the generic link chips, directly on the chat background. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The header's PR toggle now shows for every chat: the drawer auto-opens once the agent produces a pull request and shows a "No current branch" empty state before that (explicit toggles override per chat). The Share button trades its filled pill for a light border stroke with a hover fill. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Opening the dialog synchronously from the menu item's onSelect races Radix's menu close/focus-restore against the dialog's focus lock and can freeze the webview (observed as an app crash on rename). Deferring one tick lets the menu fully close first. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The work drawer becomes a PR monitor: a CI chip shows running (with progress), failing (red, count), or passing (green) from the head commit's check runs, alongside the PR's comment count — both polled while the panel is mounted. Two persisted per-chat checkboxes arm automation: "Auto-fix CI failures" prompts the chat's agent to investigate and fix once a head sha's checks settle red (one nudge per sha), and "Address comments & resolve" prompts it to work through comments and replies, reply, and resolve addressed threads whenever the comment count rises (watermarked so it never repeats). Adds fetch_github_check_summary and head sha/comment counts to the PR fetch. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
New chat screen: the "Start a chat" center gains channel-intro-style preset cards. Default agent shows who will handle the chat with a picker to swap in another managed agent or a whole team (team personas are created in the chat like template agents, first one becomes the default). Directory shows the selected project's path (or free-chat empty state) and opens the project picker. Invite searches the user directory and pre-adds people as members on create, merged with the @mention flow. Multi-agent activity: the chat transcript and working indicators only read the default agent, so a second agent's turns rendered nothing. The transcript now merges every active managed agent's items by timestamp, live turn ids come from the by-channel store (which now carries turnIds), and the composer stop button cancels every agent working in the chat. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Preset cards: taller cards with breathing room between the icon and the text block; the agent picker no longer lists the welcome guide's managed instance next to the Default agent row (the duplicate Fizz); the invite search now goes through useUserSearchQuery — the same normalized, cached path the channel invite uses — instead of a raw searchUsers call whose un-lowercased query could miss on relay search. Work panel: when no PR link was ever posted in the chat, the panel now discovers the pull request from the branch itself — a new find_github_pr_for_branch command reads the project's origin remote (ssh or https GitHub URLs), asks the pulls API for the branch head, and falls back to scanning open PRs for fork-headed branches. The panel runs this only while it has a branch + project directory and no posted link, polling slowly so a PR opened mid-conversation surfaces on its own. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The standalone link-chip treatment (opaque muted fill, provider-colored icon tile) read as a gray slab inside the user's primary-colored bubble — most visible on the automation prompts carrying a PR link. Chips in own bubbles now derive everything from currentColor: translucent fill, border, and icon tile, so they read as part of the bubble in both themes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The action reached the main timeline's rows but was never threaded into MessageThreadPanel, so messages inside a thread had no handler and the menu item silently didn't render. The panel now accepts onStartSideConversation and passes it to both the thread head and reply rows; ChannelPane forwards the same archived-gated handler the main timeline uses. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Message content in chats — bubbles and agent replies — steps up to font-medium so the conversation reads a notch heavier than the muted marker plumbing around it. Markers keep their current weight. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The auto-fix-CI and address-comments nudges are sent as user messages so the agent hears them through the normal pipeline — but rendering them as the user's own bubbles broke the illusion. They now carry an ["automation", "work-panel"] tag (riding the outgoing tag path the composer already uses) and the timeline renders only their anchored activity: the agent's turn markers and reply appear with no visible prompt, so armed automation reads as ambient. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Clicking Activate reverted to idle (with a success toast) as soon as
the start API returned — but a launched process is not a responding
agent, so the card lingered and read as a failed activation. The card's
button now stays in its loading state from click until the chat's turn
actually starts (the card unmounts then), with a 60s give-up window,
and the copy switches to "Starting {agent}… It will pick up your
message as soon as it connects." The premature success toast is gone —
the agent visibly starting work is the confirmation.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The agent's in-transcript messages (the self-talk that renders between markers) and mid-turn user prompts step up to font-medium, matching the persisted conversation rows. Marker rows and their expanded details keep their lighter treatment. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The chat-title side prompt asked for a "short title", which drifts toward wordy summaries; the agent's git branch names for the same work are consistently terser. The prompt now asks the model to name the conversation exactly as it would name a branch for the task — the same few concrete words — written with spaces instead of dashes. When a model answers with the literal slug anyway, the sanitizer converts a single dashed/underscored/slashed token into spaced words with a leading capital. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A message quoting a template command — `git checkout -b <branch>` — parsed the literal "<branch>" as the chat's branch and the work panel chip displayed it. Every command-parsed candidate now has to look like a real git ref (alphanumeric start, ref charset, not a sha); the prose patterns were already restricted. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The monitor went stale-empty overnight because every failure path compounded: the app usually launches without GITHUB_TOKEN in its env, so all GitHub calls ran anonymous (60 req/h) while the panel polls ~180 req/h — rate-limited within minutes — and non-success responses returned Ok(None), which the UI rendered as a confident "No checks / 0 open comments" instead of an error. Three fixes: ambient_github_token falls back to `gh auth token` (resolved once per process) so the desktop uses the CLI credential that's actually on the machine; GitHub commands now return Err on non-404 failures so React Query keeps the last good snapshot and retries instead of overwriting it with nothing; and polling pauses entirely while the drawer is closed — unless automation is armed, which keeps watching in the background. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The chat timeline filtered out only system messages, but the channel query also delivers reactions/edits/deletions — so an agent's 👀/💬 acknowledgment reactions (kind 7, from harnesses predating the chat gating) rendered as tiny emoji message bubbles. The timeline and the solo-layout participant count now admit only the true message kinds, suppressing the emoji regardless of which harness build the agent runs. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The branch swap and the card pop-in replayed on every visit to a chat: the panel mounts on "No current branch", async PR data resolves a beat later, and the change animated even though nothing was new. The panel now remembers the last branch/PR shown per chat — revisits render the cached value statically from the first frame, the pop-in decision is latched per mount (recording the href as seen must not strip the class mid-animation), and the branch text is keyed by chat so switching chats never animates one chat's branch into another's. A genuinely new branch or PR still animates exactly once. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The automation watermarks made each nudge one-shot: fired against a failing sha (or a comment count) exactly once, with no retry if the agent was stopped when the prompt landed or the send never took — leaving red CI and open comments with no agent working and no way to re-trigger short of unchecking and re-checking. Two escapes: while a condition persists (CI still failing / comments still open) and NO turn is running in the chat, the armed automation re-nudges after a 15-minute cooldown (timestamps join the stored watermarks); and each automation row shows a "Run now" button whenever its condition is active and the agent is idle, which fires the same prompt immediately, watermarks aside. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The mention chip's standalone palette is primary text on a primary tint — inside the primary-colored own bubble that disappears entirely, rendering mentioned names as blank gaps. Chips in own bubbles now derive from currentColor like the link chips (translucent fill, inherited text), staying legible on any bubble in both themes. The agent-mention icon already draws with currentColor, so it follows. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Four fixes from a branch-wide review of the hot paths: - useChatWorkAutomation content-compares its snapshot: a fresh object per storage event re-ran every consumer effect and re-rendered the panel even when nothing changed. - ChatMessageRow and ChatActivityTranscript are memoized: ChatDetail re-renders on every observer frame during a live turn, and every persisted message re-rendered its whole Markdown tree each time. - The active-agent pubkey list is key-stabilized: the managed-agents 30s refetch minted a fresh array identity that resubscribed the transcript store with an unchanged set. - GitHub API commands share one reqwest client: the PR monitor polls on short intervals and built a new connection pool + TLS session cache per call. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Activation card: a stopped default agent now always shows the card —
"is it running or just silent?" must never be ambiguous, especially
since automation prompts tag the default agent and go nowhere while
it's stopped. The delayed path still covers running-but-unresponsive.
Run now: the automation prompt is invisible in the timeline, so firing
one now toasts "Asked {agent} to fix the CI failures" / "…address the
review comments". (The prompts already mention the default agent — the
send path tags it on every message — so multi-agent chats route the
work to the default agent by construction.)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Conflict notes: chat migration renumbered 0002→0005 (main also shipped an 0002); kind registry, playwright testMatch, observer store, and the base prompt are unions of both sides; useMentions keeps the chat global-search gate on top of main's extracted ranking; the mention send flow keeps the extracted invite helper with main's captured- channel binding added; the composer keeps the extracted props file with main's onCaptureSendContext ported; toolbar keeps the chat visibility gates with main's emoji-picker onClose refocus.
Adapts the branch to main's API moves: Markdown dropped the compact prop; ToolDetailBlocks requires fileReadContent; formatOwnerLabel gains main's "you" short-circuit; the mention send flow's invite helper carries the captured channel id; the composer props file ports onCaptureSendContext. Lint deltas from main's stricter config are fixed properly (own-bubble chip rules reordered below the standalone rules, pass-through switch cases folded into default, pulse suppressions re-anchored). Size ceilings are restored by extracting the NIP-AB pairing API from tauri.ts and the find-target splice state from ChannelScreen into useFindTargetEvents. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The staging relay predates channel_type "chat", so chat creation falls back to a plain private channel and every harness behavior keyed on channel_type == "chat" silently degrades: the activation backlog replay never runs (Activate starts the agent but the pending message is never delivered — only a fresh @mention wakes it), reactions aren't suppressed, and titles aren't emitted. Confirmed in agent logs: no subscription ever took the "(chat backlog since …)" path. Discovery now reclassifies member channels that carry chat metadata (kind 30623, or the legacy 30078 buzz:chat events) as chats, at startup and on membership-notification refresh, so chat behaviors work against older relays. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Run now: the toast only proved the click happened — the send's failure was swallowed, the prompt was fully invisible, and a stopped default agent silently ate it. Automation prompts now surface send errors, auto-start a stopped default agent (the backlog replay delivers the prompt once it connects), and leave a collapsed marker row at the spot the instruction fired — "Asked Fizz to fix the CI failures" — expandable to the full text, so the magic has an anchor. Shimmer: glyph recoloring alone is too subtle at sidebar sizes. The accent shimmer adds a translucent primary highlight wash sweeping behind the text on the same keyframes — a highlighter pass the text stays readable through. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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>
The glyph overlay clips to text by construction, but the new highlight wash is a box on the span — and the span is flex-1, so short names swept a full-row highlight. The shimmer now lives on an inner inline-block sized to the text (self-truncating, so the overlay ellipsis stays aligned); the outer span keeps the row layout. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Turns visibly worked but never answered: two filters could swallow a genuinely sent reply. The chat timeline ran persisted agent messages through the transcript's internal-narration patterns, so replies like "Done! I've sent the summary…" were dropped outright; and the consecutive-run collapse preferred the last "human-facing" message, hiding a narration-styled FINAL reply behind an earlier one. Persisted messages now render on content alone (narration shaping stays in the activity transcript, dedup still applies), and the run collapse hides only interim narration — every substantive message stays, and the run's final message always stays regardless of phrasing. Regression spec: a narration-styled final reply must render alongside the earlier PR announcement. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Every automation send was failing client-side: the marker tag rode the outgoing media channel, whose builder rejects any non-imeta prefix — so Run now toasted an ask (now an error, after the surfacing fix) but no prompt ever reached the relay, the agent never started, and the activation card sat on "Starting…" forever. The e2e mock accepted the invalid tag, which is how the route stayed green while broken live. The marker now rides the existing whitelisted ["client", ...] channel: send_channel_message accepts client_tags and threads them to build_message_with_client_tags; splitOutgoingTags gets a clientTags bucket (client tags force the REST path so the tag-validating builder runs); and the mock now enforces the imeta-only media gate and echoes client tags, closing the test blind spot. The event→model converters move to message_converters.rs to hold the size ceiling. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Worktree reuse can make branch discovery resolve a chat to another chat's PR, and the pin then locks the mistake in. A discovered/pinned card (never a posted link) now shows "Not this chat's PR? Unlink" — unlinking stores an explicit no-PR sentinel that keeps discovery off for that chat while a posted link still overrides everything. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Drawer: the open/closed preference reset on every chat switch, so the panel re-animated open each time a PR chat was selected. The toggle is now one persisted preference — switching chats renders the drawer in its remembered state with no animation; auto-open-on-PR remains only until the user toggles once. Shimmer: the band color moves close to the background (a whisper of primary keeps the hue) so glyphs visibly wash out as it passes — the strongest contrast against full-color text — and the highlight wash drops to a soft glow instead of a gray slab. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The highlight wash read as a gray slab over the text. The accent shimmer is now glyph-only again, with the band mixed to 8% primary / 92% background — characters wash out to (nearly) the background color as it sweeps, which is the highest-contrast treatment against full-color text in both themes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Auto-open-on-PR kept re-deriving the drawer state on every chat switch, re-animating it open for anyone who had never touched the toggle. The drawer is now a plain persisted boolean (default closed): it renders in the remembered state on every chat with no animation, and only a deliberate toggle changes it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The inverse of Unlink: when the panel shows nothing (agent never
posted the link, discovery found no match) or the wrong PR, "Pin a
pull request…" / "Not this chat's PR? Change" opens an inline URL
input. A manual pin outranks every automatic source — posted links,
remembered auto pins, and branch discovery — and the auto-pin effect
never downgrades it. Pins store {href, manual} (older bare-string
entries still parse).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Chats polish round
buzz-acptitles the conversation in a tool-less side session (observer muted so the side prompt never pollutes the turn transcript) and emits achat_titleframe; the desktop applies it with the search-placeholder swap animation, falling back to a lead-in-stripping heuristic. Manual renames are never overridden; the sidebar follows the metadata title.Testing
🤖 Generated with Claude Code