Skip to content

feat(desktop): start a coding agent from New task's prompt-first composer, with Plan mode for a call with Luke - #3717

Merged
luke-agent[bot] merged 20 commits into
mainfrom
luke/feat-new-task-prompt-composer
Oct 18, 2026
Merged

luke-agent[bot] merged 20 commits into
mainfrom
luke/feat-new-task-prompt-composer

Conversation

@dastratakos

@dastratakos dastratakos commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

PR 2 of the "New task, prompt first" redesign, stacked on #3697. New task's name field is now the shared agent composer card. Its words start a coding agent on the new task. A Plan toggle brings back the old flow: plan template plus a call with Luke.

Summary

  • Composer card (tasks/new-task-composer.tsx, mounted by the dialog so PR 8 can put it on Home): this is the agent box itself (AgentComposer), not a fork of it. It has the words field, "+"/paste/drop for files, dictation, the model chip and the round Start button. The repository chip and feat(desktop): choose a New task's Linear issue from its own chip, not the name field #3697's LinearIssueChip now sit in its foot. The workspace chip stays in the title. To make this possible, AgentComposer takes a few optional slots: wording, above, tools, actions, sendable, onKey, onLeave, focusedByOwner. Its servers prop is now optional. The pickers' Escape fallback can belong to the owner.
  • Mode (@luke/panel/tasks/new-task-mode replaces @luke/panel/tasks/new-task-planning): AGENT | PLAN. You switch it with the Plan toggle chip or with Shift+Tab from the field. It is kept under a new key, luke.new-task-mode, and defaults to Agent. The old Plan switch's key is ignored.
  • Agent mode: Start is enabled once there are words, files, or a picked issue, plus a repository. Without a repository, Start is disabled and the card says "An agent needs a repository to work in. Choose one, or turn on Plan." The model chip starts on the account default. A pick applies only to the agent this card starts. Since fix(service,desktop): only Settings changes the coding agents' default model #3718 on main, only Settings writes the default, so this PR follows that rather than the original spec's "a pick becomes the default". Start sends TASKS_START with planning: false, plus the repository, the workspace, linearIssueId, and the issue's title as the name. startTask then gives the new task a draft agent through useCodingAgents.onHandDraft. That draft holds the prompt, the attachments and the chosen model, uses a fresh idempotency key, and is marked sendsOnOpen. The task opens on that draft's tab (mainTabs.onShow). DraftAgentTab sends it once start.available is true. If the agent start is refused, you stay on the draft tab with your words, the reason and Retry, which is the draft tab's existing behaviour.
  • Linear issue: choosing an issue adds a chip above the words (key, title, state, ×) and starts nothing. In Agent mode the agent's prompt is agentPromptOf(issue, words) in @luke/ui/tasks-model: [@KEY Title](url), a blank line, then the words, or the mention alone if there are no words. This comes with a unit test. Switching workspace drops a picked issue.
  • Plan mode: same start as before (planning: true, the call opens), using the issue if one was picked. The model chip is hidden and Start is always enabled. Until PR 5, the words become the task name: first line, trimmed to TASK_BOUNDS.MAX_NAME_CHARS (taskNameOfWords).
  • Keys: Return starts, Shift+Return adds a line. ⌘Return on an Agent-mode box with no words and no files makes a bare task (planning: false, no agent). Escape closes an open menu or dictation first, then the card. ⌘L opens Linear, and is ignored while an input method is composing, as in feat(desktop): choose a New task's Linear issue from its own chip, not the name field #3697.
  • Task name refresh: when an agent of the open task gets its first title (going from no title to a title) and the task is still Untitled, the window sends TASKS_REFRESH once, so the name PR 3 gives it on the service shows up.
  • Works with feat(desktop,service,database): start an agent from an issue, and move its issue into progress as it starts #3693's Start agent… (merged from main through the base): the issue's own preset (agent: true) keeps the card in Agent mode with no Plan toggle and titles it "New agent from …". In Agent mode, a card opened on a workspace issue with nothing written starts the agent on the task's plan through NewTaskStart.agent, as feat(desktop,service,database): start an agent from an issue, and move its issue into progress as it starts #3693 does. Once words or files are written, they go to the agent as NewTaskStart.handed. newTask.start keeps its five parameters.
  • Cancel and Create task are gone. The round Start button and Escape replace them.

