paperclip/ui
Dotta 97e0752158
Fix work timeline visible stats and kickoff attribution (#9271)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - The work timeline helps operators understand what agents did, when
they did it, and who kicked off each run
> - Timeline statistics should describe the window the operator is
viewing, not hidden work outside the viewport
> - Kickoff chips should point to the run that was actually closest to
the triggering edge, not stale later runs on the same issue
> - This pull request scopes timeline summary stats to the visible
window and deduplicates kickoff attribution to the nearest matching run
> - The benefit is that operators get a more accurate, less misleading
timeline while scanning agent work

## Linked Issues or Issue Description

No matching public GitHub issue was found. Public duplicate search found
no open PR for "work timeline visible window kickoff".

### What happened?

Work timeline summary stats could count hidden spans outside the
selected visible window, and kickoff attribution could appear on a stale
matching run instead of the closest run associated with the edge.

### Expected behavior

Visible timeline stats should reflect only the current visible range,
and each kickoff edge should attach to the nearest matching run.

### Steps to reproduce

1. View a work timeline with agent spans that begin before or end after
the selected visible window.
2. Compare the summary stats against only the spans visible in the
viewport.
3. View repeated runs for the same actor and issue that share a kickoff
edge.
4. Check which run gets the kickoff chip.

### Paperclip version or commit

Current `origin/master` before this PR.

### Deployment mode

Board UI.

## What Changed

- Filters timeline summary stats to the visible time window.
- Passes visible-window metadata into the work timeline chart and page
state.
- Assigns each kickoff edge to only the closest matching run, with
deterministic tie-breaking.
- Adds focused regression coverage for visible stats and stale kickoff
attribution.

## Verification

- `pnpm exec vitest run
ui/src/components/timeline/WorkTimelineChart.test.tsx
ui/src/lib/timeline/layout.test.ts ui/src/pages/Timeline.test.tsx` -- 38
tests passed.
- `pnpm check:token-gates` -- all gates clean.
- `git diff --check origin/master...HEAD` -- passed.

## Visual Evidence

Public review artifacts for the user-visible timeline behaviours. The
SVGs use sanitized run labels and no internal Paperclip issue
identifiers.

![Visible-window stat panel before and after
scroll](5f33032ee3/visible-window-stats.svg)

![Kickoff attribution before and after stale-chip
fix](3e0ac8de60/kickoff-attribution.svg)

Artifact gist:
https://gist.github.com/cryppadotta/dc2645d54c4bc56ffc0323224b3ea4bf

## Risks

- Low risk. The change affects timeline rendering and summary
calculations only; the main risk is a subtle difference in which run
gets a kickoff chip when multiple runs are very close together.

> 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. See `CONTRIBUTING.md`.

## Model Used

OpenAI Codex coding agent based on GPT-5, tool-enabled shell workflow.
Exact hosted model variant and context window were not exposed by the
runtime.

## 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-07-09 08:30:46 -05:00
..
public
src Fix work timeline visible stats and kickoff attribution (#9271) 2026-07-09 08:30:46 -05:00
storybook Make ACP the default engine for local adapters (#9238) 2026-07-08 19:05:03 -07:00
README.md
components.json
index.html
package.json Make ACP the default engine for local adapters (#9238) 2026-07-08 19:05:03 -07:00
tsconfig.json
vite.config.ts build(deps): upgrade lexical family to 0.46.0 and pin via overrides (fixes dual-version getType crash) (#9180) 2026-07-07 13:00:26 -07:00
vitest.config.ts build(deps): upgrade lexical family to 0.46.0 and pin via overrides (fixes dual-version getType crash) (#9180) 2026-07-07 13:00:26 -07:00
vitest.setup.ts

README.md

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