diff --git a/src/session.ts b/src/session.ts index a8beeb7..45f8aa9 100644 --- a/src/session.ts +++ b/src/session.ts @@ -314,7 +314,7 @@ export function finalizeSession(repoRoot: string, claudeSessionId?: string): { p // Git Notes Checkpoint // ============================================================================= -/** Attach the most recent completed session as a git note to HEAD */ +/** Attach the most recent completed session as a git note to the relevant commit */ export async function checkpoint(repoRoot: string): Promise { const idPath = currentIdPath(repoRoot); let sessionId: string | null = null; @@ -332,12 +332,21 @@ export async function checkpoint(repoRoot: string): Promise { if (!sessionId) return; - const compPath = completedSessionPath(repoRoot, sessionId); - if (!existsSync(compPath)) return; + // Prefer completed session, fall back to active + let sessionPath = completedSessionPath(repoRoot, sessionId); + if (!existsSync(sessionPath)) { + sessionPath = sessionFilePath(repoRoot, sessionId); + } + if (!existsSync(sessionPath)) return; try { - const sha = await headSha(); - await addNoteFromFile(compPath, sha); + // Use base_commit from frontmatter so the note lands on the commit + // where the session started, not just whatever HEAD is now + const content = readFileSync(sessionPath, "utf8"); + const { frontmatter } = parseFrontmatter(content); + const baseCommit = frontmatter.base_commit as string | undefined; + const sha = baseCommit && baseCommit !== "none" ? baseCommit : await headSha(); + await addNoteFromFile(sessionPath, sha); } catch { // Silently fail — non-blocking } diff --git a/src/setup.ts b/src/setup.ts index 2c88706..e6a8648 100644 --- a/src/setup.ts +++ b/src/setup.ts @@ -156,11 +156,11 @@ export async function enable(root: string, opts?: { install?: boolean; genesis?: const hooksDir = join(root, ".git", "hooks"); mkdirSync(hooksDir, { recursive: true }); const postCommitPath = join(hooksDir, "post-commit"); - const hookContent = "#!/bin/sh\nghost checkpoint &\n"; + const hookContent = '#!/bin/sh\nexport PATH="$HOME/.bun/bin:$PATH"\nghost checkpoint &\n'; if (existsSync(postCommitPath)) { const existing = readFileSync(postCommitPath, "utf8"); if (!existing.includes("ghost checkpoint")) { - writeFileSync(postCommitPath, `${existing.trimEnd()}\nghost checkpoint &\n`); + writeFileSync(postCommitPath, `${existing.trimEnd()}\nexport PATH="$HOME/.bun/bin:$PATH"\nghost checkpoint &\n`); } } else { writeFileSync(postCommitPath, hookContent);