Overview
Codaph captures activity from multiple coding agents:- Codex (OpenAI): SDK and exec adapters
- Claude Code (Anthropic): History importer
- Gemini CLI (Google): History importer
src/lib/agent-providers.ts:4-112:
Provider Detection
Codaph auto-detects providers by checking for marker directories:- Codex:
.codex/directory - Claude Code:
.claude/directory ORCLAUDE.mdORCLAUDE.local.md - Gemini CLI:
.gemini/directory
Provider Configuration
During Init
Explicit Selection
Check Current Providers
Codex Integration
Fromsrc/lib/adapter-codex-sdk.ts and src/lib/adapter-codex-exec.ts:
Live Capture (SDK)
prompt.submittedtool_call(withname,arguments)tool_result(withoutput)- Session metadata
Exec Wrapper
History Import
Fromsrc/codex-history-sync.ts:
~/.codex/db.sqlite3(Codex SDK database).codex/directories in project worktrees
- Session metadata
- Prompt/response pairs
- Tool calls and results
- File changes
Claude Code Integration
Fromsrc/claude-history-sync.ts:
History Import
~/.claude/history/(Claude Code session history).claude/directories in project worktrees
- Prompts and responses
- Thinking/reasoning steps
- File edits and tool calls
Agent Complete Hook
.claude/hooks/agent-complete
Hook behavior:
- Triggers after Claude Code agent run completes
- Runs
codaph hooks run agent-complete --provider claude-code - Syncs latest session to local mirror + Mubit
- Respects sync lock and cooldown
Gemini CLI Integration
Fromsrc/gemini-history-sync.ts:
History Import
~/.gemini/history/(Gemini CLI session history).gemini/directories in project worktrees
- Prompts and responses
- Code generation steps
- File modifications
Agent Complete Hook
.gemini/hooks/agent-complete
Multi-Provider Workflows
codaph push
# Scans Codex, Claude Code, and Gemini CLI history
# Imports all sessions to local mirror + Mubit
Selective Import
Provider-Specific Automation
History Sync Architecture
Fromsrc/index.ts:1376-1495 (runSyncPushPhase):
-
For each selected provider:
- Scan local history files
- Match to current project
- Parse events
- Import via
IngestPipeline - Deduplicate by
eventId - Write to local mirror + Mubit
- Aggregate results:
- Persist state:
Provider-Specific Event Sources
Fromsrc/lib/core-types.ts:
src/index.ts:4492-4506):
Best Practices
Auto-Detect Providers
Auto-Detect Providers
Recommended: Let Codaph auto-detect providers during init.Why?
- Ensures you don’t miss providers in use
- Detects new providers added later
- Works with worktrees and monorepos
Selective Agent Hooks
Selective Agent Hooks
Install hooks only for active agents:Why?
- Reduces unnecessary hook overhead
- Avoids errors from missing agent binaries
- Keeps automation focused
One-Time Backfill
One-Time Backfill
After init, backfill history once:Then rely on automation:Why?
codaph pushscans full history (slow)- Daily
codaph syncuses fast Mubit-first pull - Hooks capture new sessions immediately
Monitor Per-Provider Stats
Monitor Per-Provider Stats
Check provider-specific sync status:Investigate errors:
Troubleshooting
Provider Not Detected
Provider Not Detected
Issue:
codaph init doesn’t find your agent.Fix: Ensure marker directory exists:No History Found
No History Found
Issue:
codaph push reports 0 matched files.Causes:- History location not scanned
- No sessions for current project
- Project path mismatch
Agent Hook Not Triggering
Agent Hook Not Triggering
Issue: Hook installed but sync doesn’t run after agent completes.Fix:
- Check hook is executable:
- Test hook manually:
- Check hook manager:
- Reinstall hooks:
Mixed Provider Sessions
Mixed Provider Sessions
Issue: Sessions show wrong provider or “unknown”.Cause: Event source mismatch or missing provider info.Fix: Provider is inferred from event If source is generic, provider detection falls back to session metadata.
source field:Extending Provider Support
To add a new agent provider:export type AgentProviderId = "codex" | "claude-code" | "gemini-cli" | "cursor";
const PROVIDER_MARKERS: Record<AgentProviderId, string> = {
// ...
cursor: ".cursor",
};
export async function syncCursorHistory(options: {
projectPath: string;
pipeline: IngestPipeline;
repoId: string;
onProgress?: (progress: CursorHistorySyncProgress) => void;
}): Promise<CursorHistorySyncSummary> {
// Scan ~/.cursor/history/ or similar
// Parse session files
// Call pipeline.ingest() for each event
// Return summary
}
if (provider === "cursor") {
providerSummary = await syncCursorHistory({
projectPath: cwd,
pipeline,
repoId,
actorId,
onProgress: relayProgress,
});
}