Skip to content

Commit cc6ba71

Browse files
authored
chore(FR-2708): add git safety indicator to Claude Code statusline (#6982)
1 parent 256a070 commit cc6ba71

1 file changed

Lines changed: 50 additions & 3 deletions

File tree

.claude/scripts/statusline.sh

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,10 +118,18 @@ if [[ -n "$WORKSPACE" ]]; then
118118
fi
119119

120120
# Fallback output when there is no Jira/Teams context:
121-
# line 1 = VS Code link (if available), line 2 = model/tokens.
121+
# line 1 = worktree info + VS Code link (if available), line 2 = model/tokens.
122122
emit_fallback() {
123+
local line1=""
124+
if [[ -n "${WORKTREE_PART:-}" ]]; then
125+
line1+="$WORKTREE_PART"
126+
fi
123127
if [[ -n "$VSCODE_PART" ]]; then
124-
printf '%b\n%b' "$VSCODE_PART" "$MODEL_PART"
128+
[[ -n "$line1" ]] && line1+=" "
129+
line1+="$VSCODE_PART"
130+
fi
131+
if [[ -n "$line1" ]]; then
132+
printf '%b\n%b' "$line1" "$MODEL_PART"
125133
else
126134
printf '%b' "$MODEL_PART"
127135
fi
@@ -133,6 +141,40 @@ if [[ -z "$WORKSPACE" ]]; then
133141
exit 0
134142
fi
135143

144+
# ── Worktree & git safety indicator ──────────────────────
145+
# Detects: worktree name, uncommitted changes, unpushed commits
146+
# Output: WORKTREE_PART = colored string for status line
147+
WORKTREE_PART=""
148+
if [[ -n "$WORKSPACE" ]] && git -C "$WORKSPACE" rev-parse --git-dir >/dev/null 2>&1; then
149+
# Safety check: uncommitted changes or unpushed commits
150+
WT_DIRTY=0
151+
WT_DETAIL=""
152+
if ! git -C "$WORKSPACE" diff-index --quiet HEAD -- 2>/dev/null; then
153+
WT_DIRTY=1
154+
WT_DETAIL="uncommitted"
155+
elif [[ -n "$(git -C "$WORKSPACE" ls-files --others --exclude-standard 2>/dev/null | head -1)" ]]; then
156+
WT_DIRTY=1
157+
WT_DETAIL="untracked"
158+
fi
159+
160+
WT_UNPUSHED=0
161+
if git -C "$WORKSPACE" rev-parse '@{u}' >/dev/null 2>&1; then
162+
WT_UNPUSHED=$(git -C "$WORKSPACE" rev-list --count '@{u}..HEAD' 2>/dev/null) || WT_UNPUSHED=0
163+
fi
164+
165+
# Build indicator
166+
if (( WT_DIRTY )); then
167+
WT_ICON="\033[91m⚠ ${WT_DETAIL}\033[0m" # red
168+
elif (( WT_UNPUSHED > 0 )); then
169+
WT_ICON="\033[93m↑${WT_UNPUSHED}\033[0m" # yellow
170+
else
171+
WT_ICON="\033[32m✓\033[0m" # green = safe to delete
172+
fi
173+
174+
# Compose: safety indicator only (✓/⚠/↑N)
175+
WORKTREE_PART="$WT_ICON"
176+
fi
177+
136178
# ── Extract branch and repo info ──────────────────────────
137179
BRANCH=$(git -C "$WORKSPACE" rev-parse --abbrev-ref HEAD 2>/dev/null) || { emit_fallback; exit 0; }
138180
JIRA_KEY=$(echo "$BRANCH" | grep -oiE 'fr-[0-9]+' | head -1 | tr '[:lower:]' '[:upper:]') || true
@@ -198,9 +240,14 @@ except Exception:
198240

199241
IFS=$'\t' read -r JIRA_SUMMARY JIRA_STATUS TEAMS_URL <<< "$PARSED"
200242

201-
# ── Line 1: Links (VS Code + Teams + Jira) ───────────────
243+
# ── Line 1: Worktree + Links (VS Code + Teams + Jira) ────
202244
LINE1=""
203245

246+
if [[ -n "$WORKTREE_PART" ]]; then
247+
LINE1+="$WORKTREE_PART"
248+
LINE1+=" "
249+
fi
250+
204251
if [[ -n "$VSCODE_PART" ]]; then
205252
LINE1+="$VSCODE_PART"
206253
LINE1+=" "

0 commit comments

Comments
 (0)