Commit graph

1 commit

Author SHA1 Message Date
Manmit Singh
c600e314b3
fix(learn): honor CLAUDE_CONFIG_DIR when locating Claude logs and memory (#1642)
## Description

`headroom learn` ignored `CLAUDE_CONFIG_DIR`.
`ClaudeCodePlugin.__init__` resolved the Claude config directory as
`~/.claude`, and the memory writer wrote the global `CLAUDE.md` to
`~/.claude/CLAUDE.md`. A user who relocates their Claude config with
that env var had `learn` scan the wrong directory and detect no
projects.

Other parts of the codebase already honor the override
(`subscription/client.py`, `subscription/session_tracking.py`,
`mcp_registry/claude.py`); the `learn` path was the outlier.

Closes #1630

## Type of Change

- [x] Bug fix (non-breaking change that fixes an issue)

## Changes Made

- Add `claude_config_dir()` to `headroom/learn/_shared.py` — returns
`$CLAUDE_CONFIG_DIR` when set, else `~/.claude` (via `Path.home()`,
matching the existing override elsewhere).
- `ClaudeCodePlugin.__init__` now defaults `claude_dir` to
`claude_config_dir()` instead of a hardcoded `~/.claude` (an explicit
`claude_dir=` argument still wins).
- `ClaudeCodeWriter._resolve_context_path` writes the home-directory
global memory to `claude_config_dir() / "CLAUDE.md"` instead of
`~/.claude/CLAUDE.md`.

## Testing

- [x] Unit tests pass (`pytest`)
- [x] Linting passes (`ruff check .`)
- [x] Type checking passes (`mypy headroom`)
- [x] New tests added for new functionality
- [x] Manual testing performed

### Test Output

```text
$ pytest tests/test_learn/test_claude_config_dir.py tests/test_learn/test_writer.py -q
35 passed, 1 warning in 0.18s

$ ruff check headroom/learn/ tests/test_learn/test_claude_config_dir.py
All checks passed!

$ mypy headroom/learn/_shared.py headroom/learn/plugins/claude.py headroom/learn/writer.py
Success: no issues found in 3 source files
```

## Real Behavior Proof

- Environment: macOS (arm64), Python 3.14 venv, editable install of this
branch.
- Exact command / steps: ran `python -c "from
headroom.learn.plugins.claude import ClaudeCodePlugin;
print(ClaudeCodePlugin().projects_dir)"` with and without
`CLAUDE_CONFIG_DIR=/tmp/altclaude` set, then `pytest tests/test_learn/
tests/test_cli_learn.py`.
- Observed result: default prints `/Users/<me>/.claude/projects`; with
`CLAUDE_CONFIG_DIR=/tmp/altclaude` it prints `/tmp/altclaude/projects`
(before this change the second still printed `~/.claude/projects`). Test
suite: 226 passed, 3 skipped. New regression tests cover the plugin scan
dir, explicit-arg precedence, and the writer's home-memory path.
- Not tested: end-to-end `headroom learn` against a real relocated log
tree with live Claude Code transcripts — verified at the plugin/writer
resolution layer plus the existing scanner suite.

## Review Readiness

- [x] I have performed a self-review
- [x] This PR is ready for human review

## Additional Notes

The identical hardcode also exists at `headroom/cli/mcp.py:21`
(`CLAUDE_CONFIG_DIR = Path.home() / ".claude"`), but that is a separate
command outside this issue's scope, so I left it for a follow-up to keep
this PR to one issue.

---------

Co-authored-by: JerrettDavis <mxjerrett@gmail.com>
2026-07-01 23:22:16 -05:00