Repository navigation
feat: name a worktree by the GitHub issue it is for - #459
Merged
Merged
Conversation
The New worktree dialog's name field took a branch name or the task in plain words. It takes an issue too now — "#128", or the URL copied out of the browser — looked up through gh on the project's own account. What that buys is the other half: the session opened on that worktree finds the issue at its prompt. Number, title, link and body, as one bracketed paste so the body's newlines are text rather than a run of Enters, and unsent — the Enter stays the user's, as with the pull request handoff. Typing the context in by hand was the only way an agent learned what its worktree was for. Everything the flow needs already existed: toBranchName slugs the title and prints the exact branch under the field before anything is created (#413), CreateWorktree makes an ordinary branch off the chosen base, writeAtPrompt waits out the setup script and the provider's boot (#447), and bracketedPaste is why the paste is one block. What is new is one gh call, one pure module, and a row in the gh message table. Two refusals, both because the field is a branch name first: - A bare number stays a branch name. "#" is the marker, so there is one field with one meaning rather than a mode to be in. - A pull request's number is refused, naming the screen that does open pull requests. GitHub counts issues and pull requests in one sequence and `gh issue view` answers for either; taking it would branch off the base under its title instead of checking its head out. The URL is the only field in the answer that tells the two apart. And the reference itself never names the branch, resolved or not: git accepts "#381" as a branch name, and most shells read the "#" as the start of a comment, so `git checkout #381` is `git checkout`. Claude-Session: https://claude.ai/code/session_01GSu6sRs6pBuZHmWaJmuZ3o
Both sides changed the body of createWorktree: main's session fork queues the parent's conversation before the setup script, this branch writes the issue at the new session's prompt after it. Neither replaces the other — a forked worktree named by an issue does both — so the resolution keeps main's fork block and the prompt write beside it. Claude-Session: https://claude.ai/code/session_01GSu6sRs6pBuZHmWaJmuZ3o
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
lich lists a repository's pull requests, shows Files changed, comments, resolves conflicts and merges — the right-hand side of the flow. The left-hand side did not exist: an issue was not work. You opened a worktree, named it by hand, and typed the context in at the agent's prompt.
The New worktree dialog's name field now takes an issue beside the branch names and plain words it already took.
What it does
Type
#128, or paste the URL copied out of the browser. lich looks the issue up throughghon the project's own account (vcs.account), prints its title and the exact branch it will create under the field before anything exists, and hands the issue to the session that opens on it — number, title, link and body, waiting unsent at the agent's prompt.Measured against this repository, every state of that one field:
#381#381 Sandbox backend for Windows (unelevated write protection)/Branch: 381-sandbox-backend-for-windows#453(a pull request)#453 is a pull request, not an issue — open it from the Pulls screen./Branch: 453#999999GitHub has no issue with that number./Branch: 999999fix the auth redirectBranch: fix-the-auth-redirect381Branch: 381Branch: <auto-generated>Two refusals, both because the field is a branch name first
#is the marker, so there is one field with one meaning rather than a mode to be in.gh issue viewanswers for either — taking it would branch off the base under its title instead of checking its head out (CreateWorktreeFromPR). The URL is the only field in the answer that tells the two apart.And the reference itself never names the branch, resolved or not: git accepts
#381as a branch name, and most shells read the#as the start of a comment —git checkout #381isgit checkout. Caught in the headless smoke, not in review.Almost all of it already existed
toBranchName()CreateWorktree()writeAtPrompt()Terminal.Ready, so the paste outlives the setup script (#447)bracketedPaste()project.Issuegh issue view <n> --json number,title,body,url, ~60 lineslib/issue.tsghFailuresNo new screen, no route, no topbar entry, no dependency. The body is cut at 4 000 runes with the cut marked; the URL above it is the rest.
Testing
internal/project/issue_test.go— the gh call's shape, the pull request refusal, the body cut (boundary pinned as a literal and crossed by one), and the not-found wording pinned onto its message.frontend/src/lib/issue.test.ts— 10 cases:#N, issue URLs with tails, enterprise hosts, and every shape that is not a reference; the brief's bracketing and its empty-body branch. One assertstoBranchName(issueName(issue))end to end, so the branch this prints is the branch it makes.#-in-a-branch-name bug surfaced.gofmt,go vet,go test ./...,biome check,tsc,vitest(1383),vite build, and the three-OS build/vet loop.Provider symmetry
The handoff is
writeAtPrompt+ bracketed paste — the same mechanism the pull request handoff already ships on, provider-agnostic. No per-provider gap, so no newdocs/ceilings.mdbullet; the paste bullet there now names both callers.https://claude.ai/code/session_01GSu6sRs6pBuZHmWaJmuZ3o