feat(desktop): hand Plan mode's words to Luke as the task's brief

Merged
DA
13d ago
+91-50

Summary

PR 5 of the New task redesign. In New task's Plan mode, the composer's words now go to Luke as the task's brief (tasks.start's field from #3699). Until now they were used as the task's name.

  • Plan mode (new-task-composer.tsx): the words are sent as brief through TasksControl.newTask.start / startTask (use-tasks-tab.ts, whose NewTaskStart gains brief). No name is derived from them any more. The task takes the picked Linear issue's title (or the workspace issue it was opened on). Otherwise it stays Untitled until Luke names it. The issue's linearIssueId is still sent next to the brief. startTask doesn't send an empty or whitespace-only brief.
  • Bound: the words box is capped at TASK_BOUNDS.MAX_BRIEF_CHARS in Plan mode. In Agent mode it keeps the cap it had before, CODING_AGENT_BOUNDS.MAX_MESSAGE_CHARS. AgentComposer takes this as a new optional maxLength prop, defaulting to the message bound. Both limits are 16,000 today.
  • Agent mode is unchanged and never sends a brief.
  • taskNameOfWords (@luke/ui/tasks-model) and its test are removed; nothing else used it.
  • Updated the doc comments: the composer's header, NewTaskStart, newTask.start and startTask.

Out of scope: Agent mode's one-call start (PR 7), Home (PR 8), and any service change.

Evidence

  • pnpm check:affected: typecheck, lint, repository checks and migrations passed. discarded-effect ran out of memory inside the parallel run (sandbox limit), so I reran it alone with a bigger heap and it passed (No discarded Effect, Stream, or Layer in 2397 files.). knip passed on its own. The affected tests passed: ui 82 files, panel 25, web 67, desktop 197 files / 2124 tests. app-menu.test.ts first failed only because the Electron binary was missing in the sandbox; it passed after fetching it. The affected build passed.
  • New and updated tests:
    • new-task-dialog.test.ts:
      • Plan mode with words sends a brief and no name.
      • Plan mode with an issue and words sends the issue's name, linearIssueId and brief.
      • An empty Plan start sends neither.
      • Agent mode sends no brief.
      • The repository tests no longer expect a name taken from the words.
    • use-tasks-tab.test.ts: startTask puts brief in the TASKS_START payload next to linearIssueId, and leaves out a blank one.

Invariants

  • ./scripts/check.sh green. (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 as type assertion outside the allowlisted files.
  • No Effect.runPromise/runSync/runFork outside the runtime edges.
  • No new setTimeout/setInterval/new Promise/AbortController/fs.watch.
  • No Effect, Stream, or Layer written as a statement and dropped.
  • Test count: one test removed with taskNameOfWords, two added (Plan mode with issue and words; startTask's brief payload). Net +1.
  • No hand-rolled file replaced.
  • No CLAUDE.md/AGENTS.md sentence names a changed part.
  • PRIVACY.md unchanged. The words already reached the service as the task's name.
  • Package deps match imports.
  • Barrel/door rule: the renderer imports @luke/features/task-wire, a vocabulary door it already opens elsewhere.

Notes

  • Blockers or follow-up verification: None. PR 7 and #3729 touch new-task-composer.tsx / use-tasks-tab.ts too; whichever PR merges later merges origin/main forward.

Made with Luke


Devin Review