fix: worktree threads clean up on Windows, show their state, and start from current main - #229
Merged
Conversation
…atest base Deleting a worktree after dependencies were installed failed on Windows with "Filename too long" because git only handles such paths with core.longpaths. The removal command now sets that flag, so the folder goes with the thread. Cutting a worktree "from main" used the local branch even when its upstream had moved on. The bootstrap now fetches the base branch's upstream (bounded, best effort) and starts from it when the local branch is strictly behind; a local branch with its own commits still wins. New thread branches are created with --no-track so a remote start point never becomes their upstream.
…cess A restart while a turn was starting or running left the session row saying so with nothing behind it. The thread then sat on "Preparing turn" forever and deleting it was the only way out. On startup the provider command reactor now marks those sessions interrupted and records why in the thread.
…ncies Agents assume a checkout is ready to build. A fresh worktree has no node_modules, build output, or ignored local files, and Threadlines does not install anything for them. The managed-worktree instruction now says so and leaves the decision to install with the agent.
…rom the default branch After Send, the server records the thread a moment before the worktree exists, and the draft view merged that record in. For about three seconds the composer flipped to "Current checkout / main" and the "Preparing worktree..." label never showed because the flag was cleared right before the request. The requested mode now holds, and the label stays, until the thread reports its worktree. Switching a draft from an existing worktree to "New worktree" kept the previous thread's branch as the base, usually a throwaway threadlines/... name. The base now resets and the branch selector fills it from the repository's default branch instead of whatever the project checkout has out. The browser test from the server-side bootstrap move asserted "Sending" during that window; it now asserts "Preparing worktree", which is the point of the fix.
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
badcuban
enabled auto-merge (squash)
September 5, 2026 07:57
…indows Deleting a thread that owned a terminal took the whole server down under the dev runner. node-pty's Windows kill path forks a helper to list the shell's console processes and treats the first IPC message back as the answer. Under `node --watch` the server carries WATCH_REPORT_DEPENDENCIES, the helper inherits it, its module loader reports its own requires over that channel, and node-pty reads `consoleProcessList` off the wrong message. The unhandled rejection exited the process. The pty adapter now unsets that variable on Windows when it loads node-pty. The fork is deferred until the pty reports ready, so hiding it around the kill call was not enough. The server loads its module graph eagerly, so watch mode still sees every file it needs to.
…older Thread deletion kills the worktree's terminals and removes the worktree at the same time. On Windows the shell's working directory pins the folder for the moment it takes to exit, so git unregistered the worktree, failed with "Permission denied" on the final delete, and the app reported the removal as failed with an empty folder left behind. When git reports a failed delete and the worktree is already unregistered, the driver now retries deleting the folder for up to five seconds before giving up.
…fix/worktree-flow-windows
The worktree bootstrap now asks the git driver where to start the new branch before creating it. The four router tests that mock createWorktree left that method on the harness's unimplemented stub, so CI failed before reaching the worktree step.
…fix/worktree-flow-windows
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.
Starting a thread in a new worktree had several rough edges, found by timing and screenshotting the real flow on Windows. This PR fixes them together, one commit per concern.
Worktrees could not be removed on Windows once dependencies were installed.
git worktree removefailed with "Filename too long" and the folder stayed behind after "Delete the worktree too?". The removal now runs withcore.longpathson. Reproduced by hand and in the app before the fix; the driver test now nests a path past the Windows limit before removing.Worktree removal also failed while the thread's terminal shell was still exiting. Thread deletion kills terminals and removes the worktree at the same time; on Windows the shell's working directory pins the folder for a moment, so git unregistered the worktree, hit "Permission denied" on the final delete, and left an empty folder with a failure toast. The driver now retries the delete for up to five seconds once git has unregistered the worktree. A live-clock test holds the folder from a child process and checks removal still completes.
Deleting a thread that owned a terminal took the dev server down. node-pty's Windows kill path forks a helper to list the shell's console processes and treats the first IPC message back as the answer. Under
node --watchthe server carriesWATCH_REPORT_DEPENDENCIES, the helper inherits it, its module loader reports its own requires over that channel, and node-pty readsconsoleProcessListoff the wrong message. The unhandled rejection exited the process. The pty adapter now unsets that variable on Windows when it loads node-pty; the fork is deferred until the pty is ready, so hiding it only around the kill call was not enough. Reproduced before and after undernode --watch: the server now survives. Production runs without the watcher and was never affected by this one.The composer flashed "Current checkout / main" for about three seconds after Send, and "Preparing worktree..." never showed. The server records the thread a beat before the worktree exists, and the draft view merged that record in; the label's flag was also cleared right before the request that does the work. The requested mode and the label now hold until the thread reports its worktree path. The browser test from the server-side bootstrap move asserted the old "Sending" label in that window and now asserts "Preparing worktree".
"From main" started from a stale local main, and a second worktree draft inherited the previous thread's throwaway branch as its base. The bootstrap now fetches the base branch's upstream (bounded, best effort) and starts from it when the local branch is strictly behind; a local branch with its own commits still wins, and new thread branches are created with
--no-track. Switching a draft to "New worktree" resets the base, and the selector fills it from the repository's default branch.A restart mid-turn left threads on "Preparing turn" forever. On startup the provider command reactor now marks sessions still recorded as starting or running as interrupted and notes why in the thread.
Also: agents in a managed worktree are now told the checkout has no installed dependencies or build output, so they decide whether to install. No auto-install was added.
Other platforms: node-pty's unix kill path never forks a helper and swallows errors, and a process's working directory does not pin a folder on macOS or Linux, so the two terminal-related fixes are Windows-only by construction and no-ops elsewhere.
core.longpathsand--no-trackare likewise no-ops off Windows.Verification: fmt, lint, typecheck,
@threadlines/server#testfor the touched files,@threadlines/web#testfor the toolbar logic, and the full web browser suite. Two pre-existing Windows-only failures remain in the server suites (backslash path comparison in the worktree listing test, and the provider path-alias test); both fail onmainwithout this change.