Screenshots

These come from the real NewTaskDialog, drawn in Chromium with fake data in the dark theme, not from the packaged app.

Agent mode, words typed:

Agent mode with words typed

A Linear issue attached above the words:

A Linear issue attached

Plan mode (Shift+Tab): the model chip is hidden:

Plan mode

No repository: Start is disabled and the reason shows under the card:

No repository

Evidence

  • pnpm check:affected: it ran out of memory in the sandbox (typecheck, discarded-effect and desktop-shell.test.ts were OOM-killed, and app-menu.test.ts needs an Electron binary the sandbox lacks). I re-ran each of those on its own:

    • tsc --noEmit for @luke/desktop and @luke/ui: pass.
    • pnpm discarded-effect (6 GB heap): "No discarded Effect, Stream, or Layer in 2358 files."
    • pnpm knip, pnpm lint (biome + oxlint), scripts/repository-checks.sh (task-names included): pass.
    • vitest run on new-task-dialog, new-task-workspace, draft-agent-tab, use-tasks-tab, desktop-shell, modals, the agent-composer* tests and packages/ui/src/tasks-model.test.ts: pass.
    • In the full desktop vitest run, the only failure apart from the OOM and the missing Electron binary was modals.test.ts. I fixed it: the card now holds focus until the editor lands.
  • Screenshots: drawn from the real NewTaskDialog in headless Chromium, not the packaged app (evidence.sh only runs on macOS). Drawing it showed two bugs, now fixed: the foot's chips were squeezed to ellipses in the 520px card (fixed with a new 620px DIALOG_SIZE.COMPOSER), and the issue chip's Linear mark was unsized.

  • Bundle budget: the renderer/panel.js baseline moves from 901,571 to 946,875 gzipped bytes (+45,304), so the ceiling moves from 946,649 to 994,218. Measured at this head, panel.js and the chunks it loads come to 946,875 bytes. Main alone measures about 946,165, already about 480 bytes under the old ceiling: most of the gap between the old baseline and today is main's own growth, which used up the 5% slack. This PR adds about 710 bytes, all in panel.js's own chunk (95,596 → 96,306), because New task now draws the agent composer card. That is what pushed it over. Only that one entry was re-recorded, at today's measured size.

Tests (new and rewritten)

  • new-task-dialog.test.ts:
    • Agent mode starts the task with planning off and an agent with the prompt and the chip's model.
    • A model pick applies to this agent only and the default is left alone.
    • Shift+Tab or the toggle switches to Plan mode, which starts the call and is named by the first line.
    • Plan mode starts empty or with no repository.
    • No repository blocks Agent mode and shows why.
    • The mode is remembered, and the old key is ignored.
    • ⌘Return on an empty box makes a bare task.
    • A picked issue becomes a chip and then a mention in the prompt; its × drops it.
    • Linear search, ⌘L and the issue-preset cases, adapted.
  • draft-agent-tab.test.ts: a handed draft sends itself once it can start, and a refusal leaves the words with Retry.
  • use-tasks-tab.test.ts:
    • Agent mode hands the new task a draft that sends itself and opens its tab.
    • An agent's first title on an Untitled task asks TASKS_REFRESH, and a named task asks nothing.
  • tasks-model.test.ts: agentPromptOf and taskNameOfWords.
  • new-task-workspace.test.ts and desktop-shell.test.ts: Create task and Cancel changed to Plan mode's Start and Escape.

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.
  • No Effect.runPromise/runSync/runFork outside the edges.
  • No new raw async primitives.
  • No discarded Effect, Stream, or Layer.
  • Test count: +18 new or rewritten cases across the files above; old Create-task/Cancel/name-field cases removed or rewritten.
  • new-task-planning.ts deleted, replaced by new-task-mode.ts.
  • No CLAUDE.md/AGENTS.md sentence names a changed part.
  • PRIVACY.md unchanged.
  • Package deps unchanged.
  • Barrel/door rule unchanged.

Notes

  • The bare task (⌘Return) still uses a picked issue. If an issue is picked, it names the task and links to it. ⌘Return with words or files in the box acts like Return.
  • A task opened from a workspace issue gets the issue through the task (its link and the plan the agent starts on), not as a mention in the prompt, because the renderer has no URL for workspace issues.
  • The repository and Linear chips keep their bordered field look in the foot. Their menus' placement is unchanged from feat(desktop): choose a New task's Linear issue from its own chip, not the name field #3697.
  • Out of scope: the brief (PR 5), the one-call start (PRs 6/7), Home (PR 8).

