FO

format-bash-source

Format Bash scripts to match the repository's official style guide.

Install

mkdir -p .claude/skills/format-bash-source && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/19080" && unzip -o skill.zip -d .claude/skills/format-bash-source && rm skill.zip

Installs to .claude/skills/format-bash-source

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

Format Bash (*.sh) files to match .claude/CODE_STYLE.md, the repository's source of truth for shell style. Use when the user asks to format, fix, or apply the code style to shell scripts. Runs in two modes — with no arguments it formats every *.sh file modified locally on the current branch (both committed on branch and not yet committed changes); with file or folder paths as arguments it formats those targets instead.
422 chars✓ has a “when” triggerlonger than Claude Code's old 250-char listing cap (fine on current versions)
Intermediate

Key capabilities

  • Reformat Bash scripts to comply with a style guide
  • Apply style rules from `.claude/CODE_STYLE.md`
  • Format all locally modified `.sh` files on the current branch
  • Format specified `.sh` files or all `.sh` files within a folder
  • Preserve script behavior, logic, and output during formatting
  • Report formatted files and skipped paths

How it works

This skill reads the `.claude/CODE_STYLE.md` document to understand the authoritative style rules and then applies those rules to target Bash script files, either locally modified ones or explicitly provided paths.

Inputs & outputs

You give it
Bash script files (*.sh) or directories containing them
You get back
Formatted Bash script files and a summary report of changes

When to use format-bash-source

  • Formatting shell scripts
  • Enforcing project code styles
  • Cleaning up bash code

About this skill

Format Bash Source

Reformat Bash scripts so they comply with .claude/CODE_STYLE.md, the authoritative style guide for every *.sh file in this repository.

Load the Style Guide

Read .claude/CODE_STYLE.md in full before touching any file. It is the single source of truth; every rule you apply must come from it. Do not invent rules or rely on generic Bash conventions that the document does not state. If the document and a file disagree, the document wins.

Resolve the Target Files

There are two modes. Pick the mode from whether arguments were provided.

Default Mode (No Arguments)

Format every *.sh file modified locally on the current branch — both the changes already committed on the branch (relative to master) and the changes not yet committed. Collect them with:

{
	git diff --name-only --diff-filter=ACMR master...HEAD
	git diff --name-only --diff-filter=ACMR
	git diff --name-only --cached --diff-filter=ACMR
	git ls-files --others --exclude-standard
} | sort --unique | grep '\.sh$'

This covers commits made on the branch (versus master), unstaged changes, staged changes, and new untracked scripts. If the branch's base is not master, substitute the correct base branch. If the list is empty, report that there are no locally modified *.sh files and stop.

Argument Mode (Paths Provided)

When the skill is invoked with arguments, treat each argument as a file or a folder:

  • A path ending in .sh is formatted directly.

  • A folder is expanded to every *.sh file under it:

    find "${path}" -type f -name '*.sh'
    
  • Ignore arguments that resolve to no *.sh files, but report each one that was skipped so the user knows.

The arguments passed to this skill are: ${ARGUMENTS}

Format Each File

