Files
PaperClipAI/ui
DottaandPaperclip 6958cb112c fix(ui): keep responder avatars visible across stale execution outcomes (#20293)
## Thinking Path

> - Paperclip lets people manage agents and send follow-up messages in
task chat.
> - The responder identity should stay visible while a message starts a
run.
> - Comment storage, task reads, and run discovery finish separately.
> - An older intent can resolve during admission of the new message.
> - A reopened task can also retain its previous terminal status until
the next read.
> - This change keeps those older outcomes from clearing the new startup
feedback.
> - The avatar stays visible until the new run or its own admission
outcome arrives.

## Linked Issues or Issue Description

Related fixes: #17885 and #18312. A search found no other PR for these
races.

**What happened?**

After Send, the agent avatar can disappear before the new run appears. A
prior intent changing from working to resolved clears the new
submission. Sending a follow-up that reopens a done or cancelled task
also clears startup feedback against the old task status.

**Expected behavior**

Keep the responder visible through comment acknowledgement and run
discovery. Stop startup feedback on a current failure, blocker, or
completion.

**Steps to reproduce**

1. Send a follow-up while a previous intent is still reported as
working.
2. Let that same intent resolve before the new run read completes.
3. Observe the responder disappear. Alternatively, send a follow-up to a
done or cancelled task and delay the reopened task read.

**Paperclip version**

Reproduced on source master at `33a23e0246`. Rebased onto `3ef45fdd92`
before submission.

**Deployment mode**

Local component tests reproduce the read ordering. An isolated local
trusted instance verifies the real Send-to-process-run path in Chromium.
It does not invoke a live model provider. No staging message was sent.

## What Changed

- Record the previous intent identity. Its later resolution cannot
acknowledge the new message unless the observed run belongs to that
message.
- Pass the existing reopen request into shared submission state on both
chat surfaces.
- Keep startup feedback through the previous terminal status. Restore
ordinary completion handling once the reopened status arrives.
- Add six Send regression cases, a live-run handoff assertion, and
coverage for later completion and ordinary terminal notes.
- Clarify identity continuity in DESIGN.md.

## Verification

- Red: all six new Send cases fail on unchanged master.
- Green after rebase: 531 tests pass, one existing test is skipped,
across TaskChatThread, IssueChatThread, and useRunnerSubmission.
- Chromium: the existing compact-startup responder test passes on a
disposable local instance. Frame sampling checks that the same identity
stays mounted through acknowledgement and process startup.
- UI typecheck and token gates pass. Initial typecheck lacked generated
plugin SDK declarations; it passed after local server setup built that
dependency.
- Affected checks passed after rebase on `de9ed52c0b`. Final CI on
`de9ed52c0bd6a6f7738614af31aec1eae2b871d0`: 59 checks passed, four
skipped, no failures. [CI
run](https://github.com/paperclipai/paperclip/actions/runs/42646038090).
Greptile and Paperclip review both gave 5/5 with no actionable findings
or unresolved review threads.

## Risks

Low scope: client startup feedback only. An old intent must not hide a
new admission, but a new failure must still end it. Existing backoff and
failure tests remain covered. The reopen exception applies only to an
explicit reopen and ends when the reopened status arrives. No API,
database, permission, or provider behavior changes.

## Model Used

OpenAI Codex, GPT-6 family. The exact serving model ID and
context-window size are not exposed in this session. Capabilities used:
reasoning, source editing, shell execution, and browser verification.

## 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
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-11-09 09:49:19 -06:00
..
…

@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.