feat(workspace): a session in its own worktree, Claude's way
Desktop-parity phase 6, following Claude Desktop: - the workspace home's Worktree checkbox starts the pane with `claude --worktree=<name>`, so Claude Code makes, populates (.worktreeinclude, WorktreeCreate hook) and cleans up <repo>/.claude/worktrees/<name>; AgentHub only excludes /.claude/worktrees/ at the repo root (Claude does not) - server/lib/session-worktree.js resolves a session's worktree from the session row only (owned by the workspace, registered by git worktree list); every lane git route takes ?session= and answers ENOWORKTREE instead of falling back to the main folder - the session view's Changes panel works in the opened run's worktree (dashboard_runs.worktree, GitTarget in the client api) - Resume/Fork start in the session's worktree; a gone one is ENOWORKTREE - Archive of a worktree session removes the worktree after asking: git worktree remove without --force, git branch -d (unmerged work keeps its branch), a lock held by a live pid refused, a stale one cleared - listWorktrees reads `locked <reason>` locks - tests scrub GIT_* env so the pre-commit suite cannot act on this repo
This commit is contained in:
@@ -192,7 +192,7 @@ function slugify(text) {
|
||||
* Records are separated by blank lines, with keys like:
|
||||
* - worktree <path>
|
||||
* - branch refs/heads/<name>
|
||||
* - locked (optional, bare line)
|
||||
* - locked [<reason>] (optional)
|
||||
*/
|
||||
async function listWorktrees(sourceRepo) {
|
||||
const result = await git(sourceRepo, ["worktree", "list", "--porcelain"]);
|
||||
@@ -215,8 +215,11 @@ async function listWorktrees(sourceRepo) {
|
||||
const branchPath = line.slice("branch ".length);
|
||||
// Strip refs/heads/ prefix
|
||||
current.branch = branchPath.replace(/^refs\/heads\//, "");
|
||||
} else if (line === "locked") {
|
||||
} else if (line === "locked" || line.startsWith("locked ")) {
|
||||
// `locked <reason>` when one was given (Claude Code locks its session
|
||||
// worktrees with `claude session <name> (pid …)`).
|
||||
current.locked = true;
|
||||
if (line.length > "locked".length) current.lockReason = line.slice("locked ".length);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user