mirror of
https://github.com/harivansh-afk/nix.git
synced 2026-04-15 03:00:47 +00:00
Fix Claude Code Home Manager config
Generate Claude settings from Nix so managed commands use the correct home directory, add declarative keybindings for Shift+Enter newline support, and replace the broken inline docs hook with a portable script. Also stop exporting CLAUDE_CONFIG_DIR so Claude no longer splits managed config between ~/.claude and ~/.config/claude, and fix the status line script shebang for NixOS. Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
parent
b93511b85c
commit
29f9020c2f
6 changed files with 99 additions and 33 deletions
12
config/claude/keybindings.json
Normal file
12
config/claude/keybindings.json
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"$schema": "https://www.schemastore.org/claude-code-keybindings.json",
|
||||
"$docs": "https://code.claude.com/docs/en/keybindings",
|
||||
"bindings": [
|
||||
{
|
||||
"context": "Chat",
|
||||
"bindings": {
|
||||
"shift+enter": "chat:newline"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
{
|
||||
"$schema": "https://json.schemastore.org/claude-code-settings.json",
|
||||
"env": {
|
||||
"CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS": "1"
|
||||
},
|
||||
"permissions": {
|
||||
"defaultMode": "bypassPermissions"
|
||||
},
|
||||
"hooks": {
|
||||
"PreToolUse": [
|
||||
{
|
||||
"matcher": "Read",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "if [[ $(jq -r .tool_input.file_path 2>/dev/null) == */Users/rathi/Documents/GitHub/claude-code-docs/* ]]; then LAST_PULL=\"/Users/rathi/Documents/GitHub/claude-code-docs/.last_pull\" && NOW=$(date +%s) && GITHUB_TS=$(jq -r .last_updated \"/Users/rathi/Documents/GitHub/claude-code-docs/docs/docs_manifest.json\" 2>/dev/null | cut -d. -f1) && GITHUB_UNIX=$(date -j -u -f \"%Y-%m-%dT%H:%M:%S\" \"$GITHUB_TS\" \"+%s\" 2>/dev/null || echo 0) && if [[ -f \"$LAST_PULL\" ]]; then LAST=$(cat \"$LAST_PULL\"); if [[ $GITHUB_UNIX -gt $LAST ]]; then echo \"🔄 Updating docs to latest version...\" >&2 && (cd /Users/rathi/Documents/GitHub/claude-code-docs && git pull --quiet) && echo $NOW > \"$LAST_PULL\"; fi; else echo \"🔄 Syncing docs for the first time...\" >&2 && (cd /Users/rathi/Documents/GitHub/claude-code-docs && git pull --quiet) && echo $NOW > \"$LAST_PULL\"; fi; fi"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"statusLine": {
|
||||
"type": "command",
|
||||
"command": "/Users/rathi/.claude/statusline.sh"
|
||||
},
|
||||
"voiceEnabled": true
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
# Full-featured status line with context window usage
|
||||
# Usage: Copy to ~/.claude/statusline.sh and make executable
|
||||
#
|
||||
|
|
|
|||
48
config/claude/sync-docs.sh
Normal file
48
config/claude/sync-docs.sh
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
docs_dir="${HOME}/Documents/GitHub/claude-code-docs"
|
||||
manifest="${docs_dir}/docs/docs_manifest.json"
|
||||
last_pull="${docs_dir}/.last_pull"
|
||||
|
||||
file_path="$(jq -r '.tool_input.file_path // empty' 2>/dev/null || true)"
|
||||
case "${file_path}" in
|
||||
"${docs_dir}"/*) ;;
|
||||
*) exit 0 ;;
|
||||
esac
|
||||
|
||||
if [[ ! -d "${docs_dir}/.git" || ! -f "${manifest}" ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
github_unix="$(
|
||||
python3 - "${manifest}" <<'PY'
|
||||
import datetime
|
||||
import json
|
||||
import sys
|
||||
|
||||
manifest_path = sys.argv[1]
|
||||
|
||||
try:
|
||||
with open(manifest_path, encoding="utf-8") as handle:
|
||||
last_updated = json.load(handle).get("last_updated", "")
|
||||
last_updated = last_updated.split(".", 1)[0]
|
||||
parsed = datetime.datetime.strptime(last_updated, "%Y-%m-%dT%H:%M:%S")
|
||||
print(int(parsed.replace(tzinfo=datetime.timezone.utc).timestamp()))
|
||||
except Exception:
|
||||
print(0)
|
||||
PY
|
||||
)"
|
||||
|
||||
last_synced=0
|
||||
if [[ -f "${last_pull}" ]]; then
|
||||
last_synced="$(cat "${last_pull}" 2>/dev/null || echo 0)"
|
||||
fi
|
||||
|
||||
if [[ "${github_unix}" -le "${last_synced}" ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
printf 'Syncing Claude docs to latest version...\n' >&2
|
||||
git -C "${docs_dir}" pull --quiet
|
||||
date +%s > "${last_pull}"
|
||||
|
|
@ -1,24 +1,60 @@
|
|||
{
|
||||
config,
|
||||
inputs,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
claudePackage = inputs.claudeCode.packages.${pkgs.stdenv.hostPlatform.system}.default;
|
||||
jsonFormat = pkgs.formats.json { };
|
||||
claudeSettings = jsonFormat.generate "claude-settings.json" {
|
||||
"$schema" = "https://json.schemastore.org/claude-code-settings.json";
|
||||
env = {
|
||||
CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS = "1";
|
||||
};
|
||||
permissions = {
|
||||
defaultMode = "bypassPermissions";
|
||||
};
|
||||
hooks = {
|
||||
PreToolUse = [
|
||||
{
|
||||
matcher = "Read";
|
||||
hooks = [
|
||||
{
|
||||
type = "command";
|
||||
command = "${config.home.homeDirectory}/.claude/sync-docs.sh";
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
};
|
||||
statusLine = {
|
||||
type = "command";
|
||||
command = "${config.home.homeDirectory}/.claude/statusline.sh";
|
||||
};
|
||||
voiceEnabled = true;
|
||||
};
|
||||
in
|
||||
{
|
||||
home.file.".local/bin/claude".source = "${claudePackage}/bin/claude";
|
||||
|
||||
# Claude Code still resolves user settings from ~/.claude rather than XDG.
|
||||
# Claude Code stores shared config, commands, plugins, and skills in ~/.claude.
|
||||
# Global UI settings changed through /config still live in ~/.claude.json and are
|
||||
# intentionally left user-managed because Claude mutates that file directly.
|
||||
home.file.".claude/CLAUDE.md".source = ../config/claude/CLAUDE.md;
|
||||
home.file.".claude/commands" = {
|
||||
source = ../config/claude/commands;
|
||||
recursive = true;
|
||||
};
|
||||
home.file.".claude/settings.json".source = ../config/claude/settings.json;
|
||||
home.file.".claude/settings.json".source = claudeSettings;
|
||||
home.file.".claude/settings.local.json".source = ../config/claude/settings.local.json;
|
||||
home.file.".claude/keybindings.json".source = ../config/claude/keybindings.json;
|
||||
home.file.".claude/statusline.sh" = {
|
||||
source = ../config/claude/statusline.sh;
|
||||
executable = true;
|
||||
};
|
||||
home.file.".claude/sync-docs.sh" = {
|
||||
source = ../config/claude/sync-docs.sh;
|
||||
executable = true;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,9 +40,6 @@ in
|
|||
AWS_SHARED_CREDENTIALS_FILE = "${config.xdg.configHome}/aws/credentials";
|
||||
AWS_CONFIG_FILE = "${config.xdg.configHome}/aws/config";
|
||||
})
|
||||
(lib.mkIf (f.claude or false) {
|
||||
CLAUDE_CONFIG_DIR = "${config.xdg.configHome}/claude";
|
||||
})
|
||||
{
|
||||
PSQL_HISTORY = "${config.xdg.stateHome}/psql_history";
|
||||
SQLITE_HISTORY = "${config.xdg.stateHome}/sqlite_history";
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue