Skip to content

feat(statusline): add custom statusline script to dot_claude - #892

Merged
yxtay merged 5 commits into
mainfrom
feat/statusline-script
Jul 14, 2026
Merged

feat(statusline): add custom statusline script to dot_claude#892
yxtay merged 5 commits into
mainfrom
feat/statusline-script

Conversation

@yxtay

@yxtay yxtay commented Jul 14, 2026

Copy link
Copy Markdown
Owner

Summary

  • Add chezmoi/private_dot_claude/executable_statusline-command.sh — displays cwd, git branch/changes, model, context tokens/%, session cost, and caveman badge
  • Update claude-settings.json template to point statusLine.command at ~/.claude/statusline-command.sh (replaces old hooks/caveman-statusline.sh reference)

Test plan

  • Run chezmoi apply and confirm ~/.claude/statusline-command.sh exists and is executable
  • Open Claude Code and verify statusline shows all segments

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Enhanced the terminal status line to display a two-line plain-text summary including working directory, Git branch and change markers, model name, effort, context usage, total cost, and execution duration (only when available).
  • Bug Fixes
    • Updated the status line configuration to use the new status line command/script.
    • Removed prior ANSI color/staged/unstaged and extra “CAVEMAN” status logic from the output.

Shows cwd, git branch/changes, model, context tokens/%, cost, caveman badge.
Updates settings template to point to new statusline-command.sh.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@yxtay, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 53 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: bde9cf4d-2b50-4d80-b9be-f6683ca02ba2

📥 Commits

Reviewing files that changed from the base of the PR and between df934b2 and dd1a91a.

📒 Files selected for processing (1)
  • chezmoi/private_dot_claude/executable_statusline-command.sh
📝 Walkthrough

Walkthrough

A Bash statusline renderer now reads Claude session JSON, formats model, usage, cost, duration, directory, and Git details as two plain-text lines, and is wired into the Claude settings template.

Changes

Claude statusline

Layer / File(s) Summary
Statusline renderer and activation
chezmoi/.chezmoitemplates/claude-settings.json, chezmoi/private_dot_claude/executable_statusline-command.sh
The Claude command now invokes the new script, which renders conditional session metrics and Git state without ANSI colors or Caveman flag logic.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

Poem

A rabbit reads the JSON stream,
And prints two lines of shell-script dream.
Paths and branches hop in view,
Costs and context numbers too—
Plain-text carrots, fresh and clean!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main change: adding a custom statusline script for dot_claude.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/statusline-script

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

MegaLinter analysis: Success

Descriptor Linter Files Fixed Errors Warnings Elapsed time
✅ BASH shfmt 5 0 0 0 0.02s
✅ JSON prettier 8 0 0 0 0.54s
✅ MARKDOWN markdownlint 9 0 0 0 0.73s
✅ MARKDOWN markdown-table-formatter 11 0 0 0 0.15s
✅ YAML prettier 11 0 0 0 0.48s

Notices

📣 MegaLinter 9.5.0 is out! Discover the new features and security recommendations in the release announcement. (Skip this info by defining SECURITY_SUGGESTIONS: false)

See detailed reports in MegaLinter artifacts

Your project could benefit from a custom flavor, which would allow you to run only the linters you need, and thus improve runtime performances. (Skip this info by defining FLAVOR_SUGGESTIONS: false)

  • Documentation: Custom Flavors
  • Command: npx mega-linter-runner@9.6.0 --custom-flavor-setup --custom-flavor-linters BASH_SHFMT,JSON_PRETTIER,MARKDOWN_MARKDOWNLINT,MARKDOWN_MARKDOWN_TABLE_FORMATTER,YAML_PRETTIER

MegaLinter is graciously provided by OX Security
Show us your support by starring ⭐ the repository

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the Claude status line configuration and introduces a new bash script (statusline-command.sh) to display status information such as the current directory, git status, model, context window usage, cost, and a caveman badge. The review feedback identifies a performance issue due to multiple jq invocations, a logic bug with operator precedence in the Git check when the directory is empty, and robustness concerns. A refactored script is suggested to address these issues.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +8 to +52
cwd=$(echo "$input" | jq -r '.cwd // .workspace.current_dir // empty')
if [ -n "$cwd" ]; then
# Collapse $HOME to ~
short_cwd="${cwd/#$HOME/~}"
printf '\033[34m%s\033[0m' "$short_cwd"
fi

