Commit Graph
1330 Commits
Author SHA1 Message Date
klopez4212 993f3d90e9 Polish chat mode work context 2026-07-07 08:20:32 +01:00
klopez4212andClaude Fable 5 884ffc5123 Pin a PR to the work panel manually
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>
2026-07-07 07:52:33 +01:00
klopez4212andClaude Fable 5 7cf50584f2 Work drawer state is purely remembered
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>
2026-07-07 07:52:33 +01:00
klopez4212andClaude Fable 5 d416f45ca8 Shimmer: drop the wash rectangle, band sits at the background color
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>
2026-07-07 07:52:32 +01:00
klopez4212andClaude Fable 5 680bb16e97 Persist the work drawer state; shimmer washes toward background
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>
2026-07-07 07:52:32 +01:00
klopez4212andClaude Fable 5 c9236b3910 Let a chat unlink a mispinned PR
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>
2026-07-07 07:52:32 +01:00
klopez4212andClaude Fable 5 4fc78847b1 Route automation marker tags through the client tag channel
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>
2026-07-07 07:52:32 +01:00
klopez4212andClaude Fable 5 3dcf6b0a62 Never hide a real agent reply behind narration heuristics
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>
2026-07-07 07:52:31 +01:00
klopez4212andClaude Fable 5 1f923a89ef Clip the sidebar shimmer wash to the chat name
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>
2026-07-07 07:52:31 +01:00
klopez4212andClaude Fable 5 2f4867619f 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>
2026-07-07 07:52:31 +01:00
klopez4212andClaude Fable 5 73340ac6ce Make Run now trustworthy and the sidebar shimmer unmissable
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>
2026-07-07 07:52:30 +01:00
klopez4212andClaude Fable 5 09b61fbc85 Recognize compatibility chats on relays without channel_type: chat
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>
2026-07-07 07:52:30 +01:00
klopez4212andClaude Fable 5 93b0c2a879 Post-merge reconciliation with latest main
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>
2026-07-07 07:52:30 +01:00
klopez4212andClaude Fable 5 ab483ea93c Always surface a stopped default agent; acknowledge Run now
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>
2026-07-07 07:52:00 +01:00
klopez4212andClaude Fable 5 ed160c6869 Efficiency pass over the chat features
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>
2026-07-07 07:52:00 +01:00
klopez4212andClaude Fable 5 6047a11537 Make mention chips legible inside own message bubbles
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>
2026-07-07 07:52:00 +01:00
klopez4212andClaude Fable 5 86cab382ae Re-nudge stalled automation and add manual Run now overrides
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>
2026-07-07 07:51:59 +01:00
klopez4212andClaude Fable 5 f3a035c424 Animate the work panel only for new information
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>
2026-07-07 07:51:59 +01:00
klopez4212andClaude Fable 5 fc43365ffb Never render reaction events as chat bubbles
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>
2026-07-07 07:51:59 +01:00
klopez4212andClaude Fable 5 527330a093 Keep the PR monitor live: gh token fallback, honest errors, poll gating
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>
2026-07-07 07:51:58 +01:00
klopez4212andClaude Fable 5 d2d26bc07c Reject placeholder tokens when parsing branches
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>
2026-07-07 07:51:58 +01:00
klopez4212andClaude Fable 5 f682796d43 Name chats the way branches are named
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>
2026-07-07 07:51:58 +01:00
klopez4212andClaude Fable 5 21faa17229 Match transcript message weight to conversation text
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>
2026-07-07 07:51:58 +01:00
klopez4212andClaude Fable 5 5cf7a86e5e Hold agent activation in its loading state until the agent responds
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>
2026-07-07 07:51:57 +01:00
klopez4212andClaude Fable 5 47b67066c1 Hide automation prompts from the chat timeline
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>
2026-07-07 07:51:57 +01:00
klopez4212andClaude Fable 5 e63099c093 Weight chat conversation text at medium
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>
2026-07-07 07:51:57 +01:00
klopez4212andClaude Fable 5 38c9ab7ab5 Offer Side conversation on thread messages
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>
2026-07-07 07:51:56 +01:00
klopez4212andClaude Fable 5 67bdfcfc0b Tint link chips inside own message bubbles
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>
2026-07-07 07:51:56 +01:00
klopez4212andClaude Fable 5 141adb7892 Preset card polish and PR discovery from the branch
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>
2026-07-07 07:51:56 +01:00
klopez4212andClaude Fable 5 b74f5e42a8 New-chat preset cards and activity from every agent in a chat
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>
2026-07-07 07:51:55 +01:00
klopez4212andClaude Fable 5 b6af79309f Render @mentions as chips in chat messages
Chat messages rendered markdown but never passed the mention props, so
@mentions stayed plain text. ChatMessageRow now resolves the message's
p/mention tags into name→pubkey maps (people vs agent chips, same
treatment as channel messages) for every author — own bubbles, other
humans, and agents. Mentioned users' pubkeys join the chat's profile
batch so a chip resolves even when that user never posted in the chat.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 07:51:26 +01:00
klopez4212andClaude Fable 5 48a9ff9742 Track the chat's PR link from any participant, not just agents
Author-scoping the work panel's PR scan proved brittle twice over:
first it matched only the default agent, then only the viewer's
managed agents — an agent someone else added to the chat still slipped
through, leaving the panel on the bare branch chip. Any PR link posted
in the chat is the chat's work; the scan now simply takes the latest
one regardless of author.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 07:51:26 +01:00
klopez4212andClaude Fable 5 cf1f4b5dbc Work panel: accept PRs from any agent, pop the GitHub stack in
The panel's PR link scan matched only the chat's default agent, so a
pull request posted by a second agent added to the chat never surfaced
— the drawer stayed on "No current branch". The scan now matches any
managed agent (plus the configured default).

