Commit Graph
1149 Commits
Author SHA1 Message Date
Dotta caf37a355d Revert "PAP-2731 Implement sky explicit-wait UI surfaces"
This reverts commit 08a9e0caf0.
2026-04-29 16:02:11 -05:00
DottaandPaperclip ed51123e3c PAP-2852 Add space-width gap between caret and mention menu
Per visual feedback the menu was sitting flush against the cursor;
introduce MENTION_MENU_CARET_GAP (10px) so the popover floats roughly
one space-width to the right of the caret.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-29 14:14:59 -05:00
DottaandPaperclip 33bcaa5a4c Allow recovery owners to cancel stale runs
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-29 14:00:36 -05:00
DottaandPaperclip 4c5eaeadd5 PAP-2822 Walk back visible disposition badges per board feedback
The board accepted the canonical executionDisposition payload + classifier
but found the visible badges in IssueRow / IssueProperties / Storybook too
noisy on production surfaces. UI-only walkback: keep the data layer, drop
every visible badge.

- Delete IssueDispositionBadge component and its test.
- Drop the badge import, suppression rule, and trailing-slot references in
  IssueRow (desktop + mobile). Existing waiting pill, status-icon ring, and
  blockerAttention copy remain unchanged.
- Drop the badge IIFE and related imports from IssueProperties so the
  Status row only renders the StatusIcon again.
- Prune the badge cases from IssueRow.test (Live, Stalled, dispatchable,
  Resuming, explicit-waiting suppression) so the file still type-checks.
- Storybook: remove "Canonical disposition badges" and "IssueRow with
  disposition badge inline" sections plus DispositionRowSurface and
  dispositionRowFixtures. The rest of Status Language is unchanged.

Kept: executionDisposition on issue payloads, the resolver and its test,
and the PAP-2818 contract doc — future features can consume the field
without re-running the classifier work.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-29 13:25:59 -05:00
DottaandPaperclip 326fd2f6fb Allow cancelling question interactions
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-29 11:54:37 -05:00
DottaandPaperclip 0b85f56d27 PAP-2853 Close 8px flip-gap on mention menu
Align CSS max-height with MENTION_MENU_HEIGHT (208) so the rendered
menu fills the layout-reserved space; previously max-h-[200px] clipped
the box 8px short of the JS layout budget, leaving a visible gap above
the caret line on the flipped path.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-29 11:48:01 -05:00
DottaandPaperclip aa1628008e PAP-2822 Address UX review on disposition badge
- Drop the dispatchable "Ready" variant from the badge: the only place it ever
  rendered was Storybook (IssueRow and IssueProperties already returned null
  for it). dispositionCategory now returns null for dispatchable.
- Pull agent_continuable into a discrete "Resuming" category with a muted
  indigo treatment so it doesn't share the rose alarm family with Recovery /
  Needs attention / Stalled, and surface "Resuming · n/m" on the visible
  badge instead of hiding the attempt counter in the tooltip.
- Differentiate human_escalation_required by owner on the visible label:
  Needs board / Needs manager / Needs owner / Needs external. Color stays in
  the rose family but the actionable bit is no longer hover-only.
- Bump invalid (Stalled) to a solid rose-600 fill so it stands out against
  the rest of the rose family at scan distance, satisfying the parent plan's
  acceptance criterion that the board can spot a stalled review leaf without
  reading the full thread.
- Mirror the IssueRow suppression rule on IssueProperties so the Status row
  doesn't double-render the same waiting/recovery signal as the chat-thread
  IssueBlockedNotice.
- Add aria-label={tooltip} on the badge so screen readers get the path
  detail, not just the category label.
- Storybook: rename and split the disposition matrix to cover all four
  escalation owners, both Resuming attempts, and add a populated IssueRow
  surface that shows the badge in production layout context (Live, Resuming,
  Needs board, Needs manager, Stalled).

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-29 11:45:11 -05:00
DottaandPaperclip 925ac9a3c1 PAP-2852 Anchor mention menu to caret and allow touch scrolling
Mention menu now sits on the same line as the caret and to the right of
the cursor (tracking each typed character instead of staying glued to
the @ marker). When the menu would overflow below the viewport it flips
above the line so it doesn't cover the line.

Touch handling no longer preventDefaults on touchstart, so the dropdown
scrolls natively on mobile; selection runs only on touchend if the
finger lifted with negligible movement (a tap, not a scroll).

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-29 11:16:43 -05:00
DottaandPaperclip 6ac545bae7 PAP-2822 Render execution disposition badge in board UI
Adds IssueDispositionBadge that maps the canonical disposition to a
small palette of categories (live, ready, waiting, blocked-chain,
recovery, needs attention, stalled). Renders the badge in the inbox
row and on the issue detail status row, suppressing it where the
existing waiting/recovery copy already conveys the same signal so we
don't double up. Storybook gains a section showing every category for
UX review.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-29 10:50:32 -05:00
DottaandPaperclip ed6600b9d1 Hide redundant sibling blocker chips
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-29 10:38:29 -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 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 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 90e6a394c7 Fix productivity review badge routing
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-28 15:12:20 -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 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 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 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
Dotta 930b717ba5 PAP-2607: nudge inline mention chips up 1px
Reviewer follow-up — pills sat slightly low after the baseline-to-middle
switch. position: relative + top: -1px raises them to optically center
with the surrounding cap height.
2026-04-28 09:09:12 -05:00
DottaandPaperclip 6df68f5305 PAP-2607: align inline mention chips on text baseline
Inline-flex baseline behavior is browser-dependent, which made skill/agent/issue
chips in MarkdownBody and the MDXEditor hang below the surrounding text. Switch
to vertical-align: middle and drop the vertical padding so the pill sits
centered on the line with the prose around it.

