diff options
| author | Craig Jennings <c@cjennings.net> | 2026-04-20 09:12:03 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-04-20 09:12:03 -0500 |
| commit | fdb68c120e8544ae29006e76fb1165c3310ab631 (patch) | |
| tree | 4b7931fc27602b218af265d4bc7dd7f7d20216bd | |
| parent | f3526632257686692687b1b5a596eb399e42b119 (diff) | |
| download | archsetup-fdb68c120e8544ae29006e76fb1165c3310ab631.tar.gz archsetup-fdb68c120e8544ae29006e76fb1165c3310ab631.zip | |
hey: convert alias to function with git awareness + FETCH_HEAD cache
The 'hey' alias launched claude with 'Read docs/protocols.org' — broken
after the docs/ → .ai/ restructure. While updating the path, add
matching behavior to aix:
- Bail early if the current dir isn't a .ai/ template project
- Fetch upstream only when FETCH_HEAD is stale (>10 min old) — avoids
re-fetching on back-to-back invocations in the same project
- Auto-pull when clean, behind, not ahead
- Print a one-line git-status summary otherwise (↑N ↓N dirty)
- Launch claude with the updated .ai/protocols.org path
Function identical across .bashrc.d and .zshrc.d (bash/zsh compatible).
Tested: non-template dir bails cleanly with exit 1; template project
shows status and launches claude; repeated invocations reuse
FETCH_HEAD cache silently.
| -rw-r--r-- | dotfiles/common/.bashrc.d/aliases.sh | 50 | ||||
| -rw-r--r-- | dotfiles/common/.zshrc.d/aliases.sh | 50 |
2 files changed, 98 insertions, 2 deletions
diff --git a/dotfiles/common/.bashrc.d/aliases.sh b/dotfiles/common/.bashrc.d/aliases.sh index 1321bf0..6c5519f 100644 --- a/dotfiles/common/.bashrc.d/aliases.sh +++ b/dotfiles/common/.bashrc.d/aliases.sh @@ -80,7 +80,55 @@ alias gdbx="gdb --batch --ex r --ex bt --ex q --args" # ============================================================================= # Claude Code # ============================================================================= -alias hey='claude "Read docs/protocols.org and follow all instructions."' +# hey — launch Claude in the current directory (must be a .ai/ template project). +# If the repo has a remote and FETCH_HEAD is older than 10 minutes, fetches +# first so status info is accurate. Auto-pulls when clean, behind, and not +# ahead; warns for anything ambiguous. +hey() { + if [ ! -f .ai/protocols.org ]; then + echo "hey: no .ai/protocols.org in $(pwd) — not a Claude-template project" >&2 + return 1 + fi + + if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then + # Fetch upstream if FETCH_HEAD is stale (>10 min) or missing + local fetch_stale=1 gitdir age + gitdir=$(git rev-parse --git-dir 2>/dev/null) + if [ -f "$gitdir/FETCH_HEAD" ]; then + age=$(( $(date +%s) - $(stat -c %Y "$gitdir/FETCH_HEAD" 2>/dev/null || echo 0) )) + [ "$age" -lt 600 ] && fetch_stale=0 + fi + [ "$fetch_stale" -eq 1 ] && git fetch --quiet 2>/dev/null + + local upstream ahead=0 behind=0 dirty="" + upstream=$(git rev-parse --abbrev-ref --symbolic-full-name @{u} 2>/dev/null) + + if [ -n "$upstream" ]; then + ahead=$(git rev-list --count "$upstream..HEAD" 2>/dev/null || echo 0) + behind=$(git rev-list --count "HEAD..$upstream" 2>/dev/null || echo 0) + + if ! git diff --quiet 2>/dev/null \ + || ! git diff --cached --quiet 2>/dev/null \ + || [ -n "$(git ls-files --others --exclude-standard 2>/dev/null)" ]; then + dirty="dirty" + fi + + # Auto-pull if clean, behind, not ahead + if [ -z "$dirty" ] && [ "${ahead:-0}" -eq 0 ] && [ "${behind:-0}" -gt 0 ]; then + echo "hey: pulling $behind commit(s) from $upstream..." >&2 + git pull --ff-only --quiet + elif [ "${ahead:-0}" -gt 0 ] || [ "${behind:-0}" -gt 0 ] || [ -n "$dirty" ]; then + local parts=() + [ "${ahead:-0}" -gt 0 ] && parts+=("↑$ahead") + [ "${behind:-0}" -gt 0 ] && parts+=("↓$behind") + [ -n "$dirty" ] && parts+=("$dirty") + echo "hey: git ${parts[*]}" >&2 + fi + fi + fi + + claude "Read .ai/protocols.org and follow all instructions." +} # ============================================================================= # Phenomenology RAG (ollama/deepseek) diff --git a/dotfiles/common/.zshrc.d/aliases.sh b/dotfiles/common/.zshrc.d/aliases.sh index 1321bf0..6c5519f 100644 --- a/dotfiles/common/.zshrc.d/aliases.sh +++ b/dotfiles/common/.zshrc.d/aliases.sh @@ -80,7 +80,55 @@ alias gdbx="gdb --batch --ex r --ex bt --ex q --args" # ============================================================================= # Claude Code # ============================================================================= -alias hey='claude "Read docs/protocols.org and follow all instructions."' +# hey — launch Claude in the current directory (must be a .ai/ template project). +# If the repo has a remote and FETCH_HEAD is older than 10 minutes, fetches +# first so status info is accurate. Auto-pulls when clean, behind, and not +# ahead; warns for anything ambiguous. +hey() { + if [ ! -f .ai/protocols.org ]; then + echo "hey: no .ai/protocols.org in $(pwd) — not a Claude-template project" >&2 + return 1 + fi + + if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then + # Fetch upstream if FETCH_HEAD is stale (>10 min) or missing + local fetch_stale=1 gitdir age + gitdir=$(git rev-parse --git-dir 2>/dev/null) + if [ -f "$gitdir/FETCH_HEAD" ]; then + age=$(( $(date +%s) - $(stat -c %Y "$gitdir/FETCH_HEAD" 2>/dev/null || echo 0) )) + [ "$age" -lt 600 ] && fetch_stale=0 + fi + [ "$fetch_stale" -eq 1 ] && git fetch --quiet 2>/dev/null + + local upstream ahead=0 behind=0 dirty="" + upstream=$(git rev-parse --abbrev-ref --symbolic-full-name @{u} 2>/dev/null) + + if [ -n "$upstream" ]; then + ahead=$(git rev-list --count "$upstream..HEAD" 2>/dev/null || echo 0) + behind=$(git rev-list --count "HEAD..$upstream" 2>/dev/null || echo 0) + + if ! git diff --quiet 2>/dev/null \ + || ! git diff --cached --quiet 2>/dev/null \ + || [ -n "$(git ls-files --others --exclude-standard 2>/dev/null)" ]; then + dirty="dirty" + fi + + # Auto-pull if clean, behind, not ahead + if [ -z "$dirty" ] && [ "${ahead:-0}" -eq 0 ] && [ "${behind:-0}" -gt 0 ]; then + echo "hey: pulling $behind commit(s) from $upstream..." >&2 + git pull --ff-only --quiet + elif [ "${ahead:-0}" -gt 0 ] || [ "${behind:-0}" -gt 0 ] || [ -n "$dirty" ]; then + local parts=() + [ "${ahead:-0}" -gt 0 ] && parts+=("↑$ahead") + [ "${behind:-0}" -gt 0 ] && parts+=("↓$behind") + [ -n "$dirty" ] && parts+=("$dirty") + echo "hey: git ${parts[*]}" >&2 + fi + fi + fi + + claude "Read .ai/protocols.org and follow all instructions." +} # ============================================================================= # Phenomenology RAG (ollama/deepseek) |