Made with Luke


Devin Review

View guided diff Turn on auto-fix

dastratakos and others added 10 commits October 18, 2026 19:57
…t the name field

The name field is a plain name again: typing in it lists no Linear issues
and searches nothing. Where the workspace the task starts in has Linear
connected, a Linear chip stands after the repository chip, and a press on
it, or Command-L from the card, opens the shared searchable menu over the
workspace's issues: those read as the card opened with nothing typed, the
same narrowing, rested Linear search, and key or link lookup as before
(moved unchanged into linear-issue-chip.tsx). Choosing an issue starts its
task at once, as choosing one did; Escape closes the menu and not the card;
a switch of workspace closes it and reads that workspace's issues.

SearchableMenu takes an onSearch for an owner that answers the search
itself, listing its rows unfiltered.

Co-authored-by: luke-agent[bot] <339870089+luke-agent[bot]@users.noreply.github.com>
Resolves the conflicts with main's SearchableMenu move onto SearchField and
ComboboxList: onSearch now rides the SearchField's onChange, and the Linear
chip caps its list with --luke-combobox-list-max as the repository chip does.

Co-authored-by: luke-agent[bot] <339870089+luke-agent[bot]@users.noreply.github.com>
…oser, with Plan mode for a call with Luke

New task's name field becomes the agent composer card: words, files,
dictation, the model chip, and Start, with the repository and Linear chips
and a Plan toggle at its foot. Agent mode starts the task without planning
and opens it on a draft agent tab that sends the words at once, so a refused
agent keeps them with Retry. A Linear issue picked becomes a chip whose
mention leads the agent's prompt. Plan mode starts today's plan and call,
named by the words until the brief lands. An Untitled task's tasks are read
again as its first agent's title lands.

Co-authored-by: luke-agent[bot] <339870089+luke-agent[bot]@users.noreply.github.com>
Resolves the conflict with #3694's move of the renderer runtime into
@luke/panel: the Linear chip's search atom reads it from there.

Co-authored-by: luke-agent[bot] <339870089+luke-agent[bot]@users.noreply.github.com>
…s menu shut across a reconnect or a composing key

- SearchableMenu holds a moved highlight by its row's id as well as its
  place, so an owner's search answering after the arrows moved, with an
  issue sorted ahead, leaves the highlight and Return on the issue chosen.
- The Linear chip closes its menu when Linear is let go, so its coming back
  draws nothing until the chip is pressed.
- Command-L opens nothing while an input method is composing.

Co-authored-by: luke-agent[bot] <339870089+luke-agent[bot]@users.noreply.github.com>
…s ask

Co-authored-by: luke-agent[bot] <339870089+luke-agent[bot]@users.noreply.github.com>
…-prompt-composer

Co-authored-by: luke-agent[bot] <339870089+luke-agent[bot]@users.noreply.github.com>
…field lands

Co-authored-by: luke-agent[bot] <339870089+luke-agent[bot]@users.noreply.github.com>
…ts Plan mode's files in the task-names allowlist

Co-authored-by: luke-agent[bot] <339870089+luke-agent[bot]@users.noreply.github.com>
Resolves the conflict with #3693's Start agent card and #3700's move of the
panel's leaf modules into @luke/panel: the Linear chip stands beside both,
and Create reads Start agent for an agent's card.

Co-authored-by: luke-agent[bot] <339870089+luke-agent[bot]@users.noreply.github.com>
@vercel

vercel Bot commented Oct 18, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
luke-web Ready Ready Preview Oct 18, 2026 11:13pm UTC

Request Review

…-prompt-composer

Takes main's @luke/panel move (New task's mode now lives at
@luke/panel/tasks/new-task-mode) and #3693's Start agent… from an issue: the
composer stands in Agent mode with no Plan toggle for it, and an agent on a
workspace issue with nothing written starts on the task's plan through
NewTaskStart.agent; the composer's words go as NewTaskStart.handed.

Co-authored-by: luke-agent[bot] <339870089+luke-agent[bot]@users.noreply.github.com>
devin-ai-integration[bot]

This comment was marked as resolved.

… model is not kept as default, and offer no server reconnect where no servers are handed

