Files
PaperClipAI/ui
DottaandClaude Opus 5.5 8227259d86 feat(task-chat): show the agent's native plan as a task list above the composer (#19252)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Agents run through the native runner. The runner turns each
harness's native plan into a canonical `plan.updated` event.
> - The task chat did not show these plans. A small "Step 2 / 5" pill
showed the checklist only on hover, and in live runs it received no plan
data.
> - Live tests found three breaks. The UI flattened `plan.updated` into
tool rows. Headless Claude Code hides its task tools from current
models. Codex ships its `update_plan` tool disabled.
> - This pull request fixes the three breaks and replaces the pill with
a docked plan card above the composer.
> - The benefit is that users see what the agent finished, what it does
now, and what comes next. The view is the same for Claude, Codex, Grok
and Copilot.

## Linked Issues or Issue Description

**Subsystem affected**
Task chat UI (turn status island), native runner ACPX launch environment
for Claude, and native runner Codex app-server launch arguments.

**Problem or motivation**
Harnesses report native plans, and the runner records them as
`plan.updated` events. Users do not see them. The live transcript
builder converts `plan.updated` into generic tool rows, so the plan
steps are lost. Claude Code in headless mode does not offer
TaskCreate/TaskUpdate for current models, so Claude never makes a plan.
Codex 0.160 has `update_plan` disabled by default, so Codex writes its
checklist into a Paperclip document instead.

**Proposed solution**
Keep the full plan snapshot in the live transcript. Enable the Claude
task tools with `CLAUDE_CODE_ENABLE_TODO_TOOLS=1` in the ACPX launch
environment. Enable the Codex plan tool with
`tools.update_plan.enabled=true`. Show the plan as a docked card with
clear rules for when it shows, collapses and hides.

**Alternatives considered**
Show the plan only in the hover popover (the old behavior). Users did
not find it. Write the plan into the issue Plan document. That mixes a
per-turn checklist with the reviewed planning document.

**Roadmap alignment**
This makes existing native runner plan events visible. It adds no new
protocol or data model.

**Additional context**
Grok and Copilot needed no harness change. Cursor could not start in a
local worktree instance (an unrelated startup admission problem), so
this PR does not verify Cursor.

## What Changed

- `ui/src/components/transcript/native-run-events.ts`: keep
`plan.updated` as `provider_activity` with family `plan` and the full
payload, not as a tool row.
- `ui/src/components/task-chat/TaskChatTurnStatusIsland.tsx`: replace
the hover pill with a docked plan card. It shows done, current, upcoming
and blocked steps, a progress bar and file-change totals.
- Visibility rules: hidden with no steps and after the run ends;
collapses when all steps are done; header only for one-step plans and
while a question or approval is pending; window around the current step
for plans over 7 steps; collapsed by default on mobile.
- `ui/src/components/TaskChatThread.tsx`: pass `defaultCollapsed`
(mobile) and `compact` (pending runtime request), and reset the card per
run.
- `ui/src/components/task-chat/transcript-adapter.ts`: keep the `failed`
step status.
- `packages/paperclip-runner/src/drivers/acpx/environment.ts`: set
`CLAUDE_CODE_ENABLE_TODO_TOOLS=1` for Claude launches. A host value
cannot turn it off.
-
`packages/paperclip-runner/src/drivers/codex/codex-security-config.ts`:
add `-c tools.update_plan.enabled=true` before the policy overrides and
the `app-server` subcommand.
- `ui/storybook/stories/tasks/task-chat-agent-plan.stories.tsx`: new
story for each state. It uses the production composer dock, composer and
question takeover.
- Tests for all of the above. `ui/src/index.css` replaces the unused
popover size token with a list max-height token.

## Verification

- `pnpm --filter @paperclipai/ui exec vitest run
src/components/transcript src/components/task-chat
src/components/TaskChatThread.test.tsx src/adapters/paperclip-runner`
(1345 tests pass).
- `pnpm --filter @paperclipai/paperclip-runner exec vitest run
src/drivers/acpx/environment.test.ts src/drivers/codex` (pass).
- UI and runner typecheck are clean. `pnpm check:token-gates` is clean.
- Storybook: open "Tasks and conversations / … / Task chat / Agent
plan". The "All States Gallery" story shows every state. "Live Run
Simulation" animates a run.
- Live test on a local worktree instance with real API keys: a
multi-step task for each harness. The card showed and updated during the
run for Claude (Opus 5.5), Codex (gpt-5.6-sol), Grok (grok-4.7) and
Copilot (gpt-5.6-luna). For Claude the card collapsed when all steps
were done and hid after the run ended.
- Codex probe: `codex exec` with the pinned 0.160 binary reports no
`update_plan` tool by default and reports the tool with `-c
tools.update_plan.enabled=true`.

## Risks

- Claude and Codex now get their plan tools. Agents can spend a few
tokens on plan updates. The tools are standard harness features.
- The Codex flag goes before the web-search and project-instruction
policy overrides, so the existing policy tail check still holds.
- Runs that finish fast show the card only briefly. This is the intended
hide rule.
- Cursor plan display is not verified.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.

## Model Used

- Claude Opus 5.5 (`claude-opus-5-5`) in Claude Code, with tool use
(shell, file edit, browser automation) and extended reasoning.

## 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
- [x] 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>
2026-11-05 09:09:39 -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.