# --- Git branch + changes ---
if [ -n "$cwd" ] && [ -d "$cwd/.git" ] || git -C "$cwd" rev-parse --git-dir >/dev/null 2>&1; then
branch=$(git -C "$cwd" symbolic-ref --short HEAD 2>/dev/null ||
git -C "$cwd" rev-parse --short HEAD 2>/dev/null)
if [ -n "$branch" ]; then
printf ' \033[32m(%s)\033[0m' "$branch"
# Count staged + unstaged changes (skip untracked for brevity)
changes=$(git -C "$cwd" status --porcelain 2>/dev/null | grep -c '^')
if [ "$changes" -gt 0 ] 2>/dev/null; then
printf ' \033[33m*%s\033[0m' "$changes"
fi
fi
fi

# --- Model ---
model=$(echo "$input" | jq -r '.model.display_name // empty')
if [ -n "$model" ]; then
printf ' \033[36m[%s]\033[0m' "$model"
fi

# --- Context: tokens used + percentage ---
total_input=$(echo "$input" | jq -r '.context_window.total_input_tokens // empty')
ctx_size=$(echo "$input" | jq -r '.context_window.context_window_size // empty')
used_pct=$(echo "$input" | jq -r '.context_window.used_percentage // empty')

if [ -n "$total_input" ] && [ -n "$ctx_size" ] && [ "$ctx_size" -gt 0 ] 2>/dev/null; then
printf ' \033[35m%sk/%sk' "$((total_input / 1000))" "$((ctx_size / 1000))"
if [ -n "$used_pct" ]; then
printf ' (%.0f%%)' "$used_pct"
fi
printf '\033[0m'
fi

# --- Cost ---
cost=$(echo "$input" | jq -r '.cost.total_cost_usd // empty')
if [ -n "$cost" ] && [ "$cost" != "0" ]; then
printf ' \033[33m$%.4f\033[0m' "$cost"
fi

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Performance & Logic Improvements

  1. Performance (Process Spawning): The current script invokes jq 6 separate times to parse fields from the JSON input. Since statusline scripts run frequently, spawning multiple processes can introduce noticeable latency (especially on macOS/Windows). We can optimize this by parsing all required fields in a single jq invocation using @sh formatting and eval.
  2. Logic Bug (Operator Precedence): In the Git check, && and || have equal precedence in Bash and are evaluated left-to-right. Therefore, [ -n "$cwd" ] && [ -d "$cwd/.git" ] || git -C "$cwd" ... evaluates as ([ -n "$cwd" ] && [ -d "$cwd/.git" ]) || git -C "$cwd" .... If $cwd is empty, the left side is false, which forces the right side (git -C "" ...) to execute. This is a bug that runs git with an empty directory argument. Grouping the conditions with { ... ; } fixes this.
  3. Robustness: Using optional chaining (?.) in jq prevents potential errors if any parent objects (like model or context_window) are null or missing.
eval "$(echo "$input" | jq -r '
  "cwd=\\(.cwd // .workspace?.current_dir // "" | @sh)
