## Thinking Path
> - Paperclip is the open source app people use to manage AI agents for
work
> - People talk to agents in chat, and the open chat updates live when
an agent replies
> - Run finalization can save a turn's reply after the run's terminal
status is published, and that save logs no `issue.comment_added`
activity
> - Finalization then settles the conversation, which logs
`issue.updated`, but the UI did not refetch comments on that update
> - So the reply stayed hidden in the open chat until the person
reloaded the page
> - This pull request makes the open chat refetch its saved comments
when its conversation is updated
> - The benefit is that a person sees the agent's reply without a reload
## Linked Issues or Issue Description
**What happened?**
In the chat eval cohort on master 98c18784c6, the agent's reply in
`cases.case-history` was saved at 06:57:46.481 by run finalization
(presentation decision `final_agent_message`, comment action `reuse`).
The run's terminal status went out at about 06:57:45. No
`issue.comment_added` activity exists for the reply. The browser fetched
the issue, runs, live runs and activity after the run ended, but it
never fetched comments again. At 06:57:59, 13 seconds later, the open
chat still showed only the person's message (`renderedCommentIds` held
only that comment). The reply showed after a reload.
`tasks.ambiguous-task` showed the same state.
**Expected behavior**
When finalization saves the reply, the open chat shows it without a
reload.
**Steps to reproduce**
1. Open a chat with an agent.
2. Send a message. The run ends, and finalization then saves the reply.
3. The reply does not appear until you reload the page.
Refs #21034
## What Changed
- `LiveUpdatesProvider`: an `issue.updated` activity for the
conversation that is open now also invalidates that conversation's
comments query. Finalization logs this update when it settles the turn,
after it saves the reply (cohort 5: reply 06:57:46.481, update
06:57:46.510; paid run: reply 08:19:38.433, update 08:19:38.489).
- The first version of this PR used the `run.presentation.resolved` run
event. The paid run showed that a page does not receive it: run
transcript events reach only pages subscribed to that run, and the
subscription ends with the run. That handler is removed.
- A red/green test: an update for another task, and an update for the
chat while another page is open, do not refetch; an update for the open
chat refetches its comments. The test fails without the change.
## Verification
- `pnpm exec vitest run --project @paperclipai/ui ui/src/context/`: 17
files, 319 tests pass.
- The new test fails with the change removed (1 failed, 117 passed) and
passes with it.
- `node scripts/check-token-gates.mjs`: clean.
- The companion eval PR reloads once when a saved reply is still not
rendered and records both waits. A paid eval run on a branch with both
changes checks the live result.
## Risks
- Low risk. Each update of the open chat's conversation (status or
conversation state) now refetches its recent comments window. Other
pages and other tasks are unchanged.
## Model Used
- Anthropic Claude Opus 5.5 (`claude-opus-5-5`) in Claude Code, with
tool use, shell execution and code editing.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [ ] I will address all Greptile and reviewer comments before
requesting merge
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
@paperclipai/ui
Published static assets for the Paperclip board UI.
What gets published
The npm package contains the production build under dist/. It does not ship the UI source tree or workspace-only dependencies.
Storybook
Storybook config, stories, and fixtures live under ui/storybook/.
pnpm --filter @paperclipai/ui storybook
pnpm --filter @paperclipai/ui build-storybook
Typical use
Install the package, then serve or copy the built files from node_modules/@paperclipai/ui/dist.
Editor dependency identity
Keep the root and workspace overrides for @codemirror/state,
@codemirror/view, and @lezer/common aligned. CodeMirror requires shared
extension identity, while Lezer parsers and syntax highlighters require shared
NodeProp IDs. Multiple Lezer copies can crash code-block highlighting with
tags is not iterable. src/lib/codemirror-single-instance.test.ts checks the
installed dependency graph and highlights sample code through the editor's real
language dependencies. GitHub Actions owns regeneration of pnpm-lock.yaml.