mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-29 04:25:52 +01:00
fix(ui): hide task row retry status labels (#18017)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Task lists and the inbox help people scan their work. > - Shared task rows show system interruption messages beside task titles. > - These messages add detail that the person cannot act on from the row. > - This pull request removes the three system interruption labels from those rows. > - People can still open the task to inspect progress and use Retry. ## Linked Issues or Issue Description Refs #16965, which introduced these labels. Related recovery report: #17386. This change only removes row text and does not resolve that report's retry behavior. **What existing behavior does this improve?** The shared task rows in task lists and the inbox. **Current behavior** Rows show “Retry available,” “Thinking,” or “Trying again soon” beside the title for unresolved system interruptions. **Proposed behavior** Omit all three labels from shared task rows. Keep the existing system-interruption guard so the row does not show a legacy recovery chip in their place. Keep task status, other badges, and retry controls inside the task. **Reason and benefit** People can scan task titles with less incidental execution text. **Breaking changes** The three row labels disappear. APIs, recovery behavior, and task conversation controls stay the same. ## What Changed - Remove the system interruption text from every shared task-row presentation. - Cover working, scheduled-retry, and failed interruptions in both row presentations, including a legacy recovery action that must stay hidden. - Record the expected row behavior and verification states in the task feature map. ## Verification - Passed: token gates, feature-map contract and reference checks, and Git diff whitespace checks. - Passed: 83 component tests in `IssueRow.test.tsx` and `Inbox.test.tsx`, including the new regression cases; full `pnpm -r typecheck`; full `pnpm build`. - The full local `pnpm test:run` was attempted and stopped after 16 database-dependent failures. An independent disposable `initdb` reproduced `FATAL: could not create semaphores: No space left on device`. The host has exhausted its macOS System V semaphore capacity. All required CI test lanes passed on the final commit and provide full database-suite coverage. An earlier attempt also found an unbuilt plugin SDK; building that existing dependency repaired collection before this database failure. - Review the working, scheduled-retry, and failed interruption branches. Each returns no system label. The existing guard still suppresses legacy recovery chips. - Independent source review found no actionable code issues. Regression cases check title navigation, removal of the three labels, and suppression of replacement recovery chips. - All required CI gates passed on commit `dd1d7b08dbba8a10a95c5d24c4aea64479befe95`: typecheck, general and serialized tests, browser suites, build, canary, and Runner checks. - Greptile reviewed that commit at 5/5 with no open findings. The optional Paperclip review also returned 5/5 with no findings; its check status is neutral. ## Risks - Low risk. This removes row text only. Task status, recovery records, other badges, and task-level retry actions keep their current behavior. ## Model Used OpenAI Codex, GPT-6 family. This session does not expose an exact model ID or context-window size. The assistant used reasoning, shell tools, and subagents for source review and validation. ## 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>
This commit is contained in:
1 parent
8279c99008
commit
83709f75eb
3 files changed
+28
-4
No files matched your search
@@ -88,6 +88,8 @@ Use a human/unassigned task to verify persistence without invoking a model.
|
||||
|
||||
Automated: [task-list helpers](../../ui/src/pages/Issues.test.tsx) cover search URLs, pagination, deduplication, and presentation constants. The suite does not render the page or exercise filtering, grouping, opening a task, and returning; those interactions still need a running-browser check.
|
||||
|
||||
Task and inbox rows omit the system interruption labels **Thinking**, **Trying again soon**, and **Retry available**. [Shared row tests](../../ui/src/components/IssueRow.test.tsx) cover working, scheduled-retry, and failed interruptions in both row presentations, including suppression of replacement recovery chips. Task status and other relevant badges remain visible; retry controls remain inside the task conversation.
|
||||
|
||||
Manual: Seed human-created, agent-created, scheduled routine, human-initiated chat-channel, and creator-less tasks. Confirm automation is hidden by default, **show agent-created tasks** reveals it, reload preserves the choice, and Clear filters hides it again. Verify list and board search with automation newer than the human results, and expand contextual ancestors/subtasks without promoting unrelated automated roots. Repeat in project task lists. Agent profiles and task-detail subtasks retain complete history.
|
||||
|
||||
Manual: Filter by status and assignee, change grouping/sort, open a task, and return. Verify the correct records and selected view survive navigation and reload. Include an empty result and a failed request.
|
||||
|
||||
@@ -844,6 +844,31 @@ describe("IssueRow", () => {
|
||||
return snapshot;
|
||||
}
|
||||
|
||||
it.each(["working", "retry_scheduled", "failed"] as const)(
|
||||
"omits %s system interruption feedback without exposing legacy recovery in list rows",
|
||||
(state) => {
|
||||
const root = createRoot(container);
|
||||
const issue = recoveryIssue(at(3 * 60_000));
|
||||
issue.interruption = {
|
||||
intentId: "saved-input", responsibility: "system", state,
|
||||
nextRetryAt: state === "retry_scheduled" ? at(3 * 60_000) : null,
|
||||
canRetry: state === "failed", userAction: null,
|
||||
sourceRunIds: ["run-1"], observedRunId: "run-1",
|
||||
};
|
||||
try {
|
||||
for (const presentation of ["task", "legacy"] as const) {
|
||||
act(() => root.render(<IssueRow issue={issue} presentation={presentation} />));
|
||||
expect(container.textContent).toContain(issue.title);
|
||||
expect(container.querySelector("[data-inbox-issue-link]")?.getAttribute("href")).toBe("/issues/PAP-1");
|
||||
expect(container.textContent).not.toMatch(/Retry available|Thinking|Trying again soon|Recovery in progress/);
|
||||
expect(container.querySelector("[data-testid='issue-row-recovery-indicator']")).toBeNull();
|
||||
}
|
||||
} finally {
|
||||
act(() => root.unmount());
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
it("shows native export activity from the action even without a scheduled retry", () => {
|
||||
const issue = recoveryIssue(at(-5 * 60_000));
|
||||
Object.assign(issue.activeRecoveryAction!, {
|
||||
|
||||
@@ -221,10 +221,7 @@ export function IssueRow({
|
||||
// The row already carries the issue's own scheduled retry, so the chip can tell a retry the
|
||||
// scheduler is actually running from one whose due time simply passed.
|
||||
const recoveryIndicator = issue.interruption?.responsibility === "system" && issue.interruption.state !== "resolved"
|
||||
? <span className="text-xs text-muted-foreground" data-testid="issue-row-interruption">
|
||||
{issue.interruption.state === "working" ? "Thinking"
|
||||
: issue.interruption.state === "retry_scheduled" ? "Trying again soon" : "Retry available"}
|
||||
</span>
|
||||
? null
|
||||
: recoveryAction && !requiresExecutionReconciliation(recoveryAction.cause)
|
||||
? renderRecoveryChip(recoveryAction, selected, { scheduledRetry: issue.scheduledRetry ?? null })
|
||||
: null;
|
||||
|
||||
Reference in new issue
Block a user