feat(desktop): choose a New task's Linear issue from its own chip, not the name field
Merged
DA
11d ago+641+641+012345678901234567890123456789-349-349-012345678901234567890123456789
Summary
PR 1 of the New task redesign ("New task, prompt first"). Linear moves out of the name field and into a Linear chip of its own.
- The name field is plain again. It is a
TextField, its placeholder is always "Task name (optional)", and typing in it lists no issues and searches nothing. Return creates the task under the name as typed, with any modifier held. - Linear chip (
tasks/linear-issue-chip.tsx, new). It stands after the repository chip in the card's foot, but only where the workspace the task starts in has Linear connected (linearIssuesIn(startsIn) !== undefined). Pressing it opens the sharedSearchableMenuwith its own search field:- With nothing typed it lists the issues read as the card opened, in the order they were read. Nothing in the issue summary says which issues are the developer's own, so it can't put them first.
- Typing narrows the list at once (
offeredIssues). Once typing rests, Linear itself is searched (the debounced search atom). A pasted key or link asks for that one issue (linearIssuesAskOf).useLinearIssues,useLinearSearchand the atom moved out of the dialog unchanged. - ↑/↓ move, Return chooses, and Escape closes the menu but not the card. Focus goes back to whatever opened the menu.
- ⌘L opens it from the card. No app command holds ⌘L, so this PR adds
LtoSHORTCUT_KEYand exportsshortcutMatchesto read the chord. - Switching workspace closes the menu and reads that workspace's issues.
- Choosing an issue works as it does today. The task starts at once, named by the issue's title, with
linearIssueId, the repository, the workspace and the planning the card shows. (PR 2 changes this to attaching the issue above the prompt.) SearchableMenutakes an optionalonSearch. It lets the owner answer the search itself: the owner hears each query, and the menu shows the rows it hands back without filtering them. This is needed so issues that Linear's search finds outside the title still show. It also remembers a highlighted row by its id as well as its position, so rows that arrive late don't move the highlight onto another issue.- A card opened from one of the workspace's own issues offers no Linear chip, as its name searched no Linear before.
new-task-dialog.tsx's header comment now describes the new behavior.
Evidence
pnpm check:affectedran out of memory in this sandbox (8 GB) when its typechecks ran in parallel, so I ran each of its steps on its own. All passed:scripts/repository-checks.sh: passedpnpm lint(biome + oxlint): 0 errorspnpm knip: cleanpnpm discarded-effect: cleantscfor@luke/desktopand@luke/settings: cleanvitest run --project desktop --project settings --project ui: 302 files, 2643 tests passed
- Not inspected visually: there is no Mac or packaged app in this sandbox, and
scripts/evidence.shruns only on macOS.
Invariants
-
./scripts/check.shgreen. (CI) - JSON Schema goldens unchanged.
- Every behavior change has, in this PR, the test that fails without it; no change-detector test added.
- Gateway envelope goldens unchanged.
- No new
astype assertion outside the allowlisted files. - No
Effect.runPromise/runSync/runForkoutside the runtime edges. - No new raw async primitives.
- No Effect, Stream, or Layer dropped.
- Test count:
new-task-dialog.test.tsgoes from 24 to 26. Its Linear cases are rewritten: typing never lists or searches issues; the chip stands only with Linear connected; the chip lists, the arrows move, and Return starts; search narrows, then Linear is searched; a pasted link looks up one issue; Escape closes the menu and not the card; ⌘L opens it, but not while an input method is composing; a Linear result that sorts ahead of the highlighted issue leaves the highlight on the chosen issue; opening from a workspace issue shows no chip.new-task-workspace.test.tsgoes from 6 to 7 tests: its Linear case now checks that a workspace switch closes the search and the chip lists the chosen workspace's issues, and a new case checks that Linear disconnecting and reconnecting doesn't reopen the search. - No hand-rolled file replaced.
- No
CLAUDE.md/AGENTS.mdsentence names a changed part. -
PRIVACY.mdunchanged. - Package deps unchanged.
- Barrel/door rule unaffected.
Notes
-
This branch merges
origin/maintwice to resolve conflicts with #3674 (SearchableMenu moved onto SearchField and ComboboxList) and #3694 (renderer runtime moved into@luke/panel). -
Out of scope here: the prompt composer, Agent/Plan modes, and starting a coding agent (PR 2 stacks on this branch).
Made with Luke