model=\\(.model?.display_name // "" | @sh)
total_input=\\(.context_window?.total_input_tokens // "" | @sh)
ctx_size=\\(.context_window?.context_window_size // "" | @sh)
used_pct=\\(.context_window?.used_percentage // "" | @sh)
cost=\\(.cost?.total_cost_usd // "" | @sh)"'
)"

# --- Directory ---
if [ -n "$cwd" ]; then
  # Collapse $HOME to ~
  short_cwd="${cwd/#$HOME/~}"
  printf '\\033[34m%s\\033[0m' "$short_cwd"
fi

# --- Git branch + changes ---
if [ -n "$cwd" ] && { [ -d "$cwd/.git" ] || git -C "$cwd" rev-parse --git-dir >/dev/null 2>&1; }; then
  branch=$(git -C "$cwd" symbolic-ref --short HEAD 2>/dev/null ||
    git -C "$cwd" rev-parse --short HEAD 2>/dev/null)
  if [ -n "$branch" ]; then
    printf ' \\033[32m(%s)\\033[0m' "$branch"
    # Count staged + unstaged changes (skip untracked for brevity)
    changes=$(git -C "$cwd" status --porcelain 2>/dev/null | grep -c '^')
    if [ "$changes" -gt 0 ]; then
      printf ' \\033[33m*%s\\033[0m' "$changes"
    fi
  fi
fi

# --- Model ---
if [ -n "$model" ]; then
  printf ' \\033[36m[%s]\\033[0m' "$model"
fi

# --- Context: tokens used + percentage ---
if [ -n "$total_input" ] && [ -n "$ctx_size" ] && [ "$ctx_size" -gt 0 ] 2>/dev/null; then
  printf ' \\033[35m%sk/%sk' "$((total_input / 1000))" "$((ctx_size / 1000))"
  if [ -n "$used_pct" ]; then
    printf ' (%.0f%%)' "$used_pct"
  fi
  printf '\\033[0m'
fi

# --- Cost ---
if [ -n "$cost" ] && [ "$cost" != "0" ]; then
  printf ' \\033[33m$%.4f\\033[0m' "$cost"
fi

@github-actions

github-actions Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

⚠️MegaLinter analysis: Success with warnings

Descriptor Linter Files Fixed Errors Warnings Elapsed time
✅ ACTION actionlint 5 0 0 0.27s
✅ ACTION zizmor 5 0 0 0 0.94s
⚠️ BASH bash-exec 5 1 0 0.02s
✅ BASH shellcheck 5 0 0 0.15s
✅ BASH shfmt 5 0 0 0 0.01s
✅ COPYPASTE jscpd yes no no 0.14s
✅ EDITORCONFIG editorconfig-checker 85 0 0 0.16s
✅ JSON prettier 8 0 0 0 0.46s
✅ JSON v8r 12 0 0 3.78s
✅ MARKDOWN markdownlint 9 0 0 0 0.86s
✅ MARKDOWN markdown-table-formatter 11 0 0 0 0.21s
✅ REPOSITORY betterleaks yes no no 2.91s
✅ REPOSITORY checkov yes no no 27.12s
✅ REPOSITORY gitleaks yes no no 1.73s
✅ REPOSITORY git_diff yes no no 0.01s
✅ REPOSITORY grype yes no no 52.23s
✅ REPOSITORY osv-scanner yes no no 0.2s
✅ REPOSITORY secretlint yes no no 1.38s
✅ REPOSITORY syft yes no no 3.29s
✅ REPOSITORY trivy yes no no 13.93s
✅ REPOSITORY trivy-sbom yes no no 0.21s
✅ REPOSITORY trufflehog yes no no 4.67s
⚠️ SPELL lychee 35 10 0 1.12s
✅ YAML prettier 11 0 0 0 0.64s
✅ YAML v8r 11 0 0 7.95s
✅ YAML yamllint 11 0 0 0.53s

Detailed Issues

⚠️ BASH / bash-exec - 1 error
Results of bash-exec linter (version 5.3.9)
See documentation on https://megalinter.io/9.6.0/descriptors/bash_bash_exec/
-----------------------------------------------

✅ [SUCCESS] bin/cleanup-all.sh
✅ [SUCCESS] bin/update-all.sh
❌ [ERROR] chezmoi/private_dot_claude/executable_statusline-command.sh
    Error: File:[chezmoi/private_dot_claude/executable_statusline-command.sh] is not executable

✅ [SUCCESS] install.sh
✅ [SUCCESS] plugins/okf-wiki/hooks/okf-wiki-maintenance.sh
⚠️ SPELL / lychee - 10 errors
📝 Summary
---------------------
🔍 Total...........33
🔗 Unique..........25
✅ Successful......23
⏳ Timeouts.........0
🔀 Redirected.......4
👻 Excluded.........0
❓ Unknown..........0
🚫 Errors..........10
⛔ Unsupported.....10

Errors in chezmoi/.chezmoitemplates/mcp_servers.json
[406] https://mcp.deepwiki.com/mcp (at 11:15) | Rejected status code: 406 Not Acceptable

Errors in chezmoi/.chezmoitemplates/opencode.json
[406] https://mcp.deepwiki.com/mcp (at 32:15) | Rejected status code: 406 Not Acceptable

Errors in chezmoi/private_dot_agents/skills/okf/templates/concept.md
[ERROR] file://chezmoi/private_dot_agents/skills/okf/templates/url (at 24:5) | File not found. Check if file exists and path is correct

Errors in chezmoi/private_dot_agents/skills/okf/templates/index.md
[ERROR] file://chezmoi/private_dot_agents/skills/okf/templates/relative-url (at 3:3) | File not found. Check if file exists and path is correct
[ERROR] file://chezmoi/private_dot_agents/skills/okf/templates/relative-url (at 4:3) | File not found. Check if file exists and path is correct
[ERROR] file://chezmoi/private_dot_agents/skills/okf/templates/subdir (at 8:3) | File not found. Check if file exists and path is correct

Errors in chezmoi/private_dot_agents/skills/okf/templates/log.md
[ERROR] file://chezmoi/private_dot_agents/skills/okf/templates/bundle-relative-path (at 5:36) | File not found. Check if file exists and path is correct
[ERROR] file://chezmoi/private_dot_agents/skills/okf/templates/bundle-relative-path (at 6:30) | File not found. Check if file exists and path is correct
[ERROR] file://chezmoi/private_dot_agents/skills/okf/templates/bundle-relative-path (at 7:39) | File not found. Check if file exists and path is correct

Errors in plugins/.claude-plugin/marketplace.json
[404] https://anthropic.com/claude-code/marketplace.schema.json (at 2:15) | Rejected status code: 404 Not Found | Followed 1 redirect. Redirects: https://anthropic.com/claude-code/marketplace.schema.json --[301]--> https://www.anthropic.com/claude-code/marketplace.schema.json

Hint: Followed 4 redirects. You might want to consider replacing redirecting URLs with the resolved URLs. Use verbose mode (`-v`/`-vv`) to see redirection details.
Hint: You can configure accepted/rejected response codes with `-a` or `--accept`

Notices

📣 MegaLinter 9.5.0 is out! Discover the new features and security recommendations in the release announcement. (Skip this info by defining SECURITY_SUGGESTIONS: false)

See detailed reports in MegaLinter artifacts

Your project could benefit from a custom flavor, which would allow you to run only the linters you need, and thus improve runtime performances. (Skip this info by defining FLAVOR_SUGGESTIONS: false)

  • Documentation: Custom Flavors
  • Command: npx mega-linter-runner@9.6.0 --custom-flavor-setup --custom-flavor-linters ACTION_ACTIONLINT,ACTION_ZIZMOR,BASH_EXEC,BASH_SHELLCHECK,BASH_SHFMT,COPYPASTE_JSCPD,EDITORCONFIG_EDITORCONFIG_CHECKER,JSON_V8R,JSON_PRETTIER,MARKDOWN_MARKDOWNLINT,MARKDOWN_MARKDOWN_TABLE_FORMATTER,REPOSITORY_CHECKOV,REPOSITORY_GIT_DIFF,REPOSITORY_GITLEAKS,REPOSITORY_BETTERLEAKS,REPOSITORY_GRYPE,REPOSITORY_OSV_SCANNER,REPOSITORY_SECRETLINT,REPOSITORY_SYFT,REPOSITORY_TRIVY,REPOSITORY_TRIVY_SBOM,REPOSITORY_TRUFFLEHOG,SPELL_LYCHEE,YAML_PRETTIER,YAML_YAMLLINT,YAML_V8R

MegaLinter is graciously provided by OX Security
Show us your support by starring ⭐ the repository

@github-actions

github-actions Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

⚠️MegaLinter analysis: Success with warnings

Descriptor Linter Files Fixed Errors Warnings Elapsed time
⚠️ BASH bash-exec 5 1 0 0.02s
✅ BASH shellcheck 5 0 0 0.17s
✅ REPOSITORY betterleaks yes no no 2.28s
✅ REPOSITORY checkov yes no no 24.26s
✅ REPOSITORY devskim yes no no 2.16s
✅ REPOSITORY dustilock yes no no 0.02s
✅ REPOSITORY gitleaks yes no no 1.41s
✅ REPOSITORY grype yes no no 49.87s
✅ REPOSITORY kingfisher yes no no 11.73s
✅ REPOSITORY osv-scanner yes no no 0.12s
✅ REPOSITORY secretlint yes no no 1.87s
✅ REPOSITORY syft yes no no 1.79s
✅ REPOSITORY trivy yes no no 11.85s
✅ REPOSITORY trivy-sbom yes no no 0.17s
✅ REPOSITORY trufflehog yes no no 4.15s

Detailed Issues

⚠️ BASH / bash-exec - 1 error
Results of bash-exec linter (version 5.3.9)
See documentation on https://megalinter.io/9.6.0/descriptors/bash_bash_exec/
-----------------------------------------------

✅ [SUCCESS] bin/cleanup-all.sh
✅ [SUCCESS] bin/update-all.sh
❌ [ERROR] chezmoi/private_dot_claude/executable_statusline-command.sh
    Error: File:[chezmoi/private_dot_claude/executable_statusline-command.sh] is not executable

✅ [SUCCESS] install.sh
✅ [SUCCESS] plugins/okf-wiki/hooks/okf-wiki-maintenance.sh

Notices

📣 MegaLinter 9.5.0 is out! Discover the new features and security recommendations in the release announcement. (Skip this info by defining SECURITY_SUGGESTIONS: false)

See detailed reports in MegaLinter artifacts

Your project could benefit from a custom flavor, which would allow you to run only the linters you need, and thus improve runtime performances. (Skip this info by defining FLAVOR_SUGGESTIONS: false)

  • Documentation: Custom Flavors
  • Command: npx mega-linter-runner@9.6.0 --custom-flavor-setup --custom-flavor-linters BASH_EXEC,BASH_SHELLCHECK,REPOSITORY_CHECKOV,REPOSITORY_DEVSKIM,REPOSITORY_DUSTILOCK,REPOSITORY_GITLEAKS,REPOSITORY_BETTERLEAKS,REPOSITORY_GRYPE,REPOSITORY_OSV_SCANNER,REPOSITORY_SECRETLINT,REPOSITORY_SYFT,REPOSITORY_TRIVY,REPOSITORY_TRIVY_SBOM,REPOSITORY_TRUFFLEHOG,REPOSITORY_KINGFISHER

MegaLinter is graciously provided by OX Security
Show us your support by starring ⭐ the repository

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
chezmoi/private_dot_claude/executable_statusline-command.sh (1)

8-8: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Prevent echo from misinterpreting JSON input.

If $input happens to start with -n, -e, or contains backslashes, echo can mangle the string or interpret it as an option. In Bash, it's safer and more idiomatic to use a here-string (<<<) or printf '%s\n'.

Please apply this pattern to all echo "$input" | jq invocations in this file.

♻️ Proposed fix
-cwd=$(echo "$input" | jq -r '.cwd // .workspace.current_dir // empty')
+cwd=$(jq -r '.cwd // .workspace.current_dir // empty' <<< "$input")
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@chezmoi/private_dot_claude/executable_statusline-command.sh` at line 8,
Replace every echo "$input" | jq invocation in the statusline script with a safe
printf '%s\n' "$input" | jq or here-string equivalent, preserving each command’s
existing jq filter and behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@chezmoi/private_dot_claude/executable_statusline-command.sh`:
- Line 16: Update the condition in the statusline command to group the non-empty
cwd check with both Git-directory checks, ensuring neither filesystem nor git
validation runs when cwd is empty. Preserve the existing behavior for valid cwd
values and resolve ShellCheck SC2015.
- Around line 50-52: Set LC_NUMERIC=C for the script, or apply it directly to
both printf calls formatting used_pct and cost, including the formatter in the
shown cost block. Preserve the existing output formatting while ensuring JSON
numeric values with dot decimal separators are parsed consistently in
non-English locales.

---

Nitpick comments:
In `@chezmoi/private_dot_claude/executable_statusline-command.sh`:
- Line 8: Replace every echo "$input" | jq invocation in the statusline script
with a safe printf '%s\n' "$input" | jq or here-string equivalent, preserving
each command’s existing jq filter and behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: ffc550a8-a75d-463c-9ba1-66283af39ae3

📥 Commits

Reviewing files that changed from the base of the PR and between 5b1802e and c86becb.

📒 Files selected for processing (2)
  • chezmoi/.chezmoitemplates/claude-settings.json
  • chezmoi/private_dot_claude/executable_statusline-command.sh

Comment thread chezmoi/private_dot_claude/executable_statusline-command.sh Outdated
Comment on lines +50 to +52
if [ -n "$cost" ] && [ "$cost" != "0" ]; then
printf ' \033[33m$%.4f\033[0m' "$cost"
fi

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Prevent printf float conversion errors in non-English locales.

Bash printf's %f formatter respects the system's locale. Because JSON (and thus jq output) always uses a dot (.) as the decimal separator, running this script in a locale that uses a comma (e.g., de_DE, fr_FR) will cause printf to fail with an invalid number error for floats like 0.015.

To fix this, prefix printf with LC_NUMERIC=C here and on line 43 (used_pct), or export LC_NUMERIC=C at the top of the script.

🐛 Proposed fix
 if [ -n "$cost" ] && [ "$cost" != "0" ]; then
-  printf ' \033[33m$%.4f\033[0m' "$cost"
+  LC_NUMERIC=C printf ' \033[33m$%.4f\033[0m' "$cost"
 fi
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if [ -n "$cost" ] && [ "$cost" != "0" ]; then
printf ' \033[33m$%.4f\033[0m' "$cost"
fi
if [ -n "$cost" ] && [ "$cost" != "0" ]; then
LC_NUMERIC=C printf ' \033[33m$%.4f\033[0m' "$cost"
fi
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@chezmoi/private_dot_claude/executable_statusline-command.sh` around lines 50
- 52, Set LC_NUMERIC=C for the script, or apply it directly to both printf calls
formatting used_pct and cost, including the formatter in the shown cost block.
Preserve the existing output formatting while ensuring JSON numeric values with
dot decimal separators are parsed consistently in non-English locales.

- Line 1: model, effort level, context tokens, cost, session duration
- Line 2: directory (~-collapsed), branch with p10k colors and +\!?~ markers
- Remove caveman badge and rate limit; add session duration (Xh Ym)

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added size/L and removed size/M labels Jul 14, 2026
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added size/M and removed size/L labels Jul 14, 2026
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
chezmoi/private_dot_claude/executable_statusline-command.sh (1)

21-23: ⚠️ Potential issue | 🟠 Major

Prevent printf float conversion errors in non-English locales.

Bash printf's %f formatter respects the system's locale. Because JSON (and thus jq output) always uses a dot (.) as the decimal separator, running this script in a locale that uses a comma (e.g., de_DE, fr_FR) will cause printf to fail with an invalid number error for floats like 0.015.

To fix this, prefix printf with LC_NUMERIC=C.

🐛 Proposed fix
-  line1="${line1:+$line1 | }$(printf '$%.4f' "$cost")"
+  line1="${line1:+$line1 | }$(LC_NUMERIC=C printf '$%.4f' "$cost")"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@chezmoi/private_dot_claude/executable_statusline-command.sh` around lines 21
- 23, Update the printf invocation in the cost-formatting branch to run with
LC_NUMERIC=C, ensuring dot-decimal JSON values are accepted consistently across
locales while preserving the existing four-decimal currency output.
🧹 Nitpick comments (3)
chezmoi/private_dot_claude/executable_statusline-command.sh (3)

55-55: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Quote the variable length expansion to satisfy ShellCheck.

As per coding guidelines to apply ShellCheck to bash scripts, SC2086 recommends quoting variables to prevent word splitting, even for numeric length expansions.

🤖 Proposed fix
-    [ ${`#branch`} -gt 32 ] && branch="${branch:0:12}..${branch: -12}"
+    [ "${`#branch`}" -gt 32 ] && branch="${branch:0:12}..${branch: -12}"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@chezmoi/private_dot_claude/executable_statusline-command.sh` at line 55,
Quote the branch length expansion in the conditional within the status-line
script to satisfy ShellCheck SC2086, while preserving the existing truncation
behavior when the branch length exceeds 32 characters.

Source: Coding guidelines


58-61: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low value

Prefer here-strings (<<<) over piping to grep.

Piping from printf spawns an extra sub-process for each grep check. Using bash's here-string (<<<) avoids this overhead, which is beneficial for a statusline script that executes frequently.

⚡ Proposed refactor
-    printf '%s' "$git_status" | grep -q '^[MADRC]' && markers="${markers}+"
-    printf '%s' "$git_status" | grep -q '^.[MD]' && markers="${markers}!"
-    printf '%s' "$git_status" | grep -q '^??' && markers="${markers}?"
-    printf '%s' "$git_status" | grep -qE '^(UU|AA|DD)' && markers="${markers}~"
+    grep -q '^[MADRC]' <<< "$git_status" && markers="${markers}+"
+    grep -q '^.[MD]' <<< "$git_status" && markers="${markers}!"
+    grep -q '^??' <<< "$git_status" && markers="${markers}?"
+    grep -qE '^(UU|AA|DD)' <<< "$git_status" && markers="${markers}~"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@chezmoi/private_dot_claude/executable_statusline-command.sh` around lines 58
- 61, Replace the four printf-to-grep pipelines in the marker-building logic
with bash here-string redirections using the existing git_status value,
preserving each grep pattern and the resulting markers updates.

8-15: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Consolidate jq calls to improve performance.

The script invokes jq 7 separate times to parse the same JSON input. Since jq has a startup overhead, this adds noticeable latency to every statusline render.

You can extract all variables in a single jq pass using @tsv and read, which avoids this overhead and significantly improves responsiveness.

⚡ Proposed refactor

Replace the individual jq variable assignments at the top of the script with a single invocation:

IFS=$'\t' read -r model effort total_input ctx_size cost dur_ms cwd <<< "$(echo "$input" | jq -r '
  [
    (.model.display_name // ""),
    (.effort.level // ""),
    (.context_window.total_input_tokens // ""),
    (.context_window.context_window_size // ""),
    (.cost.total_cost_usd // ""),
    (.cost.total_duration_ms // ""),
    (.cwd // .workspace.current_dir // "")
  ] | `@tsv`
')"

(Note: Be sure to remove the cwd=$(...) assignment on line 42 as well if you apply this!)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@chezmoi/private_dot_claude/executable_statusline-command.sh` around lines 8 -
15, Consolidate the JSON extraction in statusline-command.sh into one jq
invocation that emits model, effort, total_input, ctx_size, cost, dur_ms, and
cwd as TSV, then populate them with read. Remove all separate jq assignments,
including the later cwd assignment, while preserving the existing variable names
and downstream behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In `@chezmoi/private_dot_claude/executable_statusline-command.sh`:
- Around line 21-23: Update the printf invocation in the cost-formatting branch
to run with LC_NUMERIC=C, ensuring dot-decimal JSON values are accepted
consistently across locales while preserving the existing four-decimal currency
output.

---

Nitpick comments:
In `@chezmoi/private_dot_claude/executable_statusline-command.sh`:
- Line 55: Quote the branch length expansion in the conditional within the
status-line script to satisfy ShellCheck SC2086, while preserving the existing
truncation behavior when the branch length exceeds 32 characters.
- Around line 58-61: Replace the four printf-to-grep pipelines in the
marker-building logic with bash here-string redirections using the existing
git_status value, preserving each grep pattern and the resulting markers
updates.
- Around line 8-15: Consolidate the JSON extraction in statusline-command.sh
into one jq invocation that emits model, effort, total_input, ctx_size, cost,
dur_ms, and cwd as TSV, then populate them with read. Remove all separate jq
assignments, including the later cwd assignment, while preserving the existing
variable names and downstream behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 93e7f661-9547-4f0a-b35f-4f6dc4698229

📥 Commits

Reviewing files that changed from the base of the PR and between c86becb and df934b2.

📒 Files selected for processing (1)
  • chezmoi/private_dot_claude/executable_statusline-command.sh

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
@yxtay
yxtay merged commit bc2797d into main Jul 14, 2026
18 of 20 checks passed
@yxtay
yxtay deleted the feat/statusline-script branch July 14, 2026 05:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant