# RFC: AI Tools Doctor - Unified Version Management

**Status**: Draft
**Author**: dotfiles team
**Date**: 2025-12-01
**Related**: dotfiles-6l8

## Problem

Multiple AI coding tools (claude-code, codex, opencode, beads) with mixed management approaches:
- NPM tools want to self-update, drift from known state
- Nix tools are declarative but version info scattered
- No unified view for agents to report tool status
- Current `ai-tools-sync.sh` only handles npm tools

## Goals

1. **Unified view** - Single tool to check all AI tools regardless of source
2. **Declarative** - Pin versions in manifest, updates are explicit
3. **Agent-first** - JSON output, exit codes, fast for hooks
4. **Nix-ian** - Reproducible, version-controlled, git-trackable

## Design

### Manifest: `config/ai-tools/tools.json`

```json
{
  "tools": {
    "claude-code": {
      "source": "npm",
      "npm_package": "@anthropic-ai/claude-code",
      "version": "2.0.55",
      "install_dir": "~/.local/share/claude-code",
      "binary": "claude"
    },
    "openai-codex": {
      "source": "npm",
      "npm_package": "@openai/codex",
      "version": "0.63.0",
      "install_dir": "~/.local/share/openai-codex",
      "binary": "codex"
    },
    "opencode": {
      "source": "nix",
      "expected_version": "0.2.1",
      "binary": "opencode"
    },
    "beads": {
      "source": "nix",
      "expected_version": "0.26.0",
      "binary": "bd"
    }
  }
}
```

### CLI: `ai-tools-doctor`

```bash
# Check all tools (human-readable)
ai-tools-doctor check

# Check all tools (machine-readable for agents)
ai-tools-doctor check --json

# Exit code only (for hooks)
ai-tools-doctor check --quiet

# Sync npm tools to declared versions
ai-tools-doctor sync

# Update manifest to latest, then sync
ai-tools-doctor bump [tool]
ai-tools-doctor bump --all
```

### Exit Codes

- `0` - All tools match declared versions
- `1` - Updates available (informational, not error)
- `2` - Error (missing tools, network failure, etc.)

### JSON Output Schema

```json
{
  "status": "updates_available",
  "updates_count": 1,
  "tools": {
    "claude-code": {
      "source": "npm",
      "installed": "2.0.55",
      "declared": "2.0.55",
      "available": "2.0.56",
      "status": "update_available"
    },
    "beads": {
      "source": "nix",
      "installed": "0.26.0",
      "declared": "0.26.0",
      "status": "ok"
    }
  }
}
```

### Shared Skill: `claude/skills/ai-tools-doctor/`

Following existing skills pattern, deployed to both Claude and OpenCode:

```
claude/skills/ai-tools-doctor/
├── SKILL.md          # Agent invocation description
├── README.md         # Documentation
└── scripts/
    └── check.sh      # Wrapper calling bin/ai-tools-doctor.sh
```

**Replaces**: `.claude/skills/update-claude/` (Claude-only, obsolete)

### Agent Integration

Session start hook or skill can run:
```bash
result=$(ai-tools-doctor check --json 2>/dev/null)
if [[ $? -eq 1 ]]; then
  # Agent parses JSON, mentions updates to user
fi
```

## Key Decisions

### Version Pinning (chosen over "latest")

**Why**: Aligns with Nix philosophy. Updates are intentional, tracked in git. Can review changelogs before bumping. Reproducible: same manifest = same tools.

**Tradeoff**: Requires manual `bump` command. Mitigated by agent visibility.

### Nix Tools as Read-Only

**Why**: Nix tools are managed by `nix flake update`, not this tool. Doctor reports their status but doesn't manage them.

**Behavior**: Shows installed vs declared. No "available" check - that's nix territory.

### Shared Skill (not Claude-only)

**Why**: Both Claude and OpenCode use these tools. Unified skill works for both agents via existing Home Manager deployment pattern.

## Files to Modify

1. `config/ai-tools/tools.json` - Add source types, pin versions, add nix tools
2. `bin/ai-tools-sync.sh` → `bin/ai-tools-doctor.sh` - Rename, add JSON/exit codes
3. `claude/skills/ai-tools-doctor/` - New shared skill
4. `home/claude.nix` - Deploy shared skill
5. Delete `.claude/skills/update-claude/` - Replaced

## Open Questions

1. Cache npm registry responses for faster checks?
2. Session start hook integration - automatic or manual trigger?
3. Should `bump` auto-commit the manifest change?

## Out of Scope

- Managing nix tool versions (use `nix flake update`)
- Auto-updating during sessions (agent reports, human decides)
- Other non-AI tools
