Cmd.WorktreeLifecycle (fnord v0.9.34)

View Source

Shared worktree lifecycle helpers used by Cmd.Worktrees, Cmd.Conversations, and Cmd.Ask for managing worktree cleanup, deletion prompts, and conversation metadata updates.

Summary

Functions

Checks whether a conversation has an associated worktree on disk and offers to delete it. Used during conversation deletion to avoid orphaned worktrees. When the user confirms cleanup, the local branch is only deleted after the worktree itself is removed successfully.

Removes worktree metadata from a conversation. On the next session, AI.Agent.Coordinator.worktree_context_msg/1 inspects live metadata during bootstrap and injects a fresh "no worktree, create one" system message, so no trailing message needs to be appended here. Mutating data.messages also breaks fnord replay, which assumes the last message is the assistant's final reply.

Attempts a clean worktree removal. If the worktree has uncommitted changes, warns the user and asks for confirmation before force-deleting. This helper only removes the worktree itself; callers should only clean up the branch after worktree removal succeeds.

Warns the user if the worktree branch has unmerged commits relative to its base branch. Returns :ok to continue or {:error, :cancelled} if the user declines to proceed.

Functions

cleanup_worktree_for_conversation(conversation)

@spec cleanup_worktree_for_conversation(Store.Project.Conversation.t()) :: :ok

Checks whether a conversation has an associated worktree on disk and offers to delete it. Used during conversation deletion to avoid orphaned worktrees. When the user confirms cleanup, the local branch is only deleted after the worktree itself is removed successfully.

clear_worktree_from_conversation(conv_id)

@spec clear_worktree_from_conversation(String.t()) :: :ok

Removes worktree metadata from a conversation. On the next session, AI.Agent.Coordinator.worktree_context_msg/1 inspects live metadata during bootstrap and injects a fresh "no worktree, create one" system message, so no trailing message needs to be appended here. Mutating data.messages also breaks fnord replay, which assumes the last message is the assistant's final reply.

delete_worktree(root, path)

@spec delete_worktree(String.t(), String.t()) :: {:ok, :ok} | {:error, atom()}

Attempts a clean worktree removal. If the worktree has uncommitted changes, warns the user and asks for confirmation before force-deleting. This helper only removes the worktree itself; callers should only clean up the branch after worktree removal succeeds.

warn_if_unmerged(root, arg2)

@spec warn_if_unmerged(String.t(), map()) :: :ok | {:error, :cancelled}

Warns the user if the worktree branch has unmerged commits relative to its base branch. Returns :ok to continue or {:error, :cancelled} if the user declines to proceed.