Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/mubit-ai/codaph/llms.txt

Use this file to discover all available pages before exploring further.

Overview

Codaph automatically detects and supports git worktrees, allowing you to capture agent sessions across multiple branches simultaneously.
When you run codaph push from a worktree, Codaph scans all worktrees in the repository and imports agent history from each.

What are Git Worktrees?

Git worktrees let you check out multiple branches of the same repository simultaneously:
# Main repository
cd ~/projects/myapp

# Create worktree for feature branch
git worktree add ../myapp-feature feature/new-ui

# Create worktree for hotfix
git worktree add ../myapp-hotfix hotfix/critical-bug
Now you can work on three branches at once without switching:
  • ~/projects/myapp (main)
  • ~/projects/myapp-feature (feature/new-ui)
  • ~/projects/myapp-hotfix (hotfix/critical-bug)

How Codaph Handles Worktrees

Automatic Detection

When you initialize Codaph or run codaph push, it:
  1. Detects the git repository root via git rev-parse --show-toplevel
  2. Lists all worktrees using git worktree list --porcelain
  3. Scopes the project path across all worktrees
  4. Imports agent history from each worktree’s agent directories
Source: src/lib/git-worktrees.ts:72

Scoped Project Paths

The resolveScopedProjectPathsForWorktrees() function resolves your project path to all matching worktrees:
// Example: if you run from ~/myapp/.codex/
const paths = resolveScopedProjectPathsForWorktrees("~/myapp");
// Returns:
[
  "/Users/you/myapp",
  "/Users/you/myapp-feature",
  "/Users/you/myapp-hotfix"
]
Source: src/lib/git-worktrees.ts:72

Parsing Worktree List

Codaph parses git worktree list --porcelain output:
export function parseGitWorktreeListPorcelain(raw: string): string[] {
  const out: string[] = [];
  const lines = raw.split("\n");
  for (const line of lines) {
    if (!line.startsWith("worktree ")) {
      continue;
    }
    const pathValue = line.slice("worktree ".length).trim();
    if (pathValue.length === 0) {
      continue;
    }
    out.push(resolve(pathValue));
  }
  return dedupePreserveOrder(out);
}
Source: src/lib/git-worktrees.ts:34 This extracts absolute paths to all worktrees and deduplicates them.

Relative Suffix Projection

Codaph projects the relative path from repo root to your current location across all worktrees:
export function scopeProjectPathAcrossWorktrees(
  worktreeRoots: string[],
  repoRoot: string,
  projectPath: string,
): string[] {
  const normalizedRepoRoot = resolve(repoRoot);
  const normalizedProjectPath = resolve(projectPath);
  const relativeSuffix = relative(normalizedRepoRoot, normalizedProjectPath);
  
  // If outside repo, return original path only
  if (relativeSuffix.startsWith("..") || isAbsolute(relativeSuffix)) {
    return [normalizedProjectPath];
  }

  // Map relative suffix to each worktree
  const scoped = worktreeRoots.map((worktreeRoot) =>
    relativeSuffix.length === 0 ? resolve(worktreeRoot) : resolve(worktreeRoot, relativeSuffix)
  );
  
  const normalizedScoped = dedupePreserveOrder(scoped);
  if (!normalizedScoped.includes(normalizedProjectPath)) {
    normalizedScoped.unshift(normalizedProjectPath);
  }
  return normalizedScoped;
}
Source: src/lib/git-worktrees.ts:50

Usage Examples

Enable Worktree Scanning (Default)

codaph push
Worktree scanning is enabled by default. Codaph imports agent history from:
  • Current worktree
  • All other worktrees in the same repository

Disable Worktree Scanning

codaph push --no-worktrees
Only the current directory is scanned (no worktree detection).

Example Workflow

# Setup repository with worktrees
cd ~/myapp
git worktree add ../myapp-feat1 feature/auth
git worktree add ../myapp-feat2 feature/payments

# Work in first worktree
cd ~/myapp-feat1
codex exec "add OAuth2 login"

# Work in second worktree
cd ~/myapp-feat2
codex exec "integrate Stripe payments"

# Push from main worktree imports BOTH sessions
cd ~/myapp
codaph push
Output:
Codex: scan 2/2 | match 2 | events 48 | sessions 2
Both Codex sessions (from myapp-feat1 and myapp-feat2) are imported.

How Import Works

When you run codaph push, Codaph:
  1. Resolves worktree paths
  2. Scans each worktree for agent marker directories:
    • .codex/ (Codex)
    • .claude/ (Claude Code)
    • ~/.config/gemini/ (Gemini CLI, not worktree-specific)
  3. Imports agent history from each location
  4. Deduplicates events by eventId in the local mirror
Source: src/index.ts:1376 (runSyncPushPhase)

Agent History Paths

For each worktree, Codaph checks:
~/myapp/.codex/history/
~/myapp-feat1/.codex/history/
~/myapp-feat2/.codex/history/

Deduplication

Codaph automatically deduplicates events across worktrees using eventId hashing:
export function createEventId(input: {
  source: AgentSource;
  threadId: string | null;
  sequence: number;
  eventType: string;
  ts: string;
}): string {
  const raw = [
    input.source,
    input.threadId ?? "no-thread",
    String(input.sequence),
    input.eventType,
    input.ts,
  ].join("|");
  return createHash("sha256").update(raw).digest("hex").slice(0, 24);
}
Source: src/lib/core-types.ts:113 If the same event appears in multiple worktrees (e.g., shared .codex/ directory), it’s imported only once.

Configuration

Disable Worktrees Globally

Add to your project settings:
.codaph/project.json
{
  "schema": "codaph.project.v2",
  "useWorktrees": false
}
Or via CLI:
codaph push --no-worktrees

Per-Command Override

# Enable for single command
codaph push --worktrees

# Disable for single command  
codaph push --no-worktrees

Limitations

Gemini CLI history is global (stored in ~/.config/gemini/), not per-worktree. All worktrees share the same Gemini history.
  • Codex and Claude Code are worktree-aware (history stored in .codex/ and .claude/ respectively)
  • Gemini CLI is not worktree-aware (global history)

Troubleshooting

”No worktrees detected”

Run git worktree list to verify worktrees exist:
git worktree list
If empty, you’re not using worktrees (this is fine — Codaph works normally).

Events imported multiple times

If worktrees share the same .codaph/ directory (symlink or bind mount), disable worktrees:
codaph push --no-worktrees

Missing sessions from other worktrees

Verify agent marker directories exist in each worktree:
ls -la ~/myapp-feat1/.codex/
ls -la ~/myapp-feat2/.codex/
If missing, the agent hasn’t run in that worktree yet.

Testing

Tests: test/lib-git-worktrees.test.ts Codaph includes unit tests for worktree parsing and scoping:
  • parseGitWorktreeListPorcelain — parsing git worktree list output
  • scopeProjectPathAcrossWorktrees — relative path projection
  • resolveScopedProjectPathsForWorktrees — end-to-end resolution