Skip to content

Let me name a workspace and its branch when I create it #6398

Open

Description

@de1mat

What problem are you trying to solve?

My normal workflow is: make a worktree, give it the name I want, open it, then start an agent from a terminal preset. The agent comes second. Naming the thing up front is the whole interaction for me, and it used to be the fastest path in the app.

Right now it is the slowest. I am on the new-workspace-screen test arm, and that screen has no way to type a name at all. Submit stays disabled while the prompt box is empty, and what I type there is a hint for the AI namer rather than the name itself. Picking "No agent" does not change that, the text still goes through as namingPrompt and comes back as something an LLM chose.

What makes me think this is drift rather than a decision is that the naming path has narrowed a bit at a time:

Underneath, a typed name is still first class, and it is the cheaper path: passing name to workspaces.create sets wantAi = false, which skips the LLM call, the deferred rename and the placeholder branch, and the workspace name falls back to the branch verbatim (input.name ?? resolvedBranch). The CLI goes further and requires --name whenever --project is set. It is only the desktop UI that has moved away from it.

Remote hosts make this harder

I use remote hosts constantly, and that is where it stops being a small annoyance. Creating a remote workspace itself is fine - the host picker works, the branch list queries the right host, the create dispatches correctly. The only missing piece is saying what it is called, and both workarounds get worse across the network:

  • Picking an existing branch needs that branch to already exist on the remote host's repo. To put it there I either need a terminal in a workspace on that host (which I do not have yet, that is what I am creating) or I push a throwaway branch from my laptop purely so the remote picker can see it.
  • The CLI works, but it is four commands and two id lookups: hosts list, projects list --host, ws create --host --project --name --branch, ws open.

Proposed solution

A name field on the new-workspace screen, with the branch defaulting to a slug of it and submit enabled on a name alone. The control modal already does exactly this, so it might be as small as bringing those two inputs across.

If the new screen's design does not want two more fields on it, an alternative that would suit me just as well: when no agent is selected, treat the prompt box text as the literal name rather than as a naming hint. One field, two meanings depending on the mode.

I am not asking to remove the AI namer. It is clearly doing real work for people who start from a prompt. I would just like a way past it that does not involve a terminal.

Keen to hear whether the screen is heading somewhere that already covers this.

Workarounds you've tried

  1. Branch picker, "Open workspace" on a row. Exact name, no LLM call, no prefix applied. Needs the branch to exist first, which is the problem on a remote host.
  2. CLI ws create --name --branch. Exact, and works remotely, but four commands and two id lookups for what used to be one text field.
  3. Create it and fix the names after. Two renames in two different places: the workspace title inline, and the branch separately from the Changes tab, since workspace.update --name does not touch git. All after waiting on an LLM call I did not want.

5939 looks like the same theme from a different angle - the prompt-less path quietly not being exercised.