Adds a skill-chip line to the MarkdownBody storybook fixture so this regresses
loudly next time.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-28 08:19:22 -05:00
DottaandPaperclip e3869bda4c Allow configurable issue attachment limits
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-28 08:17:52 -05:00
DottaandPaperclip 559a843a25 Improve new issue dialog typing performance
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-28 07:58:05 -05:00
DottaandPaperclip 48a7c43e23 PAP-2605: unify routine variables container and add help modal
Wrap the variables editor in a single rounded container so the
"Variables" header and the per-variable cards share one border with
internal dividers, instead of stacking as two visually separate
containers when expanded.

Add a help button to the variable instructions hint that opens a modal
explaining custom {{variable_name}} placeholders and the built-in
{{date}} and {{timestamp}} variables.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-28 07:42:30 -05:00
Dotta af903a3d61 Add routines sort control 2026-04-28 07:39:29 -05:00
DottaandPaperclip d0bdbe11a9 Stabilize inline selector keyboard handling (#4617)
## Thinking Path

> - Paperclip's board UI relies on compact selectors for frequent issue
and agent edits.
> - Inline selectors often live inside larger keyboard-aware surfaces
such as composers and popovers.
> - Arrow, enter, tab, and escape keys handled by the selector should
not leak to parent document shortcuts.
> - Stale company selection should also stay hidden until the company
list confirms it is valid.
> - This pull request tightens inline selector keyboard handling and
adds regression coverage for stale company bootstrap behavior.
> - The benefit is fewer accidental parent interactions and safer
company-scoped UI initialization.

## What Changed

- Added a stable empty `recentOptionIds` default so selector filtering
does not get a new array every render.
- Mirrored highlighted option state into a ref so Enter/Tab commits the
current highlighted option reliably after keyboard navigation.
- Stopped propagation for selector-owned navigation/commit/escape keys.
- Added jsdom regressions for inline selector keyboard handling and
CompanyProvider stale selection behavior.

## Verification

- `pnpm exec vitest run ui/src/components/InlineEntitySelector.test.tsx
ui/src/context/CompanyContext.test.tsx`
- Targeted selector and CompanyProvider tests pass cleanly without React
`act(...)` warnings.
- Screenshots not attached: this is keyboard/state behavior covered by
component tests.

## Risks

- Low risk: changes are scoped to inline selector key handling and
tests. The main behavior shift is intentionally preventing handled
selector keys from reaching parent listeners.

> 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

- OpenAI Codex coding agent based on GPT-5, tool-enabled local
repository and shell access, Paperclip heartbeat context.

## 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 run tests locally and they pass
- [x] I have added or updated tests where applicable
- [ ] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-27 20:04:35 -05:00
DottaandPaperclip 43b0f2ae58 Add pause and resume actions to sidebar agents (#4616)
## Thinking Path

> - Paperclip operators need fast control over the agents running their
company.
> - The sidebar is the persistent place operators scan agent state while
navigating the board UI.
> - Agent pause and resume already exist as control-plane actions, but
sidebar users had to navigate away to use them.
> - This pull request adds a compact per-agent action menu in the
sidebar.
> - It keeps edit, pause, and resume close to the visible agent list
while preserving existing navigation behavior.
> - The benefit is faster operator intervention when an agent needs to
be paused or restarted.

## What Changed

- Refactored sidebar agent rows into a small item component with a
hover/focus action menu.
- Added edit, pause, and resume actions using existing agent API calls
and cache invalidation keys.
- Added success/error toasts for pause and resume mutations.
- Tracked pause/resume pending state per agent so one active mutation
does not disable every sidebar row.
- Disabled direct sidebar resume for budget-paused agents and labeled
that state clearly.
- Added jsdom coverage for active-agent pause, paused-agent resume,
per-agent pending state, and budget-paused resume protection.
- Added visual review artifacts for the default row and opened action
menu:
  - [Sidebar row](docs/pr-screenshots/pr-4616/sidebar-agent-row.png)
- [Sidebar action
menu](docs/pr-screenshots/pr-4616/sidebar-agent-actions.png)

## Verification

- `pnpm exec vitest run ui/src/components/SidebarAgents.test.tsx`
- `pnpm --filter @paperclipai/server prepare:ui-dist`
- Browser screenshot pass against a temporary local trusted instance at
`http://127.0.0.1:3102` using Playwright.

## Risks

- Low risk: UI-only addition using existing agent pause/resume
endpoints. The main risk is layout crowding for very narrow sidebars,
mitigated by the icon-only trigger and existing truncation.
- Budget-paused agents now require a non-sidebar path to resume, which
is intentional to avoid accidentally restarting agents stopped by budget
enforcement.

> 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

- OpenAI Codex coding agent based on GPT-5, tool-enabled local
repository and shell/browser access, Paperclip heartbeat context.

## 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 run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-04-27 20:03:54 -05:00
DottaandPaperclip d3123be870 Fold sub-issue blocker count into chip
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-27 20:03:20 -05:00