Commit Graph
2501 Commits
Author SHA1 Message Date
Dotta d354ecadfa PAP-2820 Enforce issue transition dispositions 2026-04-29 10:26:50 -05:00
DottaandPaperclip 9413f55381 Add canonical issue execution disposition classifier
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-29 10:19:22 -05:00
DottaandPaperclip 628d879978 Move issue cost summary above activity feed
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-29 09:49:51 -05:00
Dotta eb6957fa86 Fix mention chip padding cascade 2026-04-29 09:38:50 -05:00
DottaandPaperclip 229487afef Unify issue activity ledger
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-29 08:49:35 -05:00
DottaandPaperclip ffe319a3f7 PAP-2789 Simplify waiting banner Owner/Resume rows and fix Jump anchor
The explicit-wait IssueBlockedNotice rendered Target/Owner/Resume as a row
of pills. Drop the Target pill entirely and render the remaining Owner and
Resume entries as a plain dl/dt/dd block — the value matters more than the
chip styling for these long-form details.

The "Jump to questions/confirmation/approval" affordance referenced anchor
ids that did not exist in the DOM (`issue-thread-interaction-{id}` and
`issue-approval-{id}`); the actual anchors are `interaction-{id}` and
`approval-{id}`. Switch to those ids and use a button with
scrollIntoView({behavior:"smooth"}) so the jump actually scrolls to the
target.

Add a small ExplicitWaitingJumpAnchor component that flips the arrow ↑/↓
based on whether the target is above or below the banner, recomputing on
scroll/resize.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-28 22:34:52 -05:00
DottaandPaperclip bcc88b561a PAP-2778 Wrap waiting pills instead of overflowing
The Target/Owner/Resume chips in the explicit-wait IssueBlockedNotice
banner used inline-flex with `truncate max-w-[Nrem]` on inner spans, so
on narrow viewports a single chip (especially Resume's full sentence)
extended past the container edge. Cap each chip at max-w-full and let
the value span wrap on word boundaries; desktop layout is unchanged.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-28 21:07:29 -05:00
DottaandPaperclip 9703830313 PAP-2753 Add copy button to markdown code blocks
Wraps fenced code blocks in MarkdownBody with a relative container and an
absolute-positioned Copy button (top-right) that copies the block contents
to the clipboard via navigator.clipboard with an execCommand fallback for
non-secure contexts. The button is hidden by default and reveals on hover
or focus, swaps to a check icon and "Copied\!" label for ~1.5s after
clicking, and falls back to "Copy failed" when the clipboard write throws.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-28 19:05:52 -05:00
DottaandPaperclip 08a9e0caf0 PAP-2731 Implement sky explicit-wait UI surfaces
Replaces the rose liveness-break banner for issues whose blocker-attention
read model reports `state="covered"` with `reason="explicit_waiting"`.

- IssueBlockedNotice: add a sky-toned banner with Hourglass icon, kind-aware
  headline/body copy (plan confirmation, user response, suggested tasks,
  board approval, generic fallback), Target/Owner/Resume pill row, a "Jump
  to confirmation" anchor, and a sky chip strip for parent-of-leaf chain
  waits. Rose banner still wins on tie via the existing precedence.
- StatusIcon: add a sky ring + bottom-right nub for explicit_waiting and
  emit `data-blocker-attention-state="explicit_waiting"`. Tooltip is
  "Waiting on board/user/agent" or prefixed "Blocked · ..." when blocked.
- IssueRow: add a sky `Waiting · {owner}` pill (collapses to `Waiting` on
  mobile) when the row's attention reason is explicit_waiting. Owner label
  resolves via new optional agent/user maps wired in by IssuesList & Inbox.
- IssueDetail/IssueChatThread: lift the linkedApprovals query into the chat
  tab and pass interactions/approvals/agentMap/userLabelMap/currentUserId
  through to the new banner.
- Storybook + tests: extend coveredBlockedMatrix with sky cells, add four
  new BlockedNotice fixtures (plan, user response, board approval, chain),
  and cover the new states with unit tests on StatusIcon, IssueBlockedNotice,
  and IssueRow.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-28 19:00:13 -05:00
DottaandPaperclip 5adbe69381 Harden pending wait recovery gating
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-28 18:31:24 -05:00
Dotta 7f9ae0adcd Harden recovery wait boundaries 2026-04-28 18:20:46 -05:00
DottaandPaperclip c1fd7521a8 PAP-2729 Handle interaction waiting lifecycle
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-28 18:13:05 -05:00
DottaandPaperclip 1e68cb9be0 Handle explicit waits in liveness read models
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-28 18:06:29 -05:00
DottaandPaperclip b72ab70a4f Fix pause resume QA blockers
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-28 18:02:28 -05:00
DottaandPaperclip 7a57a54b77 Implement issue pause resume UI
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-28 17:38:21 -05:00
DottaandPaperclip 2834e356d9 PAP-2720 Load full thread before jump-to-latest
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-28 17:23:36 -05:00
DottaandPaperclip 8d1647b039 PAP-2672 Converge Jump-to-latest on the absolute newest comment
The user reported having to click Jump-to-latest ~10 times before the
viewport actually pinned to the latest comment on long threads (e.g.
PAP-2536). The virtualizer estimates 220px per unmeasured row, so
totalSize is hugely underestimated until rows render and get measured;
a single smooth scroll lands above the real bottom and each subsequent
click walks closer as more rows mount and expand.

- IssueChatThread.handleJumpToLatest now awaits an optional
  onRefreshLatestComments before resolving the latest target so any
  comment that arrived after the initial load (or was dropped on a
  live-update reconnect) is in the loaded set first.
- scrollToLatestCommentWithSettle issues the initial smooth scroll,
  then on an 80 ms tick re-issues scrollIntoView({ block: "end" }) on
  the latest comment row for up to 4 s, exiting once the row's bottom
  matches the scroll container's bottom (within 4 px) and scrollTop +
  scrollHeight have been stable for 3 ticks. If the row hasn't been
  mounted into the virtualizer buffer, scrollToIndex is used to nudge
  the offset until it is.
- IssueDetail destructures `refetch` from the comments useInfiniteQuery
  and threads refetchLatestComments through to IssueChatThread.

QA verified on PAP-2720: single-click convergence in 327-407 ms across
5 successive trials, comment-fa353646 lands flush with the viewport
bottom (-0.44 px sub-pixel), stopped-scroll stability holds.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-28 17:09:41 -05:00
DottaandPaperclip de4ce9828d PAP-2643 Phase 3: gate run-liveness continuation and scheduled retry promotion under pause holds
Suppress bounded run-liveness continuation wakes when an active pause hold
covers the issue, and cancel due scheduled retries with errorCode `issue_paused`
instead of promoting them only to be cancelled at claim time. Adds regression
coverage for both gates plus the no-pause-hold passthrough invariant.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-28 16:57:28 -05:00
DottaandPaperclip 47d862b4b2 Show agent models on agents page
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-28 16:32:41 -05:00
DottaandPaperclip 38b57c5d56 Render rose recovery_needed surface across StatusIcon, BlockedNotice, and rows
StatusIcon adds an AlertTriangle overlay on the red-ring blocked variant
when the read model reports recovery_needed; tooltip and aria-label
spell out the liveness break and which leaf is invalid.

IssueBlockedNotice gets a rose container variant with two copy
templates: parent-perspective ("paused at a liveness break in [leaf]")
and leaf-perspective ("productive run that exited without queueing a
continuation"). The sub-row label flips to "Liveness break at" and an
owner pill renders with the next-action verb derived from the
nextActionHint.

IssueRow surfaces "liveness break at {leaf}" in the meta line for
recovery_needed parents so inbox/MyIssues rows show the actionable leaf
without opening the parent.

The status-language Storybook matrix gains the four new state/reason
combinations and parent/leaf-perspective notice variants. Targeted
vitest cases cover both the icon overlay and notice rendering.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-28 15:59:14 -05:00
DottaandPaperclip 3ea2ff4187 Surface invalid-leaf recovery_needed in blockerAttention read model
A blocked parent like PAP-2089 currently reports a generic
needs_attention chain even when its leaf is the productive-run-stopped
shape from PAP-2674's plan. Extend listIssueBlockerAttentionMap to
fetch each candidate leaf's latest issue-linked succeeded run plus its
productivity-review state, classify the leaf as recovery_needed when it
matches the shape, and propagate the leaf identifier, next-action
owner, and CTA hint up to the root. The leaf itself also surfaces
recovery_needed on its own attention so the leaf-level notice can
render when an inbox wake lands directly on it.

Adds two integration cases (productive_run_stopped and
continuation_exhausted) to the embedded-Postgres regression suite.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-28 15:59:03 -05:00
DottaandPaperclip 7d475f85bf Add recovery_needed and next-action surface to IssueBlockerAttention
Phase 5 of the liveness plan needs the blocker read model to distinguish
a "productive run stopped without continuation" leaf from generic
attention or stalled-review chains. Extend the shared type so server and
UI share one vocabulary for the new surface (state, reasons, owner,
hint).

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-28 15:58:54 -05:00
Dotta 2656a86dae Recover productive stranded runs 2026-04-28 15:30:19 -05:00
DottaandPaperclip 4b309a9e3b Classify runnable liveness follow-up
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-28 15:27:32 -05:00
Dotta 55518170ad Split run progress from liveness disposition 2026-04-28 15:23:52 -05:00
DottaandPaperclip 90e6a394c7 Fix productivity review badge routing
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-28 15:12:20 -05:00
DottaandPaperclip 45f1bc293b test: encode productive terminal liveness regression
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-28 13:35:31 -05:00
DottaandPaperclip 930a468772 Cover issue chat latest comment jump
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-28 13:24:07 -05:00
DottaandPaperclip b0d6ec582d Cover agent issue mutation ownership
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-28 13:24:03 -05:00
DottaandPaperclip 14a149c79f Harden productivity review request depth
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-28 13:24:00 -05:00
DottaandPaperclip 9465d04755 Fix subtree resume pause release
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-28 13:23:56 -05:00
DottaandPaperclip ec2c5537fc Merge origin/master into master
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-28 13:19:24 -05:00
DottaandPaperclip b6cf7dd91a Enable routine description mentions
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-28 13:05:48 -05:00
DottaandPaperclip e71b27fbd4 Stabilize infinite issue paging
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-28 12:57:49 -05:00
DottaandPaperclip 889cf660ac Page issues list with scroll offsets
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-28 12:52:09 -05:00
DottaandPaperclip 19c786a20b docs: refresh v1 implementation docs
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-28 12:49:00 -05:00
DottaandPaperclip 9c2dbab2fc PAP-2660: Bind issue chat virtualizer to <main> scroll container
The Phase 3 virtualizer (PAP-2645) used useWindowVirtualizer, but on the
real issue page the chat lives inside `<main id="main-content"
overflow-auto>`. Window scroll never moves on desktop, so the virtualizer
only ever mounted the first 7 rows and the chat area went blank past the
first viewport. Detect the actual scroll container at mount via DOM walk
and rekey the inner virtualizer to use element-mode observers/scroll-fn
when an overflow ancestor exists; fall back to window mode for mobile and
the auth-free perf fixture, where the document scrolls.

Adds a regression test that mounts IssueChatThread inside an overflow-auto
ancestor and asserts jump-to-latest drives that element's scrollTo, not
window.scrollTo.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-28 12:45:27 -05:00
DottaandPaperclip 1cb1d7c61b docs: update goal and product accuracy
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-28 12:44:54 -05:00
DottaandPaperclip 9a2c345866 PAP-2659: Warn before sending issue reply with no assignee
If the issue reply composer would post without any assignee, the first
Send press now surfaces a warning toast instead of submitting. A second
press confirms the user wants to proceed unassigned, and changing the
assignee resets the confirmation.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-28 12:07:03 -05:00
DottaandPaperclip 09923b01b2 Make issues page load more on scroll
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-28 11:48:02 -05:00
DottaandPaperclip 39ba2797fb Preserve virtualized issue chat anchors
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-28 11:44:03 -05:00
DottaandPaperclip 4c02abd919 PAP-2645: Virtualize long issue chat threads
Add @tanstack/react-virtual and gate IssueChatThread on a 150-row
threshold. Thread shorter than the threshold still uses the direct
render path; longer threads window the merged feed via
useWindowVirtualizer with dynamic measurement and overscan, so the
document scroll continues to represent the full conversation height
without introducing a nested scrollbar.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-28 11:29:41 -05:00
DottaandPaperclip 9a35d3bd0d Isolate issue thread row rendering
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-28 11:17:10 -05:00
DottaandPaperclip a2be4580ae Add long-thread issue chat perf fixture
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-28 11:11:26 -05:00
DottaandPaperclip 647c2c487e Tighten shared project workspace runtime stop/restart auth
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-28 11:02:27 -05:00
DottaandPaperclip 42e1b1bfa1 Split dialog action subscriptions
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-28 10:33:32 -05:00
DottaandPaperclip e090d9a77b PAP-2615: rename source-header productivity-review pill to "Under review"
UX feedback split the badge by role: on the source issue the linked pill
describes a state ("Under review"), while on the productivity-review issue
itself the static pill identifies the kind of issue ("Productivity review").
Tooltip and aria-label still surface the formal name on hover.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-28 09:44:03 -05:00
DottaandPaperclip 484d37feb9 Reject prompt templates for new bundled agents
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-28 09:36:12 -05:00
DottaandPaperclip b779e43272 PAP-2614: Surface productivity review state in issue UI
Adds a productivityReview lookup to single-issue and list responses, plus
a ProductivityReviewBadge component that surfaces the open productivity
review on the source issue's header (with trigger/no-comment-streak
detail in the tooltip), and a compact eye glyph next to the StatusIcon
on IssueRow so operators can spot yellow tasks in any list. The review
issue itself shows a static "Productivity review" pill in the header
when its originKind matches.

Also extends the shared IssueOriginKind union with the recovery-side
kinds (harness_liveness_escalation, issue_productivity_review,
stranded_issue_recovery) so UI checks against issue.originKind type-check.

Wires the new helper through GET /issues/:id, GET /companies/:id/issues
(via issueService.list), and GET /issues/:id/heartbeat-context. Adds a
status-language Storybook story matrix for UX review.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-28 09:27:16 -05:00
DottaandPaperclip e7d32f19cd Clear legacy prompt templates for bundled agents
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-28 09:15:53 -05:00