Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 14 additions & 5 deletions src/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<void> {
const idPath = currentIdPath(repoRoot);
let sessionId: string | null = null;
Expand All @@ -332,12 +332,21 @@ export async function checkpoint(repoRoot: string): Promise<void> {

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
}
Expand Down
4 changes: 2 additions & 2 deletions src/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down