When the PR info arrives, the card + CI monitor stack enters with a
slight scale + opacity pop (keyed by PR href, so a newer PR re-runs
it; disabled under prefers-reduced-motion).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 07:51:26 +01:00
klopez4212andClaude Fable 5 f9576ddaa5 Skip 👀/💬 seen and working reactions in chat channels
Chats have live working indicators (sidebar shimmer, working row), so
the harness's acknowledgment reactions on the user's message read as
the agent spamming emoji — noticeable the moment a second agent joins
and both react. The queue-time 👀 gates on the existing chat check;
the turn-start 💬 resolves chat-ness inside its fire-and-forget task
(startup cache first, REST fallback for chats created after the
harness booted) so the prompt still fires immediately. The
ReactionGuard cleanup stays unconditional — removing reactions that
were never added is a no-op.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 07:51:25 +01:00
klopez4212andClaude Fable 5 4c4faacdc2 Soften chat marker rows to muted-foreground/70
At full muted-foreground strength the marker labels, icons, and the
completed-work expander still competed with the conversation text;
drop them to 70% opacity so they clearly read as plumbing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 07:51:25 +01:00
klopez4212andClaude Fable 5 b93d168ccf Place unanchored turn activity by time instead of pinning it last
Turn blocks attach to their prompt message by id; when the id can't be
matched (replayed backlog outside the fetched window, a prompt that
didn't carry the id) the block fell into the trailing bucket rendered
after ALL messages — so old "Thought for Xs" summaries sat stuck at the
bottom while newer messages and turns rendered above them.

Unmatched blocks now attach to the latest message at or before the
block's start time (5s skew tolerance for the agent-host clock), so
they render at their chronological spot and move up naturally as the
conversation continues. The trailing bucket remains only for blocks
with no usable timestamp or an empty message list.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 07:51:25 +01:00
klopez4212andClaude Fable 5 83d577dc34 Ellipsize the shimmer overlay and center the stop icon
The shimmer ::before repeats the full data-shimmer-text, so on
truncating labels it painted the clipped characters over the base
text's ellipsis. The overlay now truncates identically (same font and
box, so the ellipsis lands in the same spot).

The stop square sized its svg directly, which competed with the
button's [&_svg]:size-4 rule and sat the glyph off-center — the size
override now lives on the button so class merge resolves it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 07:51:24 +01:00
klopez4212andClaude Fable 5 e369ad801e Composer stop button, message-derived branch, muted markers, shimmer punch
Stop button: while the chat's agent has an active turn, the composer's
send button becomes a stop button that sends the cancel-turn control
frame to the agent; a user message in flight keeps the sending spinner.
(MessageComposerProps moves to a sibling file to stay under the
1000-line ceiling.)