Co-authored-by: luke-agent[bot] <339870089+luke-agent[bot]@users.noreply.github.com>
Base automatically changed from luke/feat-new-task-linear-chip to main October 18, 2026 21:56
Brings #3717 up to date after #3697 was squash-merged into main.

Co-authored-by: luke-agent[bot] <339870089+luke-agent[bot]@users.noreply.github.com>
luke-agent Bot added a commit that referenced this pull request Oct 18, 2026
…-composer

Brings #3729 up to date with #3717, now on main.

Co-authored-by: luke-agent[bot] <339870089+luke-agent[bot]@users.noreply.github.com>
@luke-agent
luke-agent Bot enabled auto-merge October 18, 2026 22:07
@luke-agent
luke-agent Bot added this pull request to the merge queue Oct 18, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Oct 18, 2026
dastratakos and others added 2 commits October 18, 2026 22:31
…tings changes the default (#3718)

Main's #3718 made Settings the one place the coding agents' default model is
written, so the composer's chip no longer writes it: it starts on the default
and a pick runs the agent New task starts.

Co-authored-by: luke-agent[bot] <339870089+luke-agent[bot]@users.noreply.github.com>
…oser

New task now draws the agent composer card, which puts about 0.7 KB gzipped
into panel.js's own chunk (95,596 to 96,306 bytes); main already stood about
480 bytes under the old ceiling, so this crossed it. Baseline 901,571 to
946,875 gzipped bytes, panel.js alone.

Co-authored-by: luke-agent[bot] <339870089+luke-agent[bot]@users.noreply.github.com>
devin-ai-integration[bot]

This comment was marked as resolved.

@luke-agent
luke-agent Bot added this pull request to the merge queue Oct 18, 2026
dastratakos and others added 2 commits October 18, 2026 23:00
… for them, and size its issue chip's Linear mark

Drawn in a browser, the 520px wide card squeezed the foot's chips to
ellipses (acm…, L…, P…, Opus 5…) and the issue chip's Linear mark filled
its slot unsized. @luke/ui's Dialog gains a composer size (620px), the
short chips stand whole while the repository's name gives way, and the
issue chip's mark is drawn at the caption size.

Co-authored-by: luke-agent[bot] <339870089+luke-agent[bot]@users.noreply.github.com>
Co-authored-by: luke-agent[bot] <339870089+luke-agent[bot]@users.noreply.github.com>
@luke-agent
luke-agent Bot removed this pull request from the merge queue due to a manual request Oct 18, 2026
@luke-agent
luke-agent Bot enabled auto-merge October 18, 2026 23:02
Takes #3725's move of the panel's second band: Tooltip now comes from
@luke/panel/tooltip.

Co-authored-by: luke-agent[bot] <339870089+luke-agent[bot]@users.noreply.github.com>
luke-agent Bot added a commit that referenced this pull request Oct 18, 2026
Co-authored-by: luke-agent[bot] <339870089+luke-agent[bot]@users.noreply.github.com>
devin-ai-integration[bot]

This comment was marked as resolved.

…row for one row

A narrow window zoomed in left the foot's whole chips no room, so the
round Start ran past the card; the foot now wraps, its presses kept at the
right, as a 380px-wide render shows.

Co-authored-by: luke-agent[bot] <339870089+luke-agent[bot]@users.noreply.github.com>
@luke-agent
luke-agent Bot added this pull request to the merge queue Oct 18, 2026
Merged via the queue into main with commit 7ee384a Oct 18, 2026
11 checks passed
@luke-agent
luke-agent Bot deleted the luke/feat-new-task-prompt-composer branch October 18, 2026 23:26
luke-agent Bot added a commit that referenced this pull request Oct 18, 2026
Takes main's New task composer, dialog, and tasks tab from #3717 as it
merged, and re-applies Home's composer onto main's DetailPage Home: the
composer at the top of the page's content in place of the New task
action, standing in one place while the list is read and once it lands,
and under Luke's line in a new account's welcome. Keeps the shared mode
store and its test; drops the cross-card default-model sync and its
tests, which #3718's removal of writeDefault left nothing to follow.

Co-authored-by: luke-agent[bot] <339870089+luke-agent[bot]@users.noreply.github.com>

This branch was successfully deployed

1 active deployment
Preview — 45039617 Deployed Oct 18, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant