31 KiB
created, status, requirements, system_design, legacy_specs
| created | status | requirements | system_design | legacy_specs | |||||
|---|---|---|---|---|---|---|---|---|---|
| 2026-09-10 | done |
|
|
Implementation Plan: Threads Task Actions
Overview
Deliver the existing six task operations from each Threads header using shared task actions, explicit target identity, and an inset phone drawer. Implement the shared action boundary first, integrate desktop and deck recovery second, complete phone interaction third, and publish accurate usage guidance last.
The tasks system owns this vertical capability because task identity,
eligibility, mutation results, and recovery are its contract. Existing UI
specifications continue to own the deck, shared header, saved-view query, and
viewport-driven session activity.
The user authorized implementation with "go for it" after the design-package checkpoint. All four work orders are complete in the primary session. No subagents or new platform tasks/sessions were used. Implementation and design files were uncommitted at that implementation handoff; publication follows in the user-requested Open PR workflow step.
Parent prerequisite
This workspace started clean at 21f24eb8b on
feature/add-task-actions-to-548. During this design turn, the parent committed
its completed mobile implementation as
0b4253fa71ba0fe85188bff8cd27c2860425c516
(fix(ui): improve mobile threads and shared listing headers) on
feature/improve-mobile-threa-f2f. The parent's working tree is clean.
Its committed docs/plans/mobile-threads/plan.md contains the execution results.
The branches diverge from b7a71e64a, so integration requires a normal merge,
not a fast-forward. The pinned parent commit was merged successfully at the
implementation start as facf9aef7, preserving this package. Its ancestry is verified and
the workspace dependencies are installed with the frozen lockfile.
Read-only inspection identified these parent integration points:
components/threads/mobile-thread-column-header.tsx: two-line title picker, Open task, status and session control.components/threads/threads-board.tsx: board-owned picker andrenderHeader(activeMobileTaskId)composition.components/threads/use-mobile-thread-position.tsandthread-viewport-geometry.ts: scroll-derived position independent of chat hydration;use-thread-column-activation.tsconsumes it.components/kanban/mobile-listing-*: compact shared page header/menu, withmobile-picker-sheet.tsxgainingonCloseAutoFocussupport.e2e/tests/task/mobile-threads-swipe.spec.tsand its swipe helper: held-touch midpoint, reversal, and paging evidence.
These paths are under apps/web/. The parent work orders and scoped guidance
were re-read after the normal merge and before feature edits. No individual
parent files were copied or recreated.
The separate Choose Threads as default home view subtask is not a dependency and contributes no work to this package.
Scope
In scope
- Header-only desktop context entry and an always discoverable overflow button.
- Priority, workflow-step move, cross-workflow send, supported links, archive, and confirmed delete through existing task behavior.
- Captured task/workspace identity, current eligibility, shared-state updates, failure recovery, deterministic thread fallback, and surviving-trigger focus.
- One inset phone drawer, in-surface nested navigation, localization, desktop density, touch sizing, containment, and unchanged native swiping.
- Focused TDD and desktop/mobile Playwright outcomes, rendered phone inspection, and usage documentation.
Out of scope
- Rebuilding the parent header, picker, inline pagination, or swipe logic.
- Default Home selection, saved-view behavior changes, or session management.
- New operations, bulk commands, providers, permissions, backend APIs, storage, plugin SDK changes, feature flags, or broad UI menu migration.
Technical approach
Shared task action boundary
hooks/use-task-menu-actions.ts shares archive/delete lifecycle and successful
removal cleanup with the sidebar. useTaskManagementFlow owns captured identity
and current eligibility. TaskManagementSurface composes those owners with
useTaskWorkflowMove, useUpdateTaskPriority and existing link hooks. Preserve current menu option
derivation in task-priority-context-menu.tsx, task-move-context-menu.tsx, and
task-switcher-link-menu.tsx. Extract a focused
components/task/task-management-menu.tsx composition for the requested six
groups. Keep the existing full switcher menu as the default consumer.
Factor the existing destructive lifecycle glue into the shared task boundary
and consume it from an existing menu caller as well as Threads. Give
useTaskRemoval a caller-selected stay-on-listing behavior with its current
navigation as the default. Test that option against stale global task selection
and HTTP/WS ordering. Thread adapters contain rendering, target selection, and
deck focus, never API transport or task business rules.
The shared host captures { taskId, workspaceId } on open and lives above the
column list. It resolves current task facts from the scoped snapshots by that
ID and retains the target through menu-to-dialog transitions. Reuse
TaskArchiveConfirmation, TaskDeleteConfirmDialog, and SidebarLinkDialogs.
Archive uses the shared preference and classification, including inline phone
confirmation when supported; complex confirmation and link dialogs replace the
menu before opening.
Threads entry and recovery
Compose the shared host at ThreadsBoard, leaving ThreadsPageClient unchanged. Add a thin
thread-task-actions.tsx header adapter. Extend TaskMenuButton for a
controlled opener/ref while preserving existing callers. Restrict the context
trigger to the task header and exclude session controls, transcripts, and
editors.
Add lib/threads/thread-selection-fallback.ts with the pure
resolveRemainingThreadId algorithm. Use the parent's viewport position and
last committed admitted order for reconciliation. Preserve current surviving
tasks and their scroll offset; otherwise use successor, predecessor, first
newly admitted task, or the existing empty state. Shared lifecycle events drive
admission. Late responses cannot reset newer focus, resurrect removed columns,
or rewrite /threads to task detail.
Phone composition
Add a shared task-domain task-management-drawer.tsx over the same option
sources and callbacks as desktop. Its page state contains root, priority,
steps, workflows, selected-workflow steps, and links. Use one Drawer instance,
one body scroller, visible Back, fixed header, dvh bounds, and safe-area
clearance. Compare the integrated parent versions of mobile-menu-sheet.tsx
and mobile-picker-sheet.tsx; do not reproduce the global nested-popper CSS.
Put the visible 44px overflow beside Open task in the parent's task header. Keep the page topbar and inline swiper as shipped by the parent. Phone and coarse-pointer entries use the drawer; fine-pointer controls retain compact sizes. Cover 320px, 360px, 700px phone widths and a coarse-pointer tablet without introducing a second horizontal gesture region.
Tests
All code work orders use /tdd. Record the failing behavior before production
changes, then the passing targeted command. Proposed new test names describe
outcomes; adapt names only when the same outcome remains explicitly mapped.
| Test file and named cases | Acceptance coverage |
|---|---|
hooks/use-task-menu-actions.test.ts, use-task-management-flow.test.ts, lib/tasks/task-menu-target.test.ts, components/task/task-management-surface.test.tsx: captured A, unresolved/cross-workspace targets, duplicate submits, removal failures/retry, obsolete link completion, filtered archive anchor |
002.1-002.6 |
components/task/task-management-menu.test.tsx, existing link/confirmation tests and both browser suites: current-step eligibility/priority dispatch, ordered groups, provider choices, archive preference and deletion consent |
001.1-001.6, 002.3, 002.6 |
Existing use-task-removal.test.ts, use-task-actions.test.ts, use-task-workflow-move.test.ts, use-update-task-priority.test.ts, link/confirmation tests |
Existing mutation, cleanup, dirty-worktree, provider, preference, and error behavior under extraction |
lib/threads/thread-selection-fallback.test.ts: seven survivor/successor/predecessor/replacement/empty cases |
003.1-003.3 |
components/threads/thread-task-actions.test.tsx, threads-board.test.tsx, page/activation tests and both browser suites: named opener, removed-column focus, route preservation, native composer context, newer-menu focus, drafts and bounded activation |
002.1, 002.2, 002.5, 003.1-003.6, 004.1, 004.6 |
components/task/task-management-drawer.test.tsx, archive/surface tests and mobile browser suite: one nested surface, Back row focus, confirmation handoff and surviving focus |
001.1-001.6, 004.2-004.7 |
Numeric shorthand in these tables expands to
AC-TASKS-THREADS-ACTIONS-<number>. Work-order frontmatter lists full IDs.
E2E tests
New files are apps/web/e2e/tests/task/threads-task-actions.spec.ts in
chromium and mobile-threads-task-actions.spec.ts in mobile-chrome.
Extract common seed/action helpers to sibling threads-task-actions-helpers.ts.
Follow threads-view.spec.ts: run a real mock-agent turn to establish a primary
session, or use the existing eligible review/clarification fixture. Arbitrary
seeded RUNNING sessions are not primary and cannot prove the feature.
Each action row below is exercised on both projects. The action fixtures use unrelated tasks A and B with real primary sessions. Captured-flow tests and the existing session-switching regressions also protect global and sibling session selection. Check visible results, query persistence, then reload and verify the task metadata remains correct.
| Action / browser test | Required outcome | AC |
|---|---|---|
changes the opened task priority |
Submenu current value changes for A, B stays unchanged; saved-view filtering can remove A | 001.2, 002.2, 002.4, 003.1-003.4 |
moves the opened task to a workflow step |
A reaches the selected step, existing current/auto-start markers match, membership recovery works | 001.3, 002.4, 003.1-003.5 |
sends the opened task to another workflow |
Select workflow then step; A persists there, no-step workflow is disabled, route and B are preserved | 001.3, 002.2, 002.4, 003.1-003.5 |
links the opened task through the existing form |
Supported provider rows use existing availability; submit a mocked GitHub issue/PR link to A, verify association and B unchanged | 001.4, 002.2-002.5, 004.3 |
archives the opened task |
Preference on: cancel causes no request, then confirm succeeds; preference off: direct non-cascade archive; survivor/empty state is correct | 001.5, 002.4, 003.1-003.5 |
deletes only the confirmed task |
Destructive row follows separator; cancel preserves task/sessions; required consent precedes one delete; survivor/empty state is correct | 001.1, 001.6, 002.2, 002.6, 003.1-003.5 |
Cross-action scenarios also run in the owning project:
| Scenario | Evidence | AC |
|---|---|---|
| Desktop context and keyboard overflow equivalence | Same six groups; Enter/Space and keyboard submenu traversal work; chat/editor context stays native | 001.1, 004.1, 004.6 |
| Selection changes while flow is open | A remains target after independent selection/WS changes, B and its chosen session stay unchanged | 002.1-002.3, 002.5 |
| Rejection and retry | Inject a move or archive failure and invalid link, assert error plus unchanged confirmed state; replay a later valid UI action | 002.5, 003.4 |
| Nested dismissal and surface handoff | Back/Escape/outside at root and nested pages; cancelled archive/delete/link; original, replaced, removed, and offscreen trigger focus | 001.5, 001.6, 004.3, 004.6 |
| Narrow phone, long lists and native swipe | Bound every active page/dialog; assert 44px hitboxes, hit testing, one scroller, safe-area clearance, and no document overflow; swipe before and after menu use | 003.6, 004.2-004.7 |
For phone identity testing, use live updates or an independent client while the modal is open; do not force clicks through an inert backdrop. Exercise actual touch swipes with the parent's helper after dismissal. Use mocked providers and isolated E2E storage, not production credentials or a developer instance. Component tests cover all first-party and registered plugin choice dispatch; the browser link outcome uses supported existing integration fixtures.
Managed runs build current production assets and use one worker per shard.
Run desktop and mobile sequentially with one project per command and retries
disabled. Use causal HTTP/WS waits or persisted-state polling, never sleeps.
Restore any modified user settings in afterEach.
Work orders
- Task 01: Share the task action flow
- Task 02: Integrate desktop Threads task actions
- Task 03: Make task choices touch accessible
- Task 04: Document Threads task actions
Execute 01 → 02 → 03 → 04 sequentially after the parent prerequisite. No work order is parallel-safe because menu types, action state, and test helpers overlap. Each code work order owns its RED/GREEN and exact verification commands.
Verification results
- Parent
0b4253fa7merged asfacf9aef7; ancestry verified. Frozen-lockfile install,make -C apps/backend build, andpnpm run build:e2epassed. - Focused unit/component checks: 217 passed in 25 files, two workers.
- Desktop: 6 new tests passed with retries disabled. All 17 existing Threads/workflow regressions passed. A first combined run found a test-driver submenu pointer-grace issue; explicit submenu activation fixed the driver, and the final six-test rerun passed against the same production build.
- Mobile: the 29-test suite passed, including all five new tests and 24 parent/shared-menu cases, with retries disabled. Test discovery confirmed all 29 cases; the final run reported no failed tests.
- Typecheck, affected-file ESLint with zero warnings, formatting,
i18n:checkandi18n:ratchetpassed. All copy reuses existing keys; no locale generation or catalog changes were necessary. Existing orphan-key warnings are unchanged. - New 320px/360px phone header, root/deep drawer and delete-confirmation renders inspected. The menu is inset, long labels remain bounded, the last step is reachable, and the original compact topbar/swiper remain intact. Task 03 records image paths and geometric assertions.
- Public-doc validator tests passed; the live validator passed for 46 pages.
python3 scripts/lint-spec-files.test.py: passed, 30 tests.python3 scripts/lint-spec-files.py --all: passed.git diff --check: passed.- Package link/traceability check: all seven new artifacts resolve their links; all 25 acceptance criteria are assigned to work orders.
The final combined unit command, from apps/web, was:
pnpm exec vitest run --maxWorkers=2 \
hooks/use-task-menu-actions.test.ts hooks/use-task-management-flow.test.ts \
hooks/use-task-removal.test.ts hooks/use-task-removal-session-loading.test.ts \
hooks/use-task-actions.test.ts hooks/use-task-workflow-move.test.ts \
hooks/use-update-task-priority.test.ts lib/tasks/task-menu-target.test.ts \
lib/threads/thread-selection-fallback.test.ts \
components/task/task-management-menu.test.tsx \
components/task/task-management-surface.test.tsx \
components/task/task-management-drawer.test.tsx \
components/task/task-switcher-context-menu.test.tsx \
components/task/task-archive-confirmation.test.tsx \
components/task/task-delete-confirm-dialog.test.tsx \
components/task/task-session-sidebar-link-actions.test.ts \
components/task/task-session-sidebar-move.test.ts \
components/threads/thread-task-actions.test.tsx \
components/threads/threads-board.test.tsx \
components/threads/thread-column-activation.test.tsx \
components/kanban/kanban-header-mobile.test.tsx \
app/threads/threads-page-client.test.tsx lib/threads/stable-order.test.ts \
lib/threads/thread-view-query.test.ts \
components/threads/thread-session-switcher.test.tsx
Managed E2E commands used --host --no-build after explicitly building current
production assets. They ran sequentially with one worker, against isolated
mock-agent/provider fixtures. Task 02 and Task 03 record the exact commands.
Design reference inspection used the parent's existing rendered 360px captures
/tmp/kandev-mobile-threads-PuEDK5/mobile-shared-threads-360.png and
mobile-shared-threads-menu-360.png. They show the compact inline topbar, the
existing task header, and inset menu geometry. They are historical parent
evidence only; they do not verify the proposed task menu.
Header alignment follow-up (2026-09-10)
Completed the user's screenshot-driven styling correction within the existing package. Desktop Open task and overflow now share a vertical center; mobile picker, Open task and overflow have equal 48px center-to-center spacing. Title placement, header height, touch targets and task/swipe behavior are preserved.
Both new bounding-box assertions failed on the previous build (desktop 2px offset; mobile 38px versus 48px gaps) and passed after the fresh E2E build. The focused desktop context/keyboard and mobile long-label/nested/swipe tests each passed with one worker and no retries. Typecheck, affected-file ESLint, formatting, specification lint and whitespace checks passed. Task 02 and Task 03 contain exact commands and evidence.
Fresh dark desktop and 360px touch-phone rendering was inspected in the existing
isolated Tailscale preview. Screenshots are retained under
/tmp/kandev-threads-seed-scLDiX/{desktop,phone}-header-{before,after}.png.
Only its generated static assets/index were refreshed; prior assets/index are
retained, and its processes and user test data were not restarted or changed.
The preview remains on :19468, with the same identity-checked shutdown command.
The main :9998 instance was not queried, modified or stopped.
After approving the visual correction, the user requested shutdown. The identity-checked sandbox wrapper stopped its backend and agent descendants; ports 19468, 59468 and 59568-59667 no longer listen. Disposable data and captures are retained. The main :9998 runtime was not stopped or reconfigured.
Ready PR integration (2026-09-10)
The user requested a concise, template-based ready PR. Feature commit
046832b6d passed the normal commit hooks. Parent PR #3570 remained open;
its reviewed tip 8b508fdb307f4449edc2c2fbe23a5dad4d87a54e was integrated
through merge 4c68ac5c5. The PR targets feature/improve-mobile-threa-f2f
so its diff contains only this follow-up, not the parent's changes.
The combined board exceeded the function-size lint by one line. Extracting its existing picker-focus helper preserved behavior; all 26 board tests passed before and after extraction, followed by successful normal merge hooks. No parent behavior or unrelated main-branch changes were replaced.
Integrated validation passed: 219 focused unit/component tests in 27 files (including extracted listing-removal cases and parent mobile-position coverage), typecheck, i18n checks and ratchet, public-doc validator tests and all 46 published pages, 36 specification-linter tests, full specification lint, and whitespace checks.
A fresh managed backend/web build produced synthetic-data PR screenshots
at 1280x850 desktop and 360x780 touch-phone sizes. The desktop root menu,
phone root drawer and nested workflow-step drawer were inspected and PNG
compressed. The ignored .pr-assets/manifest.json maps all three files;
the disposable capture spec was removed. The manual Tailscale preview
remained stopped throughout.
The first combined build/browser invocation was terminated with SIGTERM (exit 143) after 19 passing tests, including the cross-device capture; it reported no assertion failure. Its processes had exited before the final regression runs reused the same fresh build.
The final desktop run passed all 23 tests with one worker and no retries:
cd apps/web
pnpm e2e:run --host --no-build --project chromium tests/task/threads-task-actions.spec.ts tests/task/threads-view.spec.ts tests/kanban/cross-workflow-task-move.spec.ts -- --retries=0
Both bounded mobile runs also passed, with one worker and no retries: 14 Threads/task-action/swipe tests and 17 shared-sidebar regressions. Together, final browser verification covers 23 desktop and 31 mobile cases.
pnpm e2e:run --host --no-build --project mobile-chrome tests/task/mobile-threads-task-actions.spec.ts tests/task/mobile-threads-view.spec.ts tests/task/mobile-threads-swipe.spec.ts -- --retries=0
pnpm e2e:run --host --no-build --project mobile-chrome tests/task/mobile-sidebar-task-actions.spec.ts -- --retries=0
PR feedback correction (2026-09-10)
The Back and Close drawer controls now use the repository-required pointer
cursor. The existing mobile regression reproduced the prior default cursor
before the two class changes. A fresh managed build passed all five mobile
task-action cases; the focused drawer/surface/header component checks passed
five tests, with ESLint and typecheck also passing. The 360px nested drawer
was inspected. Task 03 records the exact commands and RED/GREEN evidence.
Reviewer follow-up also reproduced and fixed same-workflow moves being rejected when that workflow is hidden, loaded active steps being shadowed by a placeholder snapshot, and archived targets remaining eligible in a stale snapshot. The GitLab link row again retains its pre-existing 48px phone minimum. Regression tests failed for each case before the scoped fixes. The focused suite passed 64 tests in ten files; the fresh mobile build passed all five Threads action tests plus the GitLab linking regression (six tests, one worker, no retries). The six desktop action tests passed after the behavior-preserving cleanup.
Claude's suggestions removed ineffective props memoization and redundant
workflow filtering, named the empty-board dependency, and clarified the existing
error-toast ownership. Cubic's postfix-important warning was not reproducible:
the generated CSS includes important width/height for size-11!, and the phone
regression checks real 44px targets through the 820px coarse-pointer viewport.
CodeRabbit's documentation nit was valid; the how-to now describes the existing
first-new-thread fallback before the genuinely empty state. These corrections
implement the existing requirements and design, without a new contract or copy.
Parent PR #3570 merged while review was in progress, retargeting this PR to
main. Integration with 5ffe8818773bd7c7bda548f3086b305b9b618d55 preserves
the landed control-sizing primitives, shared archive/delete switching helper,
and task-detail dialog focus refs alongside Threads' listing-only removal and
custom focus recovery. Two compatibility tests cover default-ref restoration
and the Threads override. The integrated unit/component suite passed 252 tests
in 29 files, and the fresh managed desktop build passed 27 browser tests with
one worker and no retries, including shared task-detail/preview outcomes.
The integrated phone run passed 15 cases with one worker and no retries:
Threads actions, parent view/picker/swipe behavior, and the shared GitLab link
row. It reused that freshly built backend/web pair.
Typecheck, affected-file ESLint, locale validation, public-doc validation,
specification lint and harness checks passed. Earlier stacked-base results
above remain historical.
Remote exact-head CI/review confirmation remains part of the ongoing fixup,
not a completed claim in this local verification record.
CI archive concurrency correction (2026-09-10)
E2E run 34527249627, shard job 103043769179, reproduced a shared-sidebar
regression: after optimistic navigation from A to B, archiving B while A's
request was pending was silently rejected by the shared global single-flight
guard. The trace contained only A's archive request. The unchanged
archive-task-redirect.spec.ts reproduced the same last-task URL failure
locally with retries disabled. Its dependent report and final gate failed from
that one unexpected test; no additional failed leaf was reported.
Four held-request unit cases failed before the fix for archive and delete, covering concurrent A/B requests, same-task duplicate rejection, out-of-order completion, and A's failure/retry while B remains pending. The shared removal owner now guards pending task IDs independently and retains the first pending ID for existing busy consumers. Navigation, confirmation, error feedback and Threads' listing-only cleanup still belong to their existing owners.
After the fix, the focused unit/component checks passed 141 tests in 17 files,
including those four regressions. Typecheck, zero-warning affected-file ESLint
and locale validation passed. After pnpm run build:e2e, these managed browser
runs passed with one worker and no retries: eight desktop cases and nine phone
cases, including all six actions, cancellation, nested containment and swipe
coexistence.
cd apps/web
pnpm exec vitest run --maxWorkers=2 hooks/use-task-menu-actions.test.ts hooks/use-task-actions.test.ts hooks/use-task-actions-menu-move-targets.test.tsx hooks/use-task-removal.test.ts hooks/use-task-removal-listing.test.ts hooks/use-task-removal-session-loading.test.ts hooks/use-task-workflow-move.test.ts hooks/use-task-management-flow.test.ts components/task/task-management-surface.test.tsx components/task/task-archive-confirmation.test.tsx components/task/task-delete-confirm-dialog.test.tsx components/task/task-session-sidebar-link-actions.test.ts components/task/task-session-sidebar-move.test.ts components/task/task-session-sidebar-selection.test.ts components/threads/thread-task-actions.test.tsx components/threads/threads-board.test.tsx
pnpm exec vitest run --maxWorkers=2 lib/tasks/task-menu-target.test.ts
pnpm e2e:run --host --no-build --project chromium tests/task/archive-task-redirect.spec.ts tests/task/threads-task-actions.spec.ts -- --retries=0
pnpm e2e:run --host --no-build --project mobile-chrome tests/task/mobile-threads-task-actions.spec.ts tests/task/mobile-threads-swipe.spec.ts tests/task/mobile-archive-task-redirect.spec.ts -- --retries=0
CodeRabbit's valid follow-up suggestions also corrected the work-order path,
strengthened inline confirmation containment with an awaited scoped query,
and preserved all six link-handler keys with compile-time checking. The
suggested Threads-agent contract is not a repository requirement: the scoped
guide documents component ownership, not a separate agent. The optional
layout-effect optimization is not applied; its effect reads orderedIds and
refreshes geometry/focus bookkeeping, and no lint suppression is introduced.
These changes preserve the approved contract and rendered layout. Remote CI
and current-head review are rechecked after pushing, not assumed from local
results.
Main integration follow-up (2026-09-11)
Resolved conflicts with the landed task-removal navigation coordinator in the sidebar, action wrappers and removal hook. Both shared menu operations now use that coordinator. Threads records pending targets without a detail departure, so remembered global selection cannot trigger destination loading or failure recovery navigation. Default detail/preview protection, cascade cleanup, per-task duplicate guards and localized success/error feedback remain shared.
Four added integration cases cover archive/delete pending ownership, successful
cleanup and failed removal with a remembered active session. Three failed on
the initial mechanical merge: archive acquired a detail departure, deletion
did not register a coordinated operation, and failed archive redirected to the
overview. The focused checks passed after the compatibility fixes: 201 tests
across 25 files, including the landed coordinator and all existing menu/Threads
regressions. The new cases can be rerun from apps/web with:
pnpm exec vitest run --maxWorkers=2 hooks/use-task-menu-actions.test.ts hooks/use-task-removal-listing.test.ts hooks/use-task-actions.test.ts hooks/use-task-removal-coordinator.test.ts hooks/use-task-removal.test.ts hooks/use-task-removal-session-loading.test.ts hooks/use-task-management-flow.test.ts components/task/task-session-sidebar-selection.test.ts lib/state/task-removal.test.ts
pnpm exec vitest run --maxWorkers=2 hooks/use-task-workflow-move.test.ts hooks/use-update-task-priority.test.ts hooks/use-task-crud.test.ts hooks/use-sidebar-multi-select.test.ts components/task/task-management-menu.test.tsx components/task/task-management-surface.test.tsx components/task/task-management-drawer.test.tsx components/task/task-switcher-context-menu.test.tsx components/task/task-session-sidebar-link-actions.test.ts components/task/task-session-sidebar-move.test.ts components/task/task-archive-confirmation.test.tsx components/task/task-delete-confirm-dialog.test.tsx components/threads/thread-task-actions.test.tsx components/threads/threads-board.test.tsx lib/tasks/task-menu-target.test.ts lib/threads/thread-selection-fallback.test.ts
Typecheck, affected-file ESLint, formatting, locale checks, specification lint,
harness validation and public-doc validation passed. The incoming canvas fixture required only gofmt
normalization; its whitespace-insensitive diff against main is empty.
The system design now names the coordinator. Public documentation and the
existing static menu screenshots still describe the same user workflow and
layout. Managed browser verification passed all 10 desktop and seven phone
cases, with one worker and no retries. The first command rebuilt the backend,
web assets and packaged plugin fixture; the second reused that same build.
Fresh 320px menu and 360px confirmation captures were inspected for containment.
pnpm e2e:run --host --project chromium tests/task/threads-task-actions.spec.ts tests/task/archive-task-redirect.spec.ts tests/task/delete-task-redirect.spec.ts -- --retries=0
pnpm e2e:run --host --no-build --project mobile-chrome tests/task/mobile-threads-task-actions.spec.ts tests/task/mobile-archive-task-redirect.spec.ts tests/task/mobile-delete-task-redirect.spec.ts -- --retries=0
CI follow-up records the launcher fixture race exposed after pushing.
Risks
- Parent files and archive-confirmation work can change before integration; re-read those owners before implementation and preserve their final changes.
ActiveThreadlacks priority, step identity, executor and repository details; a lossy task projection would silently alter eligibility or consent.- Sidebar removal helpers can navigate to
/t/:idor Home using remembered global selection; the shared listing option must suppress that side effect. - Menu unmount, nested overlay handoff, late responses, and filter removal can invalidate trigger refs or retarget callbacks unless identity and focus have explicit lifetimes.
- The below-640px global menu styles do not cover every phone/coarse-pointer case and position nested portals independently; scoped drawer navigation and rendered containment tests are required.