Skip to content

Commit 9cb7e9d

Browse files
ackerrclaude
andcommitted
chore: add ghostty/claude configs, update zsh and starship
- Add ghostty terminal config (Kanagawa theme) - Add claude settings and statusline script via stow - Fix compinit loading order and fzf-tab keybindings - Disable noisy starship modules (git_status, python, package, gcloud) - Remove redundant profile sourcing and CA bundle exports Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent bba4969 commit 9cb7e9d

File tree

6 files changed

+251
-14
lines changed

6 files changed

+251
-14
lines changed

Makefile

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
11
TARGET ?= ~
22

3-
.PHONY: dryrun override kitty wezterm alacritty brew
3+
.PHONY: dryrun override kitty wezterm alacritty brew claude
44

55
all: dryrun
6-
stow git tmux zsh --target $(TARGET)
6+
stow git tmux zsh claude --target $(TARGET)
77

88
dryrun:
9-
stow git tmux zsh -n -v --target $(TARGET)
9+
stow git tmux zsh claude -n -v --target $(TARGET)
1010

1111
override:
12-
stow git tmux zsh --target $(TARGET) --adopt
12+
stow git tmux zsh claude --target $(TARGET) --adopt
13+
14+
claude:
15+
stow claude --target $(TARGET)
1316

1417
kitty:
1518
stow kitty --target $(TARGET)

