Skip to content

feat(config): support CLAUDE_CONFIG_DIR environment variable#451

Open
iwvelando wants to merge 9 commits intortk-ai:developfrom
iwvelando:feat/config-support-claude-config-dir-env-var
Open

feat(config): support CLAUDE_CONFIG_DIR environment variable#451
iwvelando wants to merge 9 commits intortk-ai:developfrom
iwvelando:feat/config-support-claude-config-dir-env-var

Conversation

@iwvelando
Copy link

feat(config): support CLAUDE_CONFIG_DIR environment variable

Summary

RTK now respects the CLAUDE_CONFIG_DIR environment variable, enabling users who run multiple Claude Code instances with custom config directories (e.g., CLAUDE_CONFIG_DIR=~/.claude-a claude) to install and use RTK seamlessly.

Problem

All three places that resolved the Claude config directory (init.rs, integrity.rs, hook_check.rs) had the path ~/.claude hardcoded. Users launching Claude with CLAUDE_CONFIG_DIR=~/.claude-a claude could not use rtk init --global because hooks, RTK.md, settings.json, and CLAUDE.md were always written to ~/.claude regardless of their actual config directory.

Solution

  • Updated resolve_claude_dir() in init.rs to check the CLAUDE_CONFIG_DIR environment variable first, with ~ expansion support, falling back to ~/.claude if unset.
  • Made resolve_claude_dir() pub(crate) so it can be reused from integrity.rs and hook_check.rs instead of duplicating logic.
  • Updated integrity.rs::resolve_hook_path() to delegate to the shared resolver instead of hardcoding ~/.claude.
  • Updated hook_check.rs::hook_installed_path() to delegate to the shared resolver instead of hardcoding ~/.claude.
  • Updated user-facing messages in show_config() and print_manual_instructions() to display the actual resolved path instead of hardcoded ~/.claude.
  • Extracted resolve_claude_dir_impl() as an inner function accepting Option<String> for testability, avoiding env var races in parallel test execution.

Testing

4 new unit tests covering:

  • Default behavior (None~/.claude)
  • Absolute custom path (/tmp/my-custom-claude-dir)
  • Tilde expansion (~/.claude-custom$HOME/.claude-custom)
  • Bare tilde (~$HOME)

Manual Testing: CLAUDE_CONFIG_DIR Support

Environment

  • Custom Claude config dir: ~/.claude-a
  • Branch: feat/config-support-claude-config-dir-env-var
  • Binary: ./target/release/rtk (release build)

Pre-existing state

$ cat ~/.claude-a/settings.json
{
  "model": "opus",
  "enabledPlugins": {
    "gopls-lsp@claude-plugins-official": false,
    "frontend-design@claude-plugins-official": true,
    "swift-lsp@claude-plugins-official": true
  },
  "effortLevel": "medium"
}

$ ll ~/.claude-a/hooks
ls: /Users/isaac/.claude-a/hooks: No such file or directory

Running rtk init --global with CLAUDE_CONFIG_DIR

$ CLAUDE_CONFIG_DIR=~/.claude-a ./target/release/rtk init --global

RTK hook installed/updated (global).

  Hook:      /Users/isaac/.claude-a/hooks/rtk-rewrite.sh
  RTK.md:    /Users/isaac/.claude-a/RTK.md (10 lines)
  CLAUDE.md: @RTK.md reference added

Patch existing /Users/isaac/.claude-a/settings.json? [y/N]
y

  settings.json: hook added
  Backup: /Users/isaac/.claude-a/settings.json.bak
  Restart Claude Code. Test with: git status

Post-install verification

$ cat ~/.claude-a/settings.json
{
  "model": "opus",
  "enabledPlugins": {
    "gopls-lsp@claude-plugins-official": false,
    "frontend-design@claude-plugins-official": true,
    "swift-lsp@claude-plugins-official": true
  },
  "effortLevel": "medium",
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "/Users/isaac/.claude-a/hooks/rtk-rewrite.sh"
          }
        ]
      }
    ]
  }
}

$ ll ~/.claude-a/hooks
total 8
-rwxr-xr-x  1 isaac  staff  1755 Mar  9 23:21 rtk-rewrite.sh

Result

PASS — Hook, RTK.md, CLAUDE.md reference, and settings.json patch all installed correctly under ~/.claude-a/ instead of ~/.claude/.

Usage

# Standard (unchanged)
rtk init --global

# With custom Claude config directory
CLAUDE_CONFIG_DIR=~/.claude-a rtk init --global

aeppling and others added 9 commits March 7, 2026 11:23
add security check cicd on dev branch PR

Signed-off-by: aesoft <43991222+aeppling@users.noreply.github.com>
fix(cicd): Add security check on dev branch PR
- Add install_method detection (homebrew/cargo/script/nix/other)
- Add tokens_saved_24h and tokens_saved_total to payload
- Add Tracker::total_tokens_saved() and Tracker::tokens_saved_24h() methods
- Point telemetry to new dedicated rtk-telemetry service

Signed-off-by: Patrick szymkowiak <patrick.szymkowiak@innovtech.eu>
- Add install_method detection (homebrew/cargo/script/nix/other)
- Add tokens_saved_24h and tokens_saved_total to payload
- Add Tracker::total_tokens_saved() and Tracker::tokens_saved_24h() methods
- Point telemetry to new dedicated rtk-telemetry service

Signed-off-by: Patrick szymkowiak <patrick.szymkowiak@innovtech.eu>
Add backslash variants for .cargo\bin and .local\bin detection

Signed-off-by: Patrick szymkowiak <patrick.szymkowiak@innovtech.eu>
fix: detect install method on Windows paths
RTK now respects the CLAUDE_CONFIG_DIR environment variable, enabling
users who run multiple Claude Code instances with custom config
directories (e.g., CLAUDE_CONFIG_DIR=~/.claude-a claude) to install
and use RTK seamlessly.

- Update resolve_claude_dir() to check CLAUDE_CONFIG_DIR env var first
  with ~ expansion, falling back to ~/.claude if unset
- Make resolve_claude_dir() pub(crate) and reuse from integrity.rs and
  hook_check.rs instead of duplicating hardcoded ~/.claude paths
- Update user-facing messages to display actual resolved path
- Add 4 unit tests covering default, absolute, tilde, and bare tilde
- Update README.md and CLAUDE.md documentation

Signed-off-by: Isaac Velando <isaac@greplinux.com>
@pszymkowiak pszymkowiak force-pushed the develop branch 4 times, most recently from dc20fc4 to cc93afc Compare March 10, 2026 19:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants