diff --git a/src/resources/extensions/gsd/auto-loop.ts b/src/resources/extensions/gsd/auto-loop.ts index 74616f3f3..933f1a5b8 100644 --- a/src/resources/extensions/gsd/auto-loop.ts +++ b/src/resources/extensions/gsd/auto-loop.ts @@ -221,6 +221,15 @@ export async function runUnit( s.pendingResolve = resolve; }); + // Ensure cwd matches basePath before dispatch (#1389). + // async_bash and background jobs can drift cwd away from the worktree. + // Realigning here prevents commits from landing on the wrong branch. + try { + if (process.cwd() !== s.basePath) { + process.chdir(s.basePath); + } + } catch { /* non-fatal — chdir may fail if dir was removed */ } + // ── Send the prompt ── debugLog("runUnit", { phase: "send-message", unitType, unitId }); diff --git a/src/resources/extensions/gsd/auto.ts b/src/resources/extensions/gsd/auto.ts index 0d74f8448..2a83ab22a 100644 --- a/src/resources/extensions/gsd/auto.ts +++ b/src/resources/extensions/gsd/auto.ts @@ -1145,6 +1145,9 @@ export async function dispatchHookUnit( ctx.ui.setStatus("gsd-auto", s.stepMode ? "next" : "auto"); ctx.ui.notify(`Running post-unit hook: ${hookName}`, "info"); + // Ensure cwd matches basePath before hook dispatch (#1389) + try { if (process.cwd() !== s.basePath) process.chdir(s.basePath); } catch {} + debugLog("dispatchHookUnit", { phase: "send-message", promptLength: hookPrompt.length, diff --git a/src/resources/extensions/gsd/worktree-resolver.ts b/src/resources/extensions/gsd/worktree-resolver.ts index bdc081d52..b944f3d15 100644 --- a/src/resources/extensions/gsd/worktree-resolver.ts +++ b/src/resources/extensions/gsd/worktree-resolver.ts @@ -13,6 +13,8 @@ * `process.chdir()` internally — this class MUST NOT double-chdir. */ +import { existsSync, unlinkSync } from "node:fs"; +import { join } from "node:path"; import type { AutoSession } from "./auto/session.js"; import { debugLog } from "./debug-logger.js"; @@ -372,6 +374,15 @@ export class WorktreeResolver { }); ctx.notify(`Milestone merge failed: ${msg}`, "warning"); + // Clean up stale merge state left by failed squash-merge (#1389) + try { + const gitDir = join(originalBase || this.s.basePath, ".git"); + for (const f of ["SQUASH_MSG", "MERGE_HEAD", "MERGE_MSG"]) { + const p = join(gitDir, f); + if (existsSync(p)) unlinkSync(p); + } + } catch { /* best-effort */ } + // Error recovery: always restore to project root if (originalBase) { try {