claude/.claude/settings.json

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{
2+
"model": "opus",
3+
"statusLine": {
4+
"type": "command",
5+
"command": "sh ~/.claude/statusline-command.sh"
6+
},
7+
"enabledPlugins": {
8+
"equity-research@financial-services-plugins": true,
9+
"financial-analysis@financial-services-plugins": true,
10+
"wealth-management@financial-services-plugins": true
11+
},
12+
"alwaysThinkingEnabled": false,
13+
"autoUpdatesChannel": "stable",
14+
"effortLevel": "high",
15+
"theme": "dark",
16+
"preferredNotifChannel": "terminal_bell",
17+
"permissions": {
18+
"allow": [
19+
"Read",
20+
"Grep",
21+
"Glob",
22+
"WebSearch",
23+
"WebFetch",
24+
"Bash(git status)",
25+
"Bash(git log *)",
26+
"Bash(git diff *)",
27+
"Bash(npm run *)",
28+
"Bash(npm list *)",
29+
"Bash(ls *)",
30+
"Bash(python *)",
31+
"Bash(node *)"
32+
],
33+
"deny": [
34+
"Bash(rm -rf *)"
35+
]
36+
}
37+
}
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
#!/bin/sh
2+
input=$(cat)
3+
4+
cwd=$(echo "$input" | jq -r '.workspace.current_dir // .cwd')
5+
model=$(echo "$input" | jq -r '.model.display_name')
6+
used=$(echo "$input" | jq -r '.context_window.used_percentage // empty')
7+
cost=$(echo "$input" | jq -r '.cost.total_cost_usd // empty')
8+
9+
# Show only the directory name
10+
short_cwd=$(basename "$cwd")
11+
12+
# Git branch (skip optional locks)
13+
branch=""
14+
if git -C "$cwd" rev-parse --git-dir > /dev/null 2>&1; then
15+
branch=$(git -C "$cwd" -c core.hooksPath=/dev/null symbolic-ref --short HEAD 2>/dev/null || git -C "$cwd" rev-parse --short HEAD 2>/dev/null)
16+
fi
17+
18+
# Shorten model name: remove "Claude " prefix
19+
short_model="${model#Claude }"
20+
21+
# === Line 1: model · dir (branch) · context% · $cost ===
22+
printf "\033[35m%s\033[0m" "$short_model"
23+
24+
if [ -n "$branch" ]; then
25+
printf " \033[90m·\033[0m \033[34m%s\033[0m \033[90m(\033[38;5;146m%s\033[90m)\033[0m" "$short_cwd" "$branch"
26+
else
27+
printf " \033[90m·\033[0m \033[34m%s\033[0m" "$short_cwd"
28+
fi
29+
30+
if [ -n "$used" ]; then
31+
pct=$(echo "$used" | tr -d '%')
32+
if [ "$pct" -ge 90 ] 2>/dev/null; then
33+
color="\033[31m"
34+
elif [ "$pct" -ge 70 ] 2>/dev/null; then
35+
color="\033[33m"
36+
else
37+
color="\033[32m"
38+
fi
39+
printf " \033[90m·\033[0m \033[90mctx\033[0m ${color}%s%%\033[0m" "$used"
40+
fi
41+
42+
43+
# === Line 2: Usage (5h / 7d) from oauth/usage API ===
44+
45+
# Color based on usage percentage
46+
usage_color() {
47+
pct=$1
48+
if [ "$pct" -ge 90 ] 2>/dev/null; then
49+
printf "\033[31m"
50+
elif [ "$pct" -ge 70 ] 2>/dev/null; then
51+
printf "\033[38;2;255;176;85m"
52+
elif [ "$pct" -ge 50 ] 2>/dev/null; then
53+
printf "\033[33m"
54+
else
55+
printf "\033[32m"
56+
fi
57+
}
58+
59+
# Progress bar: usage_bar <pct> <width>
60+
usage_bar() {
61+
pct=$1
62+
width=${2:-15}
63+
filled=$(( pct * width / 100 ))
64+
empty=$(( width - filled ))
65+
color=$(usage_color "$pct")
66+
bar=""
67+
i=0; while [ "$i" -lt "$filled" ]; do bar="${bar}"; i=$((i+1)); done
68+
i=0; while [ "$i" -lt "$empty" ]; do bar="${bar}"; i=$((i+1)); done
69+
printf "${color}%s\033[0m" "$bar"
70+
}
71+
72+
# Format ISO reset time to local HH:MM or "Mon DD, HH:MM"
73+
format_reset() {
74+
iso=$1
75+
style=$2
76+
[ -z "$iso" ] || [ "$iso" = "null" ] && return
77+
stripped=$(echo "$iso" | sed 's/\.[0-9]*//' | sed 's/+00:00$//' | sed 's/Z$//')
78+
epoch=$(env TZ=UTC date -j -f "%Y-%m-%dT%H:%M:%S" "$stripped" +%s 2>/dev/null)
79+
[ -z "$epoch" ] && return
80+
if [ "$style" = "time" ]; then
81+
date -j -r "$epoch" +"%H:%M" 2>/dev/null
82+
else
83+
date -j -r "$epoch" +"%-m/%-d %H:%M" 2>/dev/null
84+
fi
85+
}
86+
87+
# Fetch usage data with 60s cache
88+
cache_file="/tmp/claude-statusline-usage.json"
89+
cache_max_age=60
90+
mkdir -p /tmp 2>/dev/null
91+
usage_data=""
92+
93+
if [ -f "$cache_file" ]; then
94+
cache_age=$(( $(date +%s) - $(stat -f %m "$cache_file" 2>/dev/null || echo 0) ))
95+
if [ "$cache_age" -lt "$cache_max_age" ]; then
96+
usage_data=$(cat "$cache_file" 2>/dev/null)
97+
fi
98+
fi
99+
100+
if [ -z "$usage_data" ]; then
101+
touch "$cache_file" 2>/dev/null
102+
token=""
103+
if command -v security >/dev/null 2>&1; then
104+
blob=$(security find-generic-password -s "Claude Code-credentials" -w 2>/dev/null)
105+
[ -n "$blob" ] && token=$(echo "$blob" | jq -r '.claudeAiOauth.accessToken // empty' 2>/dev/null)
106+
fi
107+
if [ -n "$token" ] && [ "$token" != "null" ]; then
108+
response=$(curl -s --max-time 10 \
109+
-H "Authorization: Bearer $token" \
110+
-H "anthropic-beta: oauth-2025-04-20" \
111+
"https://api.anthropic.com/api/oauth/usage" 2>/dev/null)
112+
if [ -n "$response" ] && echo "$response" | jq -e '.five_hour' >/dev/null 2>&1; then
113+
usage_data="$response"
114+
echo "$response" > "$cache_file"
115+
fi
116+
fi
117+
fi
118+
119+
if [ -n "$usage_data" ] && echo "$usage_data" | jq -e '.five_hour' >/dev/null 2>&1; then
120+
five_pct=$(echo "$usage_data" | jq -r '.five_hour.utilization // 0' | awk '{printf "%.0f", $1}')
121+
five_reset_iso=$(echo "$usage_data" | jq -r '.five_hour.resets_at // empty')
122+
five_reset=$(format_reset "$five_reset_iso" "time")
123+
124+
seven_pct=$(echo "$usage_data" | jq -r '.seven_day.utilization // 0' | awk '{printf "%.0f", $1}')
125+
seven_reset_iso=$(echo "$usage_data" | jq -r '.seven_day.resets_at // empty')
126+
seven_reset=$(format_reset "$seven_reset_iso" "datetime")
127+
128+
printf " \033[90m·\033[0m \033[90msession\033[0m %s%s%%\033[0m" "$(usage_color "$five_pct")" "$five_pct"
129+
[ -n "$five_reset" ] && printf " \033[90m@%s\033[0m" "$five_reset"
130+
131+
printf " \033[90m·\033[0m \033[90mweekly\033[0m %s%s%%\033[0m" "$(usage_color "$seven_pct")" "$seven_pct"
132+
[ -n "$seven_reset" ] && printf " \033[90m@%s\033[0m" "$seven_reset"
133+
fi