Branch chip: tool activity only exists from observer-subscription time,
so a worktree created before the app attached left "No current branch"
even though the agent had announced it. The agent's persisted messages
are now a fallback source — "…on branch kennylopez-dictation",
backticked branch names, and quoted git commands all parse.

Markers: the completed-work expander label and tool preview text drop
to muted-foreground so every marker row reads as secondary to the
conversation.

Shimmer: per-theme band colors — light keeps primary washed toward
white; dark mixes primary toward black in oklch, which keeps the hue
saturated instead of graying into the background, for a clearly
stronger sweep against near-white text.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 07:51:24 +01:00
klopez4212andClaude Fable 5 ba8ac20fec Make the accent shimmer contrasty and robust to mid-turn attach
Contrast: the accent shimmer band swept raw primary, which sits too
close to the text's lightness in both themes (58%-L purple vs
near-black text in light; 80%-L purple vs near-white text in dark) and
barely read. The band now mixes primary toward the background — lighter
in light mode, darker in dark mode, both directions pulling away from
the text — and narrows so the highlight covers more visible text per
pass.

Robustness: observer frames are ephemeral, so an app subscribing
mid-turn missed turn_started and the turns store stayed empty (dark
sidebar shimmer, no working badges) until a liveness ping happened to
land. Any frame carrying a turn context — tool calls included, which
stream constantly during work — now establishes the turn, still gated
by the terminal tombstone so completed turns stay dead.

Adds an e2e spec covering the sidebar title shimmer end to end via
seeded active turns.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 07:46:18 +01:00
klopez4212andClaude Fable 5 463c74d5a2 Show the agent's live branch in the work panel, animated on change
The branch chip previously only knew head.ref from the GitHub PR, so it
sat on "No current branch" until a PR existed and snapped when it did.
The chat's channel-scoped transcript already carries the agent's shell
commands, so the panel now derives the current branch from the latest
`git worktree add` / `checkout -b` / `switch` the agent ran (live
activity wins over the PR's head ref) and swaps the chip text with the
same character animation the chat title uses.

File checkouts, `--` restores, and bare shas are ignored so only real
branch moves update the chip.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 07:46:17 +01:00
klopez4212andClaude Fable 5 e787698a76 Expandable CI monitor with per-check runs and open-comment count
The CI chip in the chat work panel is now a dropdown: the summary row
keeps the aggregate state plus a chevron, and expanding it lists each
check run with its own pass/fail/pending icon, followed by the two
automation checkboxes (moved out of their standalone chip).

The comment count now shows review threads still awaiting the PR
author's reply instead of the raw total — REST can't see GitHub's
resolved bit, so replying is what clears a thread. New
fetch_github_pr_comment_state command groups review comments into
threads and counts the ones whose last word isn't the author's; the
address-comments automation nudges on rises in that count and re-arms
once it returns to zero.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 07:46:17 +01:00
klopez4212andClaude Fable 5 1ee49bce2f CI monitor and automation toggles in the chat work panel
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>
2026-07-07 07:46:17 +01:00
klopez4212andClaude Fable 5 e24f4a8c8a Defer opening the rename dialog past the context menu's close
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>
2026-07-07 07:46:16 +01:00
klopez4212andClaude Fable 5 8aa9839884 Always offer the work drawer; lighten the Share button
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>
2026-07-07 07:46:16 +01:00
klopez4212andClaude Fable 5 f8a84deb63 Widen the work drawer and match generic card styling
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>
2026-07-07 07:46:16 +01:00
klopez4212andClaude Fable 5 090d5f6d9c Reserve the rich PR card for the chat work drawer
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>
2026-07-07 07:46:16 +01:00
klopez4212andClaude Fable 5 0640bd31b2 Soften the work panel container to a muted wash
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>
2026-07-07 07:46:15 +01:00
klopez4212andClaude Fable 5 8f8c4a70e6 Drop the Work label from the chat work panel
The branch chip and PR card speak for themselves.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 07:46:15 +01:00
klopez4212andClaude Fable 5 c3d49f111c Give the work panel's PR card its own surface
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>
2026-07-07 07:46:15 +01:00
klopez4212andClaude Fable 5 c201f0431a Style the work drawer as a secondary-surface container
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>
2026-07-07 07:46:14 +01:00