ADR-134: Unified Multi-LLM Watcher Architecture
Status
Accepted (2026-01-28)
Related ADRs
- ADR-135 - Cross-LLM Bridge Architecture (complementary runtime layer)
- ADR-122 - Unified LLM Component Architecture (foundation)
Related Commands
/session-log- Logs multi-LLM session activity/sx- Cross-LLM session export
Relationship to Cross-LLM Bridge
This ADR focuses on session watching and export across LLMs, while ADR-135 focuses on runtime orchestration and routing. Together they provide:
- ADR-134: Proactive session preservation (prevents data loss)
- ADR-135: Intelligent request routing (optimizes cost/quality)
Both support the 5 LLMs: Claude, Codex, Gemini, Kimi, and future providers.
Context
CODITECT supports multiple LLM CLI tools (Claude, Codex, Gemini, KIMI), each with different session formats, compaction thresholds, and export mechanisms. The current approach creates separate watcher implementations for each LLM:
| LLM | Current Implementation | Status | Duplication |
|---|---|---|---|
| Claude | codi-watcher (Rust) | Production v0.4.0 | Baseline |
| Codex | codi-codex-watcher (Rust) | Proposed (40%) | ~80% duplicate |
| Gemini | codi-gemini-watcher (Rust) | Accepted (25%) | ~80% duplicate |
| KIMI | KASE (Python) | Accepted (15%) | Different stack |
Problems
- Code Duplication: Each watcher reimplements monitoring, cooldowns, notifications, state persistence
- Maintenance Burden: Bug fixes must be applied to 4+ separate codebases
- Inconsistent Behavior: Different implementations may have subtle behavioral differences
- Scaling Issue: Adding new LLMs (Qwen, DeepSeek, etc.) requires new watcher projects
- Service Sprawl: Multiple launchd/systemd services to manage
- Configuration Fragmentation: Each watcher has its own config format
LLM Compaction Thresholds (Known)
| LLM | Compaction Starts | Safe Export Threshold |
|---|---|---|
| Claude | 80% | 75% |
| Codex | ~90% | 85% |
| Gemini | ~90% | 85% |
| KIMI | 80% | 79% |
Decision
Consolidate all LLM watchers into a single unified codi-watcher v2.0 Rust binary with configuration-driven multi-LLM support.
Architecture
High-Level Design
┌─────────────────────────────────────────────────────────────────┐
│ codi-watcher v2.0 │
│ (Unified Multi-LLM Watcher) │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ llm-watchers.json (Configuration) │ │
│ │ - LLM definitions with paths, thresholds, extractors │ │
│ │ - Global settings (poll interval, cooldown, dirs) │ │
│ │ - Per-LLM enable/disable │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ LLM Detection Engine │ │
│ │ - Auto-detect installed LLMs (which/where) │ │
│ │ - Discover active sessions via process detection │ │
│ │ - File system watching for unbounded logs (KIMI) │ │
│ │ - Dynamic enable/disable based on availability │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │ │
│ ┌─────────────────┼─────────────────┐ │
│ ▼ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Claude │ │ Codex │ │ Gemini │ ... │
│ │ Monitor │ │ Monitor │ │ Monitor │ │
│ │ Thread/Task│ │ Thread/Task│ │ Thread/Task│ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │ │
│ └────────────────┴────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ Trigger Evaluator │ │
│ │ - Context % threshold (per-LLM configurable) │ │
│ │ - File size threshold (for unbounded logs) │ │
│ │ - Time-based triggers (periodic backup) │ │
│ │ - Turn-based triggers (after N interactions) │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ Unified Export Pipeline │ │
│ │ - Invoke per-LLM extractor (script or builtin) │ │
│ │ - CUSF format normalization │ │
│ │ - Route to per-LLM pending directory │ │
│ │ - Session log integration │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ State & Cooldown Manager │ │
│ │ - Per-session cooldown tracking │ │
│ │ - Unified state file (all LLMs) │ │
│ │ - Export history and statistics │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
Configuration Schema
File: ~/.coditect/config/llm-watchers.json
{
"$schema": "https://coditect.ai/schemas/llm-watchers-v1.0.0.json",
"version": "1.0.0",
"global": {
"poll_interval_seconds": 30,
"cooldown_minutes": 10,
"pending_base_dir": "~/.coditect-data",
"session_log_dir": "~/PROJECTS/coditect-rollout-master/docs/session-logs",
"notifications": {
"enabled": true,
"on_warn": true,
"on_export": true
}
},
"llms": {
"claude": {
"enabled": true,
"binary": "claude",
"session_paths": [
"~/.claude/projects/**/*.jsonl"
],
"detection": {
"method": "process",
"process_name": "claude",
"fallback": "lsof"
},
"thresholds": {
"warn_percent": 75,
"export_percent": 75,
"compaction_starts_at": 80
},
"triggers": {
"context_percent": true,
"size_mb": null,
"time_minutes": null,
"turns": null
},
"export": {
"method": "script",
"script": "~/.coditect/scripts/extractors/claude_extractor.py",
"args": ["--format", "cusf"],
"strategy": "full"
},
"pending_dir": "claude-sessions-pending"
},
"codex": {
"enabled": true,
"binary": "codex",
"session_paths": [
"~/.codex/sessions/**/*.jsonl",
"~/.codex/history.jsonl"
],
"detection": {
"method": "process",
"process_name": "codex"
},
"thresholds": {
"warn_percent": 80,
"export_percent": 85,
"compaction_starts_at": 90
},
"triggers": {
"context_percent": true,
"size_mb": null,
"time_minutes": null,
"turns": null
},
"export": {
"method": "script",
"script": "~/.coditect/scripts/extractors/codex_extractor.py",
"args": ["--format", "cusf"]
},
"pending_dir": "codex-sessions-pending"
},
"gemini": {
"enabled": true,
"binary": "gemini",
"session_paths": [
"~/.gemini/sessions/**/*.jsonl",
"~/.gemini/exports/**/*.jsonl"
],
"detection": {
"method": "process",
"process_name": "gemini"
},
"thresholds": {
"warn_percent": 80,
"export_percent": 85,
"compaction_starts_at": 90
},
"triggers": {
"context_percent": true,
"size_mb": null,
"time_minutes": null,
"turns": null
},
"export": {
"method": "script",
"script": "~/.coditect/scripts/extractors/gemini_extractor.py",
"args": ["--format", "cusf"]
},
"pending_dir": "gemini-sessions-pending"
},
"kimi": {
"enabled": true,
"binary": "kimi",
"session_paths": [
"~/.kimi/sessions/**/context.jsonl",
"~/.kimi/sessions/**/wire.jsonl",
"~/.kimi/user-history/**/*.jsonl"
],
"detection": {
"method": "file_watch",
"watch_pattern": "**/wire.jsonl",
"fallback": "process"
},
"thresholds": {
"warn_percent": 70,
"export_percent": 79,
"compaction_starts_at": 80
},
"triggers": {
"context_percent": true,
"size_mb": 5,
"time_minutes": 15,
"turns": 10
},
"export": {
"method": "script",
"script": "~/.coditect/scripts/extractors/kimi_extractor.py",
"args": ["--format", "cusf", "--strategy", "incremental"]
},
"pending_dir": "kimi-sessions-pending"
}
}
}
Detection Methods
| Method | Use Case | Implementation |
|---|---|---|
process | LLMs with long-running CLI process | lsof / ps to find active sessions |
file_watch | LLMs with unbounded log growth | notify-rs inotify/FSEvents |
status_command | LLMs with status API | Parse <llm> /status output |
Trigger Types
| Trigger | Description | Config Key |
|---|---|---|
| Context % | Export when context usage exceeds threshold | thresholds.export_percent |
| Size MB | Export when session file exceeds size | triggers.size_mb |
| Time Minutes | Periodic export regardless of usage | triggers.time_minutes |
| Turn Count | Export after N user interactions | triggers.turns |
State File
File: ~/.coditect-data/context-storage/watcher-state.json
{
"version": "2.0.0",
"last_updated": "2026-01-28T19:30:00Z",
"llms": {
"claude": {
"active_sessions": ["uuid-1", "uuid-2"],
"session_cooldowns": {
"uuid-1": "2026-01-28T19:20:00Z"
},
"last_export": "2026-01-28T19:15:00Z",
"exports_triggered": 12,
"last_context_percent": 72.5
},
"codex": {
"active_sessions": ["uuid-3"],
"session_cooldowns": {},
"last_export": "2026-01-28T18:00:00Z",
"exports_triggered": 3,
"last_context_percent": 45.0
},
"kimi": {
"active_sessions": ["uuid-4"],
"session_cooldowns": {},
"last_export": "2026-01-28T19:25:00Z",
"last_export_line": 1547,
"exports_triggered": 8,
"last_file_size_mb": 4.2
}
},
"global_stats": {
"total_exports": 23,
"uptime_hours": 48.5
}
}
CLI Interface
# Start unified watcher (monitors all enabled LLMs)
codi-watcher
# Monitor specific LLMs only
codi-watcher --llm claude,codex
# Override config file
codi-watcher --config /path/to/custom-config.json
# Status check
codi-watcher --status
codi-watcher --status --llm kimi
# Dry run (show what would be exported)
codi-watcher --dry-run
# Force export for specific LLM
codi-watcher --force-export --llm gemini
# Reload configuration without restart
codi-watcher --reload
# Debug mode with verbose logging
codi-watcher --verbose
Service Integration
macOS (launchd): ~/Library/LaunchAgents/ai.coditect.watcher.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>ai.coditect.watcher</string>
<key>ProgramArguments</key>
<array>
<string>/Users/halcasteel/.coditect/bin/codi-watcher</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>StandardOutPath</key>
<string>/Users/halcasteel/.coditect-data/logs/watcher.log</string>
<key>StandardErrorPath</key>
<string>/Users/halcasteel/.coditect-data/logs/watcher.error.log</string>
</dict>
</plist>
Linux (systemd): ~/.config/systemd/user/coditect-watcher.service
[Unit]
Description=CODITECT Unified Multi-LLM Watcher
After=network.target
[Service]
Type=simple
ExecStart=%h/.coditect/bin/codi-watcher
Restart=always
RestartSec=10
[Install]
WantedBy=default.target
Implementation
Phase 1: Configuration & Schema (J.19.1)
- Create JSON schema:
schemas/llm-watchers-v1.0.0.json - Create default config:
config/llm-watchers.json - Add config loading to existing codi-watcher
Phase 2: Multi-LLM Detection (J.19.2)
- Refactor detection engine to be LLM-agnostic
- Add file_watch detection method for KIMI
- Implement per-LLM session discovery
Phase 3: Unified Monitor Loop (J.19.3)
- Create per-LLM monitor tasks (async Rust)
- Implement configurable trigger evaluation
- Add per-LLM threshold checking
Phase 4: Export Pipeline (J.19.4)
- Abstract export mechanism (builtin vs script)
- Add script invocation with args
- Route output to per-LLM pending directories
Phase 5: State Management (J.19.5)
- Migrate state file to multi-LLM format
- Implement per-LLM cooldown tracking
- Add global statistics
Phase 6: Deprecation (J.19.6)
- Mark separate watcher projects as deprecated
- Update documentation
- Remove from build pipeline
Migration Path
From codi-watcher v0.4.0
- Automatic: Existing Claude config migrates to
llms.claudesection - State Migration: Old state file converted to new multi-LLM format
- Service Update: Single plist/service replaces Claude-only version
From Proposed Watchers
- Codex: Design docs (ADR-124) incorporated, code discarded
- Gemini: Design docs (ADR-127) incorporated, code discarded
- KIMI: KASE design (ADR-133) incorporated as file_watch + triggers
Consequences
Positive
- Single codebase to maintain
- Consistent behavior across all LLMs
- Easy LLM addition via config (no recompilation)
- Unified logging and monitoring
- Single service to manage
- Shared improvements benefit all LLMs
Negative
- Larger binary (all LLM logic included)
- Config complexity (more options to understand)
- Migration effort for existing users
Risks
| Risk | Mitigation |
|---|---|
| Config errors disable all LLMs | Validate config on load, fail gracefully per-LLM |
| One LLM bug affects others | Isolate monitor tasks, error boundaries |
| Performance with many LLMs | Async tasks, configurable poll intervals |
Alternatives Considered
- Keep Separate Watchers: Rejected - too much duplication, maintenance burden
- Python Unified Watcher: Rejected - performance concerns, existing Rust investment
- Plugin Architecture: Rejected - over-engineering for 4-5 LLMs
Related
- ADR-133: KIMI Automated Session Export (KASE) - triggers incorporated, implementation note added
- ADR-124: Codex Session Export Watcher - SUPERSEDED (status updated 2026-02-05, never implemented separately)
- ADR-127: Gemini Session Export Watcher - SUPERSEDED (planned but never created; Gemini support implemented directly in unified watcher)
- ADR-122: Unified LLM Component Architecture - alignment
References
- Existing codi-watcher:
tools/context-watcher/ - notify-rs: https://docs.rs/notify/
- CUSF Schema:
schemas/cusf-v1.0.0.json
Appendix A: LLM Export Reference
Complete documentation for each supported LLM's export configuration, timing, and limits.
A.1 Claude (Anthropic Claude Code)
Session Paths
| Path | Format | Purpose |
|---|---|---|
~/.claude/projects/<project_hash>/<session_uuid>.jsonl | Native JSONL | Active sessions |
~/Claude-Exports/claude-export-*.txt | Export TXT | Manual exports |
Native JSONL Format
{"type": "user", "message": {"content": [{"type": "text", "text": "..."}]}, "timestamp": "2026-01-28T..."}
{"type": "assistant", "message": {"content": [...], "model": "claude-opus-4-5", "usage": {"input_tokens": 1000, "output_tokens": 500}}}
{"type": "system", "reason": "compacted", "summary": "..."}
{"type": "summary", "content": "..."}
Entry Types:
user: User messages with optional tool resultsassistant: AI responses with token usagesystem: Compaction events, retriessummary: Conversation summaries from compaction
Configuration
{
"claude": {
"enabled": true,
"binary": "claude",
"session_paths": ["~/.claude/projects/**/*.jsonl"],
"detection": {
"method": "process",
"process_name": "claude",
"fallback": "lsof"
},
"thresholds": {
"warn_percent": 75,
"export_percent": 75,
"compaction_starts_at": 80
},
"triggers": {
"context_percent": true,
"size_mb": null,
"time_minutes": null,
"turns": null
},
"export": {
"method": "script",
"script": "~/.coditect/scripts/extractors/claude_extractor.py",
"args": ["--format", "cusf"],
"strategy": "full"
},
"pending_dir": "claude-sessions-pending"
}
}
Timing & Limits
| Parameter | Value | Rationale |
|---|---|---|
| Warn Threshold | 75% | Early warning before compaction |
| Export Threshold | 75% | Export before data loss |
| Compaction Starts | 80% | Claude begins summarizing context |
| Cooldown | 10 minutes (global) | Prevent export spam |
| Detection Interval | 30 seconds | Process detection polling |
Extractor Options
claude_extractor.py [source] [options]
--format cusf # Output format (cusf, jsonl, json)
--session-id UUID # Extract specific session
--include-tool-results # Include tool outputs (default: true)
--include-thinking # Include extended thinking (default: true)
A.2 Codex (OpenAI Codex CLI)
Session Paths
| Path | Format | Purpose |
|---|---|---|
~/.codex/history.jsonl | Flat JSONL | All sessions in single file |
~/.codex/sessions/YYYY/MM/DD/*.jsonl | Date hierarchy | Per-session files |
Native JSONL Format
{"session_id": "019c013d-...", "role": "user", "content": "...", "timestamp": "2026-01-28T..."}
{"session_id": "019c013d-...", "role": "assistant", "content": "...", "model": "gpt-4o", "usage": {"prompt_tokens": 100, "completion_tokens": 50}}
Entry Types:
role: user- User messagesrole: assistant- AI responses with usagerole: system- System messagestool_calls- Array of tool invocations (inline)
Configuration
{
"codex": {
"enabled": true,
"binary": "codex",
"session_paths": [
"~/.codex/sessions/**/*.jsonl",
"~/.codex/history.jsonl"
],
"detection": {
"method": "process",
"process_name": "codex",
"fallback": "lsof"
},
"thresholds": {
"warn_percent": 80,
"export_percent": 85,
"compaction_starts_at": 90
},
"triggers": {
"context_percent": true,
"size_mb": null,
"time_minutes": null,
"turns": null
},
"export": {
"method": "script",
"script": "~/.coditect/scripts/extractors/codex_extractor.py",
"args": ["--format", "cusf"],
"strategy": "full"
},
"pending_dir": "codex-sessions-pending"
}
}
Timing & Limits
| Parameter | Value | Rationale |
|---|---|---|
| Warn Threshold | 80% | Codex has larger context window |
| Export Threshold | 85% | Higher threshold for GPT-4o context |
| Compaction Starts | 90% | Conservative estimate |
| Cooldown | 10 minutes (global) | Standard cooldown |
| Detection Interval | 30 seconds | Process detection polling |
Extractor Options
codex_extractor.py [source] [options]
--format cusf # Output format (cusf, jsonl, json)
--session-id UUID # Extract specific session from history.jsonl
--include-tool-results # Include tool outputs (default: true)
A.3 Gemini (Google Gemini CLI)
Session Paths
| Path | Format | Purpose |
|---|---|---|
~/.gemini/sessions/*.jsonl | Session JSONL | Active sessions |
~/.gemini/exports/*.jsonl | Export JSONL | Manual exports |
Native JSONL Format
{"role": "user", "parts": [{"text": "..."}], "metadata": {...}}
{"role": "model", "parts": [{"text": "..."}, {"functionCall": {...}}], "usageMetadata": {"promptTokenCount": 100, "candidatesTokenCount": 50}}
Entry Types:
role: user- User messagesrole: model- AI responses (note:modelnotassistant)parts[].text- Text contentparts[].functionCall- Tool invocationsparts[].functionResponse- Tool results
Configuration
{
"gemini": {
"enabled": true,
"binary": "gemini",
"session_paths": [
"~/.gemini/sessions/**/*.jsonl",
"~/.gemini/exports/**/*.jsonl"
],
"detection": {
"method": "process",
"process_name": "gemini",
"fallback": "lsof"
},
"thresholds": {
"warn_percent": 80,
"export_percent": 85,
"compaction_starts_at": 90
},
"triggers": {
"context_percent": true,
"size_mb": null,
"time_minutes": null,
"turns": null
},
"export": {
"method": "script",
"script": "~/.coditect/scripts/extractors/gemini_extractor.py",
"args": ["--format", "cusf"],
"strategy": "full"
},
"pending_dir": "gemini-sessions-pending"
}
}
Timing & Limits
| Parameter | Value | Rationale |
|---|---|---|
| Warn Threshold | 80% | Gemini 2.0 has 2M token context |
| Export Threshold | 85% | Higher threshold for large context |
| Compaction Starts | 90% | Conservative estimate |
| Cooldown | 10 minutes (global) | Standard cooldown |
| Detection Interval | 30 seconds | Process detection polling |
Extractor Options
gemini_extractor.py [source] [options]
--format cusf # Output format (cusf, jsonl, json)
--session-id UUID # Extract specific session
--include-tool-results # Include function responses (default: true)
A.4 KIMI (Moonshot AI KIMI CLI)
Session Paths
| Path | Format | Purpose |
|---|---|---|
~/.kimi/sessions/<workdir_hash>/<session_uuid>/context.jsonl | Context JSONL | Session context |
~/.kimi/sessions/<workdir_hash>/<session_uuid>/wire.jsonl | Wire protocol | Raw API calls |
~/.kimi/user-history/<workdir_hash>.jsonl | User history | Conversation snippets |
Native JSONL Formats
context.jsonl:
{"role": "user", "content": "..."}
{"role": "assistant", "content": "..."}
{"role": "system", "content": "..."}
{"role": "_checkpoint", "id": "...", "token_count": 1500}
{"role": "_usage", "token_count": 2000}
wire.jsonl (LOSSLESS):
{"type": "metadata", "protocol_version": "1.0", "session_id": "..."}
{"type": "request", "method": "chat", "messages": [...], "timestamp": "..."}
{"type": "response", "content": "...", "usage": {...}, "timestamp": "..."}
Entry Types:
role: user- User messagesrole: assistant- AI responsesrole: system- System promptsrole: _checkpoint- Context checkpoints (metadata)role: _usage- Token usage markers
Configuration
{
"kimi": {
"enabled": true,
"binary": "kimi",
"session_paths": [
"~/.kimi/sessions/**/context.jsonl",
"~/.kimi/sessions/**/wire.jsonl",
"~/.kimi/user-history/**/*.jsonl"
],
"detection": {
"method": "process",
"process_name": "kimi",
"fallback": "lsof"
},
"thresholds": {
"warn_percent": 70,
"export_percent": 79,
"compaction_starts_at": 80
},
"triggers": {
"context_percent": true,
"size_mb": 5,
"time_minutes": 15,
"turns": 10
},
"export": {
"method": "script",
"script": "~/.coditect/scripts/extractors/kimi_extractor.py",
"args": ["--format", "cusf"],
"strategy": "full"
},
"pending_dir": "kimi-sessions-pending",
"cooldown_minutes": 5
}
}
Timing & Limits
| Parameter | Value | Rationale |
|---|---|---|
| Warn Threshold | 70% | KIMI has smaller context, earlier warning |
| Export Threshold | 79% | Export just before compaction |
| Compaction Starts | 80% | KIMI aggressively compacts |
| Size Trigger | 5 MB | wire.jsonl grows ~0.88 MB/hour |
| Time Trigger | 15 minutes | Periodic backup for long sessions |
| Turn Trigger | 10 turns | Export after significant work |
| Cooldown | 5 minutes | Shorter due to fast growth rate |
| Detection Interval | 30 seconds | Process detection polling |
Extractor Options
kimi_extractor.py [source] [options]
--format cusf # Output format (cusf, jsonl, json)
--session-id UUID # Extract specific session
--include-system # Include system messages (default: true)
--include-checkpoints # Include _checkpoint entries (default: false)
--lossless # Extract wire.jsonl with ALL protocol data
LOSSLESS Mode: When extracting wire.jsonl, ALL protocol data is preserved for complete reconstruction. Output includes -LOSSLESS suffix.
Appendix B: Codi-Watcher Integration
Binary Location
~/.coditect/bin/codi-watcher (symlink)
→ ~/Library/Application Support/CODITECT/core/bin/codi-watcher
Service Files
macOS (launchd):
~/Library/LaunchAgents/ai.coditect.watcher.plist
Linux (systemd):
~/.config/systemd/user/coditect-watcher.service
Log Files
| Log | Path | Purpose |
|---|---|---|
| Main log | ~/.coditect-data/logs/watcher.log | Watcher operations |
| Error log | ~/.coditect-data/logs/watcher.error.log | Error output |
| State | ~/.coditect-data/context-storage/watcher-state.json | Cooldowns, stats |
Pending Directories
All exports are written to per-LLM pending directories:
~/.coditect-data/
├── claude-sessions-pending/
├── codex-sessions-pending/
├── gemini-sessions-pending/
└── kimi-sessions-pending/
Filename Format:
{timestamp}Z-session-{llm}-{session_uuid}--{llm}-session-export.jsonl
Example:
2026-01-28T13-06-48Z-session-kimi-add7c4a1-...--kimi-session-export.jsonl
CLI Commands
# Start watcher (foreground)
codi-watcher
# Status check
codi-watcher --status
codi-watcher --status --llm kimi
# Force export
codi-watcher --force-export --llm claude
# Dry run
codi-watcher --dry-run
# Specific LLMs only
codi-watcher --llm claude,codex
# Debug mode
codi-watcher --verbose
Service Management
# macOS
launchctl list | grep coditect # Check status
launchctl load ~/Library/LaunchAgents/ai.coditect.watcher.plist
launchctl unload ~/Library/LaunchAgents/ai.coditect.watcher.plist
# Linux
systemctl --user status coditect-watcher
systemctl --user start coditect-watcher
systemctl --user enable coditect-watcher
Appendix C: Export Automation Summary
Default Configuration Quick Reference
| LLM | Warn | Export | Compaction | Size | Time | Turns | Cooldown |
|---|---|---|---|---|---|---|---|
| Claude | 75% | 75% | 80% | - | - | - | 10 min |
| Codex | 80% | 85% | 90% | - | - | - | 10 min |
| Gemini | 80% | 85% | 90% | - | - | - | 10 min |
| KIMI | 70% | 79% | 80% | 5 MB | 15 min | 10 | 5 min |
Extractor Scripts
| LLM | Script | Size | Features |
|---|---|---|---|
| Claude | claude_extractor.py | 21 KB | JSONL + TXT export support |
| Codex | codex_extractor.py | 14 KB | Multi-session history.jsonl |
| Gemini | gemini_extractor.py | 13 KB | Parts-based content extraction |
| KIMI | kimi_extractor.py | 24 KB | Lossless wire.jsonl support |
Output Format (CUSF)
All extractors output CODITECT Universal Session Format (CUSF):
{"_meta": {"format": "cusf", "version": "1.0.0", "exported_at": "...", "exporter": "coditect-sx/1.0.0"}}
{"type": "session_start", "session_id": "...", "llm_source": "claude", "llm_model": "claude-opus-4-5", ...}
{"type": "message", "role": "user", "content": "...", "timestamp": "...", "message_id": "..."}
{"type": "message", "role": "assistant", "content": "...", "usage": {"input": 1000, "output": 500}, ...}
{"type": "tool_use", "tool_name": "Read", "tool_input": {...}, "tool_id": "...", ...}
{"type": "tool_result", "tool_id": "...", "result": "...", ...}
{"type": "session_end", "session_id": "...", "total_messages": 42, "total_tokens": {...}}
Created: 2026-01-28 Updated: 2026-01-28 Author: CODITECT Architecture Team Track: J.19 (Memory - Unified Watcher)