ghostty/.config/ghostty/config

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
## General
2+
3+
## Font
4+
font-family = "CaskaydiaCove NFM Light"
5+
font-family-bold = "CaskaydiaCove Nerd Font Mono"
6+
font-family-italic = "CaskaydiaCove NFM Light"
7+
font-family-bold-italic = "CaskaydiaCove Nerd Font Mono"
8+
font-size = 15
9+
10+
## Colors (Kanagawa)
11+
foreground = #DCD7BA
12+
background = #1F1F28
13+
selection-foreground = #C8C093
14+
selection-background = #2D4F67
15+
16+
# 16-color palette
17+
palette = 0=#090618
18+
palette = 1=#C34043
19+
palette = 2=#76946A
20+
palette = 3=#C0A36E
21+
palette = 4=#7E9CD8
22+
palette = 5=#957FB8
23+
palette = 6=#6A9589
24+
palette = 7=#C8C093
25+
palette = 8=#727169
26+
palette = 9=#E82424
27+
palette = 10=#98BB6C
28+
palette = 11=#E6C384
29+
palette = 12=#7FB4CA
30+
palette = 13=#938AA9
31+
palette = 14=#7AA89F
32+
palette = 15=#DCD7BA
33+
34+
auto-update-channel = tip
35+
36+
37+
# Window/background appearance
38+
background-opacity = 0.80
39+
background-blur = 20
40+
keybind = cmd+u=toggle_background_opacity
41+
keybind = cmd+enter=toggle_maximize

zsh/.config/starship.toml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,16 @@
11
add_newline = false
22
command_timeout = 5000
3+
4+
[git_status]
5+
disabled = true
6+
7+
[python]
8+
detect_extensions = []
9+
detect_files = ["pyproject.toml"]
10+
detect_folders = []
11+
12+
[package]
13+
disabled = true
14+
15+
[gcloud]
16+
disabled = true

zsh/.zshrc

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@ autoload -Uz _zinit
1919
### End of Zinit's installer chunk
2020

2121
# plugins
22-
autoload -Uz compinit
23-
compinit
2422

2523
zinit ice lucid wait"1" as"command" from"gh-r" lucid \
2624
mv"zoxide*/zoxide -> zoxide" \
@@ -32,16 +30,17 @@ zinit ice lucid wait'0b' from"gh-r" as"program"
3230
zinit light junegunn/fzf
3331

3432
zinit ice lucid wait
35-
zinit snippet OMZP::fzf
36-
zinit snippet "https://github.com/junegunn/fzf/blob/master/shell/completion.zsh"
3733
zinit snippet "https://github.com/junegunn/fzf/blob/master/shell/key-bindings.zsh"
3834

39-
# Load completions first
40-
zinit ice lucid wait='0a' atload"zicompinit; zicdreplay"
35+
# Load completions first (synchronous), then initialize compinit exactly once
36+
zinit ice lucid
4137
zinit light zsh-users/zsh-completions
4238

39+
autoload -Uz compinit
40+
compinit
41+
4342
# fzf-tab MUST load after compinit but before autosuggestions
44-
zinit ice lucid wait='0b'
43+
zinit ice lucid
4544
zinit light Aloxaf/fzf-tab
4645

4746
zinit ice lucid wait='1'
@@ -142,8 +141,18 @@ export NVM_AUTO_USE=false # Must be false when lazy loading is enabled
142141

143142
zinit light lukechilds/zsh-nvm
144143

144+
# Keep TAB completion deterministic even if later plugins alter keymaps/styles.
145+
zstyle -d ':fzf-tab:*' accept-line
146+
if (( ${+widgets[fzf-tab-complete]} )); then
147+
bindkey '^I' fzf-tab-complete
148+
bindkey -M emacs '^I' fzf-tab-complete
149+
bindkey -M viins '^I' fzf-tab-complete
150+
else
151+
bindkey '^I' expand-or-complete
152+
bindkey -M emacs '^I' expand-or-complete
153+
bindkey -M viins '^I' expand-or-complete
154+
fi
155+
bindkey -M vicmd '^I' expand-or-complete
156+
145157
# alias
146158
[ -f ~/.alias ] && source ~/.alias
147-
[ -f ~/.profile ] && source ~/.profile
148-
[ -f ~/.bash_profile ] && source ~/.bash_profile
149-
[ -f ~/.zprofile ] && source ~/.zprofile

0 commit comments

Comments
 (0)