For every target file, read it and apply the rules from .claude/CODE_STYLE.md using Edit. Make only style changes — never alter the script's behavior, logic, or output. The checks to enforce include (this is a reminder, not a replacement for reading the document):

  • File layout: shebang, blank line, sorted source block, blank line, function definitions, single trailing main invocation, no blank last line; _-prefix for internal files.
  • Functions: function name form (no ()), snake_case, verb prefixes, _-prefix for local functions, globals declared before locals.
  • Variables: UPPER_SNAKE_CASE for globals/env, lower_snake_case for locals (_UPPER when shared across local functions), local declarations, no spaces around =, always braced and quoted ("${var}"), the whole parameter quoted when a variable is adjacent to literal text ("release.${name}.pom", not release."${name}".pom; literal kept outside quotes only for a glob or for a Git URL/ref/refspec/tag passed to git), locals declared close to first use rather than batched at the top, the enumerated Bash-specific parameter expansions (${var##*/}, ${var%/*}, ${var##*:}, ${var%.*}, ${var#prefix}, ${var/a/b}) rewritten to the legible equivalents listed in CODE_STYLE.md (every other expansion left unchanged), $((...)) arithmetic with no inner spaces, $(...) over backticks, a single command substitution, parameter expansion, or arithmetic expansion left unquoted when it is the entire right-hand side of a bare x=, local x=, export x=, readonly x=, or declare x= assignment, no trailing ; at the end of a $( ... ).
  • Sorting: source lines, function definitions, and same-location local variable declarations sorted case-sensitively (../ before ./). This is mechanical, not a judgment call — apply it even when the current order looks like a deliberate "template" and even when it means moving whole function bodies. Functions sort alphabetically with globals before locals and main in its alphabetical position (it is not pinned first or last); reordering definitions never changes behavior, since execution order comes from the calls in main, not the definition order.
  • Commands: awk parameters wrapped in "" (the field separator counts as a parameter — rewrite the attached -F= / -Fx forms to -F "=" / -F "x") and awk instructions in '', sed regex expressions in "" (even when they contain $) with the program always passed via --expression, never as a bare positional argument (sed --expression "s/a/b/", not sed "s/a/b/") — this applies to standalone single-script sed and to sed nested in a command substitution; long form of flags preferred (e.g. xargs --null, not xargs -0); flags ordered alphabetically whether inline or broken, except order-dependent ones (find primaries, repeated sed --expression, sed's --regexp-extended, which must precede --expression, and zip's -i/-x include/exclude filters, which trail the input file list they act on rather than sorting in with the other flags); commands with three or more flags (e.g. curl) broken one argument per line with positionals last (e.g. sed --expression "..." --in-place file), except a command whose syntax pins the operand first (find's path) — an option and its value count as one flag, positionals do not count, ≤2 flags stay inline, and the break applies even inside if / if ! conditions; put a space between a redirection operator and its target (&> /dev/null, not &>/dev/null), but 2>&1, >&2, and <(...) / >(...) stay attached.
  • Control flow: then (including after elif) and do on their own line, single-bracket [ ... ] tests by default but [[ ... ]] for pattern/regex matching, ${BASH_SOURCE[0]} comparisons, lexicographic </> string comparisons, and numeric comparisons (-eq, -ge, etc.) — but a numeric comparison whose operator is held in a variable ([ "${a}" "${operator}" "${b}" ]) stays single-bracket, since [[ ... ]] needs a literal operator — == for strings, aligned multiline conditions, no parentheses around a single boolean function, variable, command, or pipeline (parentheses only for combined conditions, with (( )) arithmetic and awk/jq program if (...) left untouched).
  • Indentation/spacing: tabs only, single blank line between logical statements, no blank line just inside { / }.
  • Pipelines: long pipelines and curl-style commands broken across lines with | \ continuations indented one tab; a space after $( when a pipeline or command is broken inside a command substitution.
  • Return codes: named LIFERAY_COMMON_EXIT_CODE_* constants, quoted (but boolean functions return bare 0/1).
  • Comments / shared helpers: #-delimited comment blocks, lc_* helpers over reimplementation. Do not convert between echo and lc_log — that choice is semantic and is left to the author, not the formatter.

Skip .claude/CODE_STYLE.md itself and any non-*.sh file.

Verify Idempotency

The formatter must be idempotent: a second run on an unchanged tree must produce zero edits. To guarantee this:

  • Only edit code that strictly violates a rule you can cite by name. Never replace one compliant form with another equally-compliant form.
  • After editing a file, rescan it. If a second pass would make any further change, either make it now or recognize that the triggering rule is too subjective to auto-apply — and leave the code alone.
  • The "too subjective" exception is narrow: it covers only rules that genuinely require judgment, never deterministic ones. Sorting (source lines, function definitions, local declarations), bracket choice, quoting, and the enumerated parameter-expansion rewrites are all mechanical and must always be applied — do not skip them because the change is large (e.g. moving a function body) or because the existing order resembles an intentional layout.

Verification Sweep

Reading each file is the primary check, but it is easy to miss a class of violation across many files — especially when the work is split across several passes or subagents that may apply a rule unevenly. After editing, rescan the target files with these greps and confirm every remaining hit is intentional. Each is a deterministic rule, so a hit is either a real violation to fix now or an explainable exception (and never both):

# Parenthesized conditions — every hit must be a combined (&& / ||) condition, a
# `(( ))` arithmetic evaluation, or awk/jq program syntax; a single command,
# pipeline, function, or variable wrapped in ( ) is a violation.
grep -nE '\b(if|elif|while) +!? *\(' "${files[@]}"

# Quoted single-expansion scalar RHS — `local x="${1}"` / `x="$(...)"` / `x="$((...))"`
# must be unquoted; this includes export/readonly/declare assignments.
grep -nE '^[[:space:]]*(local |export |readonly |declare (-[A-Za-z]+ )?)?[A-Za-z_][A-Za-z0-9_]*="(\$\{[A-Za-z0-9_@#?]+\}|\$\(\([^"]*\)\)|\$\([^")]*\))"[[:space:]]*$' "${files[@]}"

# A variable adjacent to a literal path must be quoted as one parameter
# (`"${dir}/file"`, not `"${dir}"/file`). Every hit must be a glob (`"${dir}"/*.zip`)
# or a git URL/ref — otherwise merge the quotes.
grep -nE '"\$\{[A-Za-z0-9_]+\}"/' "${files[@]}"

# sed program passed as a bare positional instead of via --expression.
grep -nE "\bsed( +--[a-z-]+(=[^ ]+)?)* +['\"]" "${files[@]}" | grep -v -- '--expression'

# sed's --regexp-extended must precede --expression (a later one leaves an
# extended-regex script parsed as basic, breaking `(`, `|`, `+`, `\1`).
grep -nE '\bsed\b.*--expression.*--regexp-extended' "${files[@]}"

# Inline `; then` / `; do`, backticks, and attached awk `-F`.
grep -nE '; *(then|do)\b' "${files[@]}"
grep -nE '[^\\]`|^`' "${files[@]}"
grep -nE "awk[^|]*-F[^ \"']" "${files[@]}"

# Enumerated parameter expansions that must be rewritten.
grep -nE '\$\{[A-Za-z0-9_]+(##\*[/:]|%/\*|%\.\*|/[^}]+/[^}]*)\}' "${files[@]}"

# A command broken across lines inside `$( ... )` must use the split opening
# `$( \` with the command on the next line, never attached as `$(command \`.
grep -nE '\$\([a-z]+ \\$' "$

---

*Content truncated.*

When not to use it

  • When the user wants to invent new style rules not in CODE_STYLE.md
  • When the user wants to alter script behavior during formatting
  • When the user wants to apply generic Bash conventions not specified in the document

Limitations

  • Formatting must only apply style changes, not alter script behavior
  • Rules must strictly come from `.claude/CODE_STYLE.md`
  • The skill does not invent rules or rely on generic Bash conventions

How it compares

This workflow enforces a specific, documented code style for Bash scripts, preventing manual style inconsistencies that can arise from individual preferences or generic conventions.

Compared to similar skills

format-bash-source side by side with the closest alternatives in the catalog.

SkillInstallsUpdatedSafetyDifficulty
format-bash-source (this skill)014dReviewIntermediate
webapp-testing3533moReviewIntermediate
resolve-conflicts818moReviewIntermediate
telegram-bot-builder1066moReviewIntermediate

Try saying

Example prompts that trigger this skill in your AI assistant.

You might also like

webapp-testing

anthropics

Toolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing browser screenshots, and viewing browser logs.

353585

resolve-conflicts

antinomyhq

Use this skill immediately when the user mentions merge conflicts that need to be resolved. Do not attempt to resolve conflicts directly - invoke this skill first. This skill specializes in providing a structured framework for merging imports, tests, lock files (regeneration), configuration files, and handling deleted-but-modified files with backup and analysis.

81334

telegram-bot-builder

davila7

Expert in building Telegram bots that solve real problems - from simple automation to complex AI-powered bots. Covers bot architecture, the Telegram Bot API, user experience, monetization strategies, and scaling bots to thousands of users. Use when: telegram bot, bot api, telegram automation, chat bot telegram, tg bot.

106130

dev-browser

SawyerHood

Browser automation with persistent page state. Use when users ask to navigate websites, fill forms, take screenshots, extract web data, test web apps, or automate browser workflows. Trigger phrases include "go to [url]", "click on", "fill out the form", "take a screenshot", "scrape", "automate", "test the website", "log into", or any browser interaction request.

53176

openspec-onboard

studyzy

Guided onboarding for OpenSpec - walk through a complete workflow cycle with narration and real codebase work.

10207

codex-cli-bridge

alirezarezvani

Bridge between Claude Code and OpenAI Codex CLI - generates AGENTS.md from CLAUDE.md, provides Codex CLI execution helpers, and enables seamless interoperability between both tools

9180

Search skills

Search the agent skills registry