fix(ui): restore task page archive shortcut (#13253)

## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The task detail page gives operators keyboard shortcuts for fast
task work.
> - The `y` shortcut must archive the open task from the inbox and
return the operator to the inbox.
> - A streamlined UI gate limited this shortcut to tasks opened from a
selected inbox row.
> - Direct task pages no longer ran the shortcut.
> - This pull request removes that gate and adds regression coverage.
> - The benefit is consistent keyboard operation from every visible task
page.

## Linked Issues or Issue Description

**What happened?**

The `y` keyboard shortcut did nothing on a task page opened outside the
inbox.

**Expected behavior**

The `y` shortcut archives the open task from the inbox and returns the
operator to `/inbox`.

**Steps to reproduce**

1. Enable keyboard shortcuts.
2. Open a visible task from the Tasks page.
3. Press `y` while focus is outside an editor.
4. Observe that the task does not archive.

**Paperclip version or commit**

Current `master` before this pull request.

**Deployment mode**

Local development.

## What Changed

- Enable the `y` archive shortcut on every visible task detail page when
keyboard shortcuts are enabled.
- Keep the existing input, dialog, modifier, hidden-task, and
pending-request guards.
- Verify that `y` archives the task and navigates to `/inbox` for a task
opened from the Tasks page.

## Verification

- `pnpm exec vitest run ui/src/pages/IssueDetail.test.tsx
ui/src/lib/keyboardShortcuts.test.ts
ui/src/lib/issueDetailBreadcrumb.test.ts` (139 tests passed)
- `pnpm --filter @paperclipai/ui typecheck`
- `pnpm check:token-gates`
- `pnpm --filter @paperclipai/ui build`
- The full workspace typecheck and build reached the Rust runner. This
environment does not include `cargo`, so the Rust steps did not run.
- The full test suite entered unrelated serialized external-chat
integration tests. It was stopped after the affected UI suite passed.

## Risks

- Low risk. The change restores the shortcut behavior that existed
before the streamlined UI gate.
- The shortcut still ignores text inputs, open dialogs, modifier keys,
and hidden tasks.

> 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. The Paperclip runtime did not expose the exact model ID
or context window. The model used reasoning, repository tools, code
execution, and test execution.

## 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)
- [ ] 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

Co-authored-by: Paperclip <noreply@paperclip.ing>
This commit is contained in:
Dotta 2026-09-11 15:11:56 -05:00 committed by GitHub
parent ce09ea40b0
commit a27dd722a2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 6 additions and 7 deletions

View File

@ -2643,7 +2643,7 @@ describe("IssueDetail", () => {
});
});
it("keeps inbox archive actions scoped to an inbox-origin task", async () => {
it("archives a task-page issue with y and returns to the inbox", async () => {
mockLocation.state = createIssueDetailLocationState(
"Tasks",
"/issues/all",
@ -2679,7 +2679,10 @@ describe("IssueDetail", () => {
document.dispatchEvent(
new KeyboardEvent("keydown", { key: "y", bubbles: true }),
);
expect(mockIssuesApi.archiveFromInbox).not.toHaveBeenCalled();
await waitForAssertion(() => {
expect(mockIssuesApi.archiveFromInbox).toHaveBeenCalledWith("issue-1");
expect(mockNavigate).toHaveBeenCalledWith("/inbox", { replace: true });
});
});
it("arms the inbox archive shortcut only for the selected inbox row", async () => {

View File

@ -92,7 +92,6 @@ import {
readIssueDetailHeaderSeed,
withIssueDetailHeaderSeed,
rememberIssueDetailLocationState,
shouldArmIssueDetailInboxQuickArchive,
} from "../lib/issueDetailBreadcrumb";
import {
resolveIssueActiveRun,
@ -5667,10 +5666,7 @@ export function IssueDetail({ tasksTab }: { tasksTab?: TaskSidePanelProps["tasks
const goToInboxShortcutArmedRef = useRef(false);
const goToInboxShortcutTimeoutRef = useRef<number | null>(null);
const canQuickArchiveFromInbox =
keyboardShortcutsEnabled &&
(!streamlinedUiEnabled ||
(isFromInbox && shouldArmIssueDetailInboxQuickArchive(location.state))) &&
!issue?.hiddenAt;
keyboardShortcutsEnabled && !issue?.hiddenAt;
useEffect(() => {
if (!issue?.id || !canQuickArchiveFromInbox) return;