Activity

  1. github-actions commented on Aug 12, 2026

    @github-actions
    Contributor

    This is a feature request rather than a bug report, so I traced the claims through the code to confirm which are accurate and where the gap actually sits.


    The request is that the new-workspace-screen test arm has no way to type a workspace name or branch name at creation time: submit is gated on a non-empty prompt, and whatever you type goes to the server as an AI-naming hint rather than as the name, even when the agent is set to "No agent". The control modal still has both inputs, and the whole create pipeline underneath — draft store, resolveNames, workspaces.create — still treats a typed name as first class and cheaper (it skips the LLM entirely). I confirmed all of the load-bearing technical claims in the report; the gap is purely that the test arm never renders the two inputs, not that the plumbing was removed.

    Affected code

    The two arms diverge only in rendering. The control modal renders both fields:

    • PromptGroup.tsx:400-441 — the workspace-name Input (placeholder "Workspace name (optional)") and the right-aligned half-width mono branch Input, exactly as described.
    • PromptGroup.tsx:646 — submit is disabled={needsSetup} only, so a typed name with an empty prompt submits.

    The test arm renders neither:

    • NewWorkspaceScreen.tsx:593-772 — the composer has the markdown editor, agent/model/effort pills, link buttons, device/project/base-branch pills, and no name or branch input.
    • NewWorkspaceScreen.tsx:762 — disabled={needsSetup || isPromptEmpty}, with a matching early return at NewWorkspaceScreen.tsx:480. This is the "submit stays disabled while the prompt box is empty" behaviour.

    Everything below the UI is shared and already supports a typed name. Both arms use the same draft store and the same submit hook:

    • new-workspace-draft.ts:40-49 — workspaceName, workspaceNameEdited, branchName, branchNameEdited, branchNameFromProvider all still exist on the draft.
    • resolveNames.ts:16-28 — returns the typed name/branch or null.
    • useSubmitWorkspace.ts:128-141 — sends name/branch when typed, otherwise sends namingPrompt.
    • workspaces.ts:77-92 (host-service createInputSchema) — the doc comment states the contract directly: "A typed name also seeds the branch when branch is omitted."

    Root cause / what I confirmed

    The behaviour is not drift in the submit path — it is a rendering gap in one arm, and the report's reading of the server side is correct:

    • "No agent" does not bypass the LLM. useSubmitWorkspace.ts:83 sets wantAgent = false when the agent is none, and useSubmitWorkspace.ts:138-141 then sends the typed text as namingPrompt. On the host, workspaces.ts:527-533 folds namingPrompt into composerPrompt and computes wantAi = pr === undefined && worktreePath === undefined && name === undefined && !!composerPrompt. With no name and a non-empty prompt, wantAi is true regardless of the agent choice. Selecting "No agent" cannot reach the non-AI path from this screen.
    • A typed name is the cheaper path, as claimed. name set ⇒ wantAi false ⇒ no generateWorkspaceNamesFromPrompt call (workspaces.ts:535-542), no deferred rename. workspaces.ts:894-899 slugs the typed name into the branch candidate (sanitizeBranchCandidate(input.name), else generateFriendlyBranchName()), and the workspace name falls back to the branch verbatim at workspaces.ts:1048 (name: input.name ?? resolvedBranch).
    • The branch-picker workaround does require a pre-existing branch. CompareBaseBranchPicker only offers onOpenWorkspace on rows returned by useBranchContext (CompareBaseBranchPicker.tsx:230-243, useBranchPickerController.ts:75-98); there is no "create branch from the search text" row. The "no prefix applied" observation also checks out: an existing ref sets plan.usedExistingBranch, which skips the prefix block at workspaces.ts:860-874.

    One additional finding the report doesn't mention, which I think strengthens it. The test arm does already have a working non-AI naming path — it is just invisible. useLinkedContext.ts:41-50 seeds patch.workspaceName = title and patch.branchName = deriveBranchName(...) into the draft when you link a Linear issue, and NewWorkspaceScreen.tsx:704-714 renders that IssueLinkCommand. So on this screen, linking an issue silently sets name (suppressing AI naming) with no field anywhere to show or override it. Related: NewWorkspaceScreen.tsx:388 passes typedWorkspaceName: draft.workspaceName into the branch-picker controller, which on this arm is always "" unless an issue happens to be linked. Both are symptoms of state that the arm writes and reads but never renders.

    One correction to the report, which doesn't affect the argument. The CLI does not require --name when --project is set — --name is optional (packages/cli/src/commands/workspaces/create/command.ts:14). What it requires is one of --branch, --pr, or --task (command.ts:74-79). The four-command, two-lookup remote flow is still accurate.

    Reproduction

    Manual, on the test arm (force it with the NEW_WORKSPACE_SCREEN_OVERRIDE flag — useNewWorkspaceScreenVariant.ts:30-38 short-circuits to "test" without emitting experiment exposure):

    1. Open the new-workspace screen, pick a project, set the agent pill to "No agent".
    2. Observe there is no name or branch input, and the submit arrow is disabled while the composer is empty.
    3. Type a name-shaped string, submit, and observe the created workspace gets an LLM-chosen name and branch. Server-side, wantAi is true at workspaces.ts:529.
    4. Repeat on control (flag off): type into "Workspace name (optional)" with an empty prompt, Cmd+Enter, and the workspace is created with that exact name and a slug branch, no LLM call.

    For a regression test, the cheapest assertions are at the two ends rather than through the full component:

    • A bun:test unit test that a none-agent submit with a typed workspaceName produces a snapshot with name set and namingPrompt undefined — resolveNames (resolveNames.ts) and the snapshot construction at useSubmitWorkspace.ts:117-142 are the units worth pinning.
    • A host-service test asserting create({ name }) skips naming: the existing packages/host-service/src/trpc/router/workspaces/worktree-add-tolerance.test.ts is the nearest harness for the create procedure.

    Suggested fix direction

    The proposal to port the two inputs looks correct and small, because nothing below the UI needs to change: the test arm already consumes the same useDashboardNewWorkspaceDraft and the same useSubmitWorkspace, so writing workspaceName/workspaceNameEdited and branchName/branchNameEdited from new inputs makes resolveNames and the wantAi suppression work with no server change. Two edits beyond the markup:

    1. Relax NewWorkspaceScreen.tsx:762 and :480 from isPromptEmpty to something like isPromptEmpty && !draft.workspaceName.trim() && !draft.branchName.trim(), mirroring control's disabled={needsSetup}.
    2. Note that NewWorkspaceScreen.tsx:388 already wires typedWorkspaceName into the branch picker, so the picker's "Open workspace" action starts honouring the typed name for free once a field writes it.

    The single-field alternative ("no agent ⇒ prompt text is the literal name") is also reachable — it is a condition change at useSubmitWorkspace.ts:138-141, sending name: trimmedPrompt instead of namingPrompt when selectedAgent === "none". Two caveats if you go that way: draft.prompt is markdown from MarkdownEditor and can be multi-line, so it would need length/newline clamping before it becomes a branch slug via sanitizeBranchCandidate; and the mode switch is invisible, so the same keystrokes produce a name or a hint depending on a pill the user may not be looking at. The two-field version has the advantage that it also surfaces the currently-hidden issue-link seeding described above.

  2. Kitenite commented on Aug 12, 2026

    @Kitenite
    Member

    Hey @de1mat yes point taken, will adjust

  3. Kitenite commented on Aug 12, 2026

    @Kitenite
    Member

    tagging @saddlepaddle as well as we're iterating on this flow

  4. saddlepaddle commented on Aug 12, 2026

    @saddlepaddle
    Collaborator

    Hi there @de1mat it's been a bit, thanks for adding such detailed guidance!

    So one of the reasons we pushed for a redesign of the new workspace modal is to boost activation, and the experiment has done really well so far (~28% lift). A lot of that I attribute to reducing clutter on the create surface, which is why I'm hesitant to immediately add the fields back.

    I did note the two bugs you mentioned and fixed those in #6401, apologies but I'd like to let this one bake a bit more before we add back in the naming / branch renaming, and I'll try to reincorporate it if possible in the future!

  5. de1mat commented on Aug 13, 2026

    @de1mat
    ContributorAuthor

    Thanks for #6401. And fair enough on holding off, a 28% activation lift isn't a number to argue with.

    One clarification, because my wording caused it: I only ever wanted one string, not two fields. The ask was a single name with the branch following from it, but I wrote "bringing those two inputs across", and that's the version that got discussed and declined. That's on me.

    So here is a smaller version that adds nothing to the screen. When the agent pill is on "No agent", check whether what I typed is already a legal git branch name. If it is, use it for the workspace name and the branch and move on. If it isn't, do exactly what you do today.

    The test does the work. serverless-cache-fix is a legal branch name, so it's plainly a name. fix the serverless cache invalidation has spaces in it, so it isn't, and falls through to the namer as now. Anyone typing a sentence, which is everyone the new screen is built for, sees no change at all, so I don't think this can move your numbers in either direction.

    The check already exists in sanitizeUserBranchName (branch.ts:166): trimmed, non-empty, no whitespace, and unchanged by it. One thing worth getting right, pass the string as both name and branch on the create rather than just name, since a lone name gets slugged through sanitizeBranchCandidate (workspaces.ts:895) and loses slashes and anything past 25 characters. With both set the server needs no change at all.

    On timing, I should be straight that this is blocking rather than a nice-to-have. I create several worktrees a day and name them deliberately, and right now there's no way to do that from the UI, so each one is a CLI invocation or two renames after the fact. I tried to put myself back on control locally and couldn't get it to hold. So in the meantime, could you take me off the test arm? The experiment targets new accounts on created_at and mine isn't one, and if I'm on new-workspace-screen-override then flipping it off costs you nothing, since overridden users don't count toward the results anyway. Otherwise I think I'm down to pinning at 1.17.1, the last release before the screen landed, which I'd rather not do.

  6. edoecohen commented on Aug 31, 2026

    @edoecohen

    With the updated flow for creating a new workspace, is there any manual way at all to name the workspace? Couldn't find any mention in the docs.

  7. l16i commented on Sep 3, 2026

    @l16i

    Just hit this too. My account is from March and I still got put on the test arm, so it's not only new accounts, the screen just changed under me one morning with no update.

    I'd just like to be able to type a name once and have the workspace and the branch take it, the way it worked before.

  8. de1mat commented on Oct 2, 2026

    @de1mat
    ContributorAuthor

    Quick update so this isn't waiting on me: I've moved my daily work to another tool for now, so no need to take me off the test arm. I'll leave the issue open, since others are clearly hitting the same thing (see #7168). Thanks again for the quick fix in #6401, and for all the PRs you've taken from me over the year.

  9. Kitenite commented on Oct 4, 2026

    @Kitenite
    Member

    Thanks for the update, de1mat. Sad to see you go. Curious what you ended up using and what you like from there?

  10. MattStannettOperandio commented on Oct 21, 2026

    @MattStannettOperandio

    Also running into this issue, would be nice to have a fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions