Repository navigation
feat(server): resolve GitHub issues and prepare an issue worktree thread - #4
Conversation
Adds the helpers the start-from-issue flow shares between server and web: one normalizes an issue number or GitHub issue URL, the other names the worktree branch issue/<number>-<slug>. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Adds git.resolveIssue and git.prepareIssueThread with their schemas so clients can read a GitHub issue and start a worktree thread from it. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Adds an optional getIssue capability to source control providers, implemented for GitHub with gh issue view, and a GitManager.resolveIssue service method behind the git.resolveIssue RPC. Pull request numbers and hosts without the capability fail with a clear message. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
GitManager.prepareIssueThread resolves the issue, then creates a worktree on issue/<number>-<slug> from the default branch and runs the project setup script. Starting the same issue again reuses its worktree, and an existing issue branch without a worktree is checked out instead of recreated. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
gh issue view reports a pull request's state as MERGED, which the issue decoder rejected, so pasting a merged PR number showed a generic read error instead of the pull request message. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Review follow-ups for the issue thread flow: - A missing issue number now says the issue was not found instead of a generic CLI failure. - An issue branch checked out in the main repo is refused rather than handing the main checkout back as a worktree. - Stale worktree registrations are pruned first, so a worktree folder deleted by hand no longer blocks starting the issue again. - Reuse matches the issue number prefix, so a renamed issue finds its existing branch and worktree. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Hey - I've found 1 issue
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="apps/server/src/git/GitManager.ts" line_range="2405-2414" />
<code_context>
+ const existing =
+ localRefs.find((ref) => ref.name === branch) ??
+ localRefs.find((ref) => ref.name.startsWith(issueBranchPrefix));
+ if (existing?.worktreePath) {
+ const rootWorktreePath = yield* canonicalizeExistingPath(input.cwd);
+ if ((yield* canonicalizeExistingPath(existing.worktreePath)) === rootWorktreePath) {
+ return yield* new GitManagerError({
+ operation: "prepareIssueThread",
+ cwd: input.cwd,
+ detail: `${existing.name} is already checked out in the main repo. Switch the main repo off that branch to start a worktree thread.`,
+ });
+ }
+ return { issue, branch: existing.name, worktreePath: existing.worktreePath };
+ }
+
</code_context>
<issue_to_address>
**issue (bug_risk):** The main-checkout comparison canonicalizes `input.cwd` rather than the repository root, so a request whose `cwd` is a subdirectory of the main repository is treated as a different worktree and returns the main checkout as the issue worktree even though that branch is checked out in the main repo.
**Triggers:** When `cwd` points to a subdirectory inside the repository and the matching issue branch is checked out in the main checkout.
**Suggested fix:** Resolve `input.cwd` to the Git worktree root before comparing it with `existing.worktreePath`, or obtain the root from Git directly.
</issue_to_address>Adds the Start work from issue dialog. It resolves the issue, prepares its worktree, opens the project draft there, and prefills the composer with the issue without discarding text already typed in the draft. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Adds a Start work from issue command palette action and a branch picker item for issue 123 or a GitHub issue URL. Bare numbers stay pull request checkout. Documents the flow in the source control guide. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Review follow-ups: - The palette action now works from any thread. It opens the project's draft first, because the dialog only mounts on a draft. - Matching an issue URL in the draft uses whole tokens, so issue 3 is no longer skipped when the draft mentions issue 31. - Starting a second issue replaces the first issue's untouched prompt instead of appending to it. Edited text is still kept. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6dec9d3137
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
The provider registry rebuilds each provider with its remote context and dropped the optional getIssue capability, so every real project reported that only GitHub issues are supported. Found in a manual run against a GitHub clone; the earlier tests injected the provider directly and bypassed the registry. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
Pushed 64abefd: fix(server): keep the issue capability when routing to a provider. The manual pass for #5 found that SourceControlProviderRegistry.bindProviderContext rebuilt each provider without the optional getIssue capability, so every real project reported "Only GitHub issues are supported". The earlier GitManager tests injected the provider directly and bypassed the registry. New test: 'keeps the issue capability on a resolved GitHub provider' (failed first, passes now; registry suite 13/13). |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 64abefd646
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
- Look up issue branches with a prefix query, so repositories with more than one page of refs still find an existing issue worktree. - Detect the main checkout when the project folder is a subdirectory of the repository. - Fail when the default branch is unknown instead of branching from the current checkout, which could carry unrelated commits. - Serialize issue starts so two clients starting the same issue get the same worktree instead of a git conflict. - Continue an issue branch that exists only on the remote instead of recreating it from the default branch. - Raise the gh output cap so the largest issue bodies decode. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- An issue URL followed by punctuation in the draft is recognized, so starting the same issue again does not add it twice. - If opening the draft fails after the worktree is created, the dialog shows the error instead of failing silently. Starting again reuses the worktree. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Clients use it to hide Start from issue on servers that do not serve git.resolveIssue and git.prepareIssueThread. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Codex review follow-ups: - A prompt that mixes user text with an issue is never marked as replaceable, so a later issue start appends instead of deleting the user's text. - Start from issue appears only when the server advertises issueThreads and the project is not the scratch project. - The dialog request carries its project; a chat view for another project drops it instead of starting work in the wrong repository. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5f2507ab99
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
gh issue view bypassed the shared GraphQL budget guard, so repeated issue lookups neither checked nor recorded rate limits. Also pins that an issue worktree starts when the default branch exists only on the remote. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a22af357cf
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
- Lock issue starts per project instead of server-wide, and run the setup script after releasing it, so a slow setup cannot block other projects or other issues. - Strip the exact remote name when continuing a remote issue branch, so remotes with a slash in their name are found. - Charge bare issue numbers to the repository's own GitHub host quota, matching the other GitHub reads. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ting - A start that finishes after navigation closed the dialog no longer opens or prefills the originating draft. - The issue field is disabled while the worktree is prepared, so the shown issue always matches the one being started. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- The dialog request carries the draft it was opened on. Leaving that draft (Back, sidebar, another thread) drops it, while automatic environment selection keeps the same draft and the dialog. - Start from issue is offered only for GitHub repositories. - A failed start no longer lingers after the issue changes or when the dialog is opened again. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
prepareIssueThread creates or checks out an issue branch, but unlike the VCS worktree and ref commands it left the cached ref list alone, so an open branch picker could miss the new branch. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…hub-issues # Conflicts: # apps/server/src/git/GitManager.ts
…pgrade Upstream moved reactivity out of effect/unstable when it upgraded to Effect 4.0.1, which broke the issue dialog's import after merging main. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5ac1b23d22
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Git cannot create issue/<n>-… refs while a branch named exactly issue exists, and its cannot-lock-ref error does not say why. Starting work from an issue now names the blocking branch and how to rename it. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: be11707ae4
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
With only origin/<base> present, git worktree add -b issue/... <path> <base> checked out a new local <base> tracking branch instead of the issue branch, so issue work could be committed to the default branch. The start point is now the local branch, else origin/<base>, else a clear error. The test now asserts the checked-out branch, not only the commit. Also drop --path-format from the issue lock key, which Git 2.30 and older reject, and resolve the relative --git-common-dir output instead. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9a225d8b0c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…-found - A default branch that exists only on a remote not named origin (for example upstream in a fork) is now used as the start point; origin wins when several remotes have it. - The issue not-found message uses the transport-safe reference, so a pasted URL's query string or fragment is never echoed to clients. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 446c1e6470
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
The suffix test on remote refs also accepted nested branches such as aaa/releases/main, so an issue worktree could start from an unrelated branch. Each configured remote is now checked for exactly <remote>/<default>, origin first. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The dialog used the VCS action's pending flag, which follows the action's scope; automatic environment selection could change that scope mid-start and re-enable Cancel and Start work. The dialog now owns its starting state. Also scope the user guide to web and desktop; mobile has no issue start yet. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Automatic environment selection could move the draft while an issue start was running. The dialog then unmounted (dropping the result) or read its error from the new environment's action state (hiding a failure). The dialog now keeps its lookup and start on the environment it opened on and stays mounted. If the draft has moved, it says so instead of attaching a worktree from another environment. Also hide a previous lookup error while a new reference is still being typed, and show the lookup spinner again. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
t3code/apps/server/src/git/GitManager.ts
Lines 2570 to 2572 in eb9b318
When the default exists only as origin/main and the repository also has a valid local branch named origin/main, this verifies the unambiguous refs/remotes/origin/main but then returns the short name. GitVcsDriver.createWorktree passes that short name as the start commit; on Git 2.43 this produces warning: refname 'origin/main' is ambiguous followed by fatal: ambiguous object name: 'origin/main', so the issue worktree cannot be created. Return the same fully qualified remote ref that was verified.
t3code/apps/server/src/git/GitManager.ts
Lines 2461 to 2465 in eb9b318
When the registered project is itself a linked Git worktree already checked out on this issue branch, cwdPath equals or falls under existingPath, so this reports that the branch is in the main checkout and refuses the request. Git projects rooted at linked worktrees— including registered monorepo subdirectories inside one—therefore cannot use the advertised same-issue reuse behavior even though existing.worktreePath is exactly the worktree that should be returned; distinguish the primary checkout from a linked worktree before rejecting it.
t3code/apps/web/src/components/ChatView.tsx
Lines 2866 to 2868 in eb9b318
When automatic environment selection moves the draft while prepareIssueThread is pending, the in-flight handleConfirm invocation still holds the onPrepared callback from the render where the request began, and that callback captured the old activeProject. This comparison therefore sees the old environment on both sides and passes, after which the stale openOrReuseProjectDraftThread closure can attach the old environment's worktree path to the draft that has moved; read the draft's current project/environment from a ref or store when preparation completes instead of validating captured render state.
AGENTS.md reference: AGENTS.md:L75-L75
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Problem
There is no way to start agent work from a GitHub issue.
The user has to read the issue on GitHub, create a branch and worktree by hand, and paste the issue into the composer.
This PR is the server half of the fork experiment tracked in #1.
Change
git.resolveIssuereads one issue throughgh issue view, behind a new optionalgetIssuecapability on source control providers. Only GitHub implements it; other hosts get "Only GitHub issues are supported."git.prepareIssueThreadresolves the issue, then creates a worktree onissue/<number>-<slug>from the default branch and runs the project setup script.The web dialog that calls these RPCs follows in a stacked PR for #3.
Scope and approval
Fork-only experiment, tracked in #1 and #2.
Upstream context: pingdotgg#11067 suggests "creating a thread from an issue can follow" the first Issues slice. This change deliberately has no issue browsing UI.
Verification
GitManager,GitWorkflowService,GitHubSourceControlProvider,GitHubCli,VcsProcess,GitHubPullRequestCli, sharedgit, contractsgitandrpc).main, reuse on second start, reuse after a title change, existing branch without a worktree, deleted worktree folder, branch checked out in the main repo.apps/serverandpackages/contractstypecheck clean.ghagainst this fork: a fork issue URL resolves; a bare1resolves againstorigin(upstream) and hits upstream PR feat: start agent work from a GitHub issue #1, which is how the merged-PR bug was found and fixed.Release note: Agents can start work from a GitHub issue in its own worktree (server support).
Fixes #2
Implemented by Claude Opus 5.5 (1M context) in Claude Code, running inside T3 Code.
🤖 Generated with Claude Code