MichaelDimmitt/scripts

★ 2Forks 0ShellGitHub ↗Compare

README

scripts

An operating system for shell automation on macOS. A growing collection of focused scripts for inspecting, reporting on, and generating configuration for your local environment.


File Naming Convention

Files follow a verb_noun.sh pattern in snake_case, grouped into folders by verb:

  • tell/ — scripts that display or report information
  • generate/ — scripts that produce or create output
  • install/ — scripts that set up tooling or wire up shell integrations
  • check/ — scripts that verify the repo's own conventions
  • bin/ — standalone executables (no verb prefix)

Examples

File Verb Purpose
tell/tell_ai_tools.sh tell Report installed SaaS AI tools
tell/tell_casks.sh tell Report installed Homebrew casks
tell/tell_rcs.sh tell Report shell RC files
tell/tell_skills.sh tell Report cloned skill repos under ~/skills
tell/tell_claude_skills.sh tell Snapshot Claude Code skill and plugin locations
tell/tell_installed_skills.sh tell List every installed SKILL.md skill (Claude + Cursor + Antigravity)
tell/tell_statusline.sh tell Explain every segment of the status line, one line each
tell/tell_statusline_antigravity.sh tell Explain every segment of the Antigravity status line, one line each
generate/generate_cask-aliases.sh generate Create shell aliases for casks
install/install_checkout_release.sh install Wire up latest_release without running the full generate script
install/install_statusline.sh install Copy the status line to ~/.claude, and repoint settings.json if it still runs an older copy
install/install_statusline_antigravity.sh install Copy the status line to ~/.gemini/antigravity-cli, and configure settings.json
install/install_prompt_skill.sh install Install the cross-platform /prompt skill to Claude Code and Antigravity CLI
install/install_aliases.sh install Install the hand-maintained shell aliases and source them from your shell RC
check/check_conventions.sh check Verify the installer contract, shebangs, exec bits, and library form
check/check_install.sh check Install into a throwaway $HOME and assert the aliases are live in a fresh shell
bin/latest_release — Checkout the highest versioned release branch

Rules

  • Use a verb prefix that describes what the script does (tell, generate, install, check)
  • Separate words with underscores (snake_case)
  • Use the .sh extension for all shell scripts
  • Place the script in the folder matching its verb

Usage

Requires just: brew install just

just                        # list all commands
just tell-ai-tools
just tell-casks
just tell-rcs
just tell-skills
just tell-claude-skills
just tell-installed-skills
just tell-statusline        # what each segment of the status line means
just tell-statusline-antigravity # what each segment of the Antigravity status line means
just generate-cask-aliases
just install-checkout-release
just install-statusline
just install-statusline-antigravity
just install-prompt-skill
just install-aliases
just install-all            # every install-* script in one pass
just check-conventions      # installer contract, shebangs, exec bits
just lint                   # check-conventions, then shellcheck every script
just check-install          # end-to-end: install to a throwaway HOME, assert aliases are live
just test-statusline        # run Claude Code status line test suite
just test-statusline-antigravity # run Antigravity status line test suite

Continuous integration

.github/workflows/checks.yml runs just lint and just check-install on macOS.

It is disabled on purpose. workflow_dispatch is its only trigger, so nothing runs on a push or a pull request — the file is there to be turned on when you want it, not to start gating merges today. You can still run it by hand from the repo's Actions tab to see it pass first.

To enable it, uncomment the two triggers at the top of the file:

on:
  workflow_dispatch:
  pull_request:
  push:
    branches: [master]

Docs

File Purpose
ARCHITECTURE.md Folder structure, naming conventions, how to add scripts and resources
AGENT_GUIDE.md Tips for agents navigating this repo and ~/skills efficiently
SKILLS_APPROACH.md Pros/cons of plugin vs direct ~/skills reference for Claude skills

Templates

Skeletons to copy when adding a script, rather than starting from a blank file.

File Purpose
install_template.sh Starting point for a new install/*.sh — sources the three shared libraries, shows the SKIP: already current branch beside the one that records a next step, and closes with next_steps_render
cp resources/templates/install_template.sh install/install_foo.sh
chmod +x install/install_foo.sh

The template encodes the installer contract, which just lint enforces — so a copy starts out passing.

Extras

Hand-maintained additions that layer on top of generated output.

File Purpose
brew-cask-aliases-additional Extra shell aliases to source alongside ~/.brew-cask-aliases
context-monitor.sh Claude Code Stop hook that warns when a session nears the autocompact threshold
context-monitor-setup.md Setup guide for the context monitor hook — thresholds, tuning, and how to test it
statusline-command.sh Claude Code status line script that mirrors a bash PS1 (cwd, short SHA, branch in cyan) and adds model, context window usage, and rate-limit percentages
statusline-setup.md Setup guide for the status line — includes a no-clone install path using curl
statusline-antigravity.sh Google Antigravity / Gemini CLI (agy) status line script (cwd, git branch, model, effort, ctx tokens, subagents, total USD)
statusline-antigravity-setup.md Setup guide for the Antigravity status line — includes standalone curl and settings.json instructions
statusline-tests/ Fixture-driven test suite for the status line scripts
stashes.sh Shell functions dump_stashes and dump_stashes_files for exporting a range of git stashes to a text file
text-manipulation.sh Shell utility functions for common text transformations

Source it from your RC file to keep these alongside the generated aliases:

source ~/scripts/resources/extras/brew-cask-aliases-additional

Or install the copy that generate_cask-aliases.sh uses:

just install-aliases

That copies the file to ~/.brew-cask-aliases-additional and sources it from your shell's interactive RC — .zshrc under zsh, .bashrc under bash. Re-run it after editing the aliases; it is idempotent, and it collapses the duplicate source lines older versions of the generate script left behind.

The installer runs as a child process, so it cannot change the alias table of the shell you launched it from. Until you re-source, alias cchats still reports the old definition and the install looks like it did nothing. Load it with:

source ~/.brew-cask-aliases-additional

Or just open a new terminal. Every installer here prints this reminder when it finishes.

Either path works, but pick one — a home-dir copy stops tracking the repo the moment this file changes.

just generate-cask-aliases (or regen-aliases) also refreshes this copy, since it delegates to the same installer. Use it when you have added or removed a Homebrew cask; use just install-aliases when you have only edited these aliases, as it skips the (slow) cask scan and needs no brew at all.

What's in brew-cask-aliases-additional

Name Type Purpose
cl alias Start a fresh Claude Code session with --dangerously-skip-permissions
cx alias Start a Codex session with --yolo (approval prompts bypassed)
cresume alias Resume the most recent Claude Code session with --dangerously-skip-permissions
cchats alias List previous Claude Code sessions for the current project (newest first)
cresumef <session-id> function Resume a specific Claude Code session by ID (IDs come from cchats) with permissions bypass
regen-aliases function Re-run generate_cask-aliases.sh and re-source both alias files in the current shell

Claude Code status line

See statusline-setup.md for the full setup guide, including a no-clone install path.

To install or update it:

just install-statusline

That copies the script to ~/.claude/, sets the executable bit (without it the status line silently does not appear), and checks that settings.json actually points at the copy with refreshInterval set.

Re-run it after every pull that touches the script. Claude Code runs the copy, not the repo file, so the two drift apart the moment this file changes — and a stale bar looks perfectly healthy, it just quietly lacks whatever was added since. The installer is idempotent and prints SKIP: already current when there is nothing to do, so it is safe to run habitually.

Alternatively, tell Claude:

Use the statusline-setup agent to configure my statusLine from ~/scripts/resources/extras/statusline-command.sh.

Or do it by hand:

cp ~/scripts/resources/extras/statusline-command.sh ~/.claude/statusline-command.sh
chmod +x ~/.claude/statusline-command.sh

Then add this to ~/.claude/settings.json:

{
  "statusLine": {
    "type": "command",
    "command": "bash /Users/<you>/.claude/statusline-command.sh",
    "refreshInterval": 30
  }
}

refreshInterval (seconds) keeps the rate-limit percentages current while the session sits idle — without it they freeze during long tool calls. See statusline-setup.md.

How it compares to the popular status lines

There is a sizeable ecosystem of Claude Code status lines, most of them larger than this one. The useful ones to know about:

Project Language Notes
ccstatusline TypeScript The category leader. Dozens of widgets, TUI configurator, Powerline themes. Runs via npx @latest per render.
claude-powerline TypeScript Vim-style powerline, installable from the plugin marketplace. Node 18+.
CCometixLine Rust Compiled binary — the fastest render in the field. Multiple themes.
claude-statusline-powerline TypeScript Superscript git symbols, tuned for Victor Mono.
ccusage statusline TypeScript Cost-focused: session / daily / block spend, burn rate. Own pricing engine.
kcchien/claude-code-statusline Bash Closest peer to this one — single jq call, gradient context bar, git status.
awesome-claude-statusline Bash Git Flow branch icons, ahead/behind sync status.

Feature comparison against this script:

This script ccstatusline ccusage kcchien
Context window % ✓ ✓ ✓ ✓
5h / 7d rate limits ✓ ✓ ✗ ✓
Session cost ✓ ✓ ✓ ✓
Per-command cost ✓ ✗ ✗ ✗
Git SHA + branch ✓ ✓ ✗ ✓
Width-aware path collapsing ✓ ✓ ✗ ✓
No runtime dependency beyond jq ✓ ✗ ✗ ✓
No network at render time ✓ ✗ ✗ ✓
Git dirty / staged / ahead-behind ✗ ✓ ✗ ✓
Per-model weekly limits ✗ ✓ ✗ ✗
Burn rate, block timers ✗ ✓ ✓ ✗
Lines added/removed, session duration ✗ ✓ ✗ ✓
Reasoning effort indicator ✗ ✓ ✓ ✗
Powerline / Nerd Font theming ✗ ✓ ✗ ✓
TUI configuration ✗ ✓ ✗ ✓

The tradeoff is deliberate. A survey of the ecosystem concluded that these tools are no longer differentiated by whether they can show model, context, git, and cost — everything does — but by how they install, what data they trust, and whether they do network or transcript work at render time. This script reads only the official stdin payload, forks two processes (jq and git), and degrades every field independently rather than failing the whole bar. The per-command cost segment is the one feature none of the popular ones have: the payload carries only a cumulative total, so this-command cost has to be Outstanding work, and how to pick it up, is tracked in ROADMAP.md.

Antigravity CLI status line

See statusline-antigravity-setup.md for the full setup guide, including a no-clone install path using curl.

To install or update it:

just install-statusline-antigravity

That copies the script to ~/.gemini/antigravity-cli/statusline-antigravity.sh, sets the executable bit, and configures ~/.gemini/antigravity-cli/settings.json with:

{
  "statusLine": {
    "command": "bash ~/.gemini/antigravity-cli/statusline-antigravity.sh",
    "stack_with_default": true
  }
}

Antigravity CLI status line layout:

dir: ~/scripts  (feat/antigravity-statusline*)  model: Gemini 3.8 Flash (high)  ctx 16k/1049k (1%)  weekly 6% (6d11h)  [2 agents]  +$0.02  $0.05 (sub:$0.02)

Antigravity tracks metrics specific to agy:

  • Subagents: Displays active/running background subagent count (e.g. [2 agents]).
  • Git VCS: Directly reads .vcs.branch and .vcs.dirty without extra subshells, falling back to local git when omitted.
  • Model Effort: Reads .model.effort alongside .model.display_name.
  • Token Context: Formatted as ctx <used>k/<size>k (<pct>%) with color-coded thresholds.
  • Model Quota: Displays weekly model quota usage and reset countdown (e.g. weekly 6% (6d11h) via .quota).
  • Cost: Total USD session spend with optional subagent cost breakdown and per-command cost delta (+$X.XX).

/prompt agent handoff skill

A cross-platform skill for Claude Code and Antigravity CLI (agy) that formulates structured handoff prompt files (AGENT_PROMPT_<TASK_NAME>.txt) in the project root with a mandatory self-cleanup directive.

To install or update it across all supported environments:

just install-prompt-skill

Copies resources/extras/skills/prompt/SKILL.md to:

  • Claude Code: ~/.claude/skills/prompt/SKILL.md
  • Antigravity CLI: ~/.gemini/antigravity-cli/skills/prompt/SKILL.md
  • Antigravity Config: ~/.gemini/config/skills/prompt/SKILL.md

Trigger inside Claude Code or Antigravity CLI:

/prompt <task description>

If invoked with empty arguments, the skill interactively prompts for task details, target files, and objectives before generating the handoff file.

Claude Code context monitor

A Stop hook that warns you as a session approaches autocompact, so you can wrap up deliberately instead of being compacted mid-task. See context-monitor-setup.md for thresholds and tuning.

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "bash ~/scripts/resources/extras/context-monitor.sh"
          }
        ]
      }
    ]
  }
}

Scripts

tell/tell_ai_tools.sh

Scans your machine for installed SaaS AI tools and reports what it finds, grouped by category. Prints a summary with found/not-found counts, then for every installed tool shows the command to launch it.

Detects:

  • Web interface desktop apps — Claude, ChatGPT, Gemini, Grok
  • AI-powered IDEs — Cursor, Windsurf, Zed
  • CLI / terminal agents — Claude Code, Aider, Codex, Gemini CLI, OpenCode, GitHub Copilot CLI
  • VS Code extensions — GitHub Copilot, Cline
  • Python SDKs — Anthropic, OpenAI, LangChain, Google GenAI
  • Node.js SDKs — Anthropic JS, OpenAI JS, LangChain JS

Requires: resources/mappings/ai_tools_launch.txt (included)

bash tell/tell_ai_tools.sh

tell/tell_casks.sh

Lists all installed Homebrew casks split into two groups: casks that expose a binary in /bin/ or /sbin/, and those that don't. Useful for auditing what CLI tools your GUI apps quietly ship.

bash tell/tell_casks.sh

tell/tell_rcs.sh

Detects your current shell and prints the relevant RC and profile files for it (e.g. ~/.zshrc, ~/.zprofile). Also shows which of those files actually exist on disk.

bash tell/tell_rcs.sh

tell/tell_skills.sh

Reports on git-cloned skill repos under ~/skills. Shows remote URL, current branch, last commit, whether the repo is up to date vs origin, and a list of available skills. Handles both a single repo at ~/skills/ and a directory of multiple repos.

If ~/skills doesn't exist, prompts you to clone anthropics/skills automatically.

bash tell/tell_skills.sh

tell/tell_claude_skills.sh

Snapshots all Claude Code skill and plugin locations to a dated file (~/claude-skills-<hostname>-<YYYYMMDD>.txt). Covers user skills (~/.claude/skills), installed plugins (~/.claude/plugins), nested plugin skill directories, and project-scoped skill directories under ~/.claude/projects.

bash tell/tell_claude_skills.sh

tell/tell_installed_skills.sh

Lists the name of every SKILL.md-based skill installed on the machine, grouped by source: Claude marketplace plugins, Claude global skills (~/.claude/skills), project-local .claude/skills directories, Cursor skills (~/.cursor/skills), and project-local .cursor/skills directories. Prints to stdout — use tell_claude_skills.sh instead when you want a dated file on disk.

bash tell/tell_installed_skills.sh

install/install_checkout_release.sh

Minimal installer that wires up latest_release without running the full generate_cask-aliases.sh. Copies bin/latest_release to ~/.local/bin, adds it to PATH in your shell's interactive RC — .zshrc under zsh, .bashrc under bash — registers the git checkout-release alias, and installs the git checkout release / git checkout release/ shell function intercept. Use this when you only want the release-checkout tooling on a new machine.

bash install/install_checkout_release.sh
source ~/.zshrc      # or ~/.bashrc under bash — the installer tells you which

install/install_prompt_skill.sh

Idempotent installer that installs or updates the /prompt skill definition across Claude Code and Antigravity CLI. Automatically manages target directories, creates .bak backups before modifying any existing differing files, and integrates with the shared next_steps.sh reporting protocol.

bash install/install_prompt_skill.sh

generate/generate_cask-aliases.sh

Generates shell aliases for every installed Homebrew cask (e.g. alias notion="open -a 'Notion'"), writes them to ~/.brew-cask-aliases, and sources that file from your shell's interactive RC — .zshrc under zsh, .bashrc under bash. Then delegates the hand-maintained companion file to install_aliases.sh, gathering both scripts' call-to-actions into one closing block. Re-run whenever you install or remove casks, or on a fresh clone; it is idempotent and reports when there was nothing to change.

Takes no options — --help prints usage and exits without touching anything.

bash generate/generate_cask-aliases.sh

bin/latest_release

Checks out the highest versioned release/X.Y.Z branch in the current repo. Fetches all remotes, filters to branches matching the release/#.##.## pattern, version-sorts them, and checks out the latest. Branches with non-version suffixes (e.g. release/vite-config-updates) are ignored.

Three ways to invoke:

latest_release                # direct (after install)
git checkout-release          # git alias
git checkout release          # shell function intercept (also matches release/; release/X.Y.Z passes through to git)

Install on a new machine:

# clone the repo, then:
bash install/install_checkout_release.sh
source ~/.zshrc      # or ~/.bashrc under bash — the installer tells you which

check/check_conventions.sh

Verifies the conventions a reviewer would otherwise have to catch by eye, reporting every violation in one pass and exiting non-zero if there are any. Run by just lint before shellcheck.

Checks:

  • Every install/*.sh (except the install_all.sh aggregator) sources resources/lib/next_steps.sh and calls next_steps_render
  • No installer prints its own source ~/... call to action — that is what next_step is for
  • Every tracked file has a shebang if and only if it is executable (resources/templates/ excepted: a template carries the shebang its copy will need without being runnable itself)
  • resources/lib/*.sh are non-executable, shebang-free, and carry # shellcheck shell=bash

See The installer contract for the rules and why they are enforced rather than documented.

just check-conventions

check/check_install.sh

End-to-end check that an install actually produces working aliases. Runs install_all.sh against a throwaway $HOME, then starts a fresh interactive shell and asks it whether each alias and function is defined. Reports pass/fail counts and exits non-zero on any failure.

Everything else in this repo is checked statically — shellcheck reads the scripts, check_conventions.sh reads their shape, tell_aliases.sh greps the RC files for a source line. None of that can tell you an alias works, only that a line exists somewhere.

Why a separate shell: an installer runs as a child process and can never change the alias table of the shell that launched it, so liveness is only observable from a shell started after the install. And aliases are not expanded in non-interactive shells — zsh -c 'type cchats' reports "not found" on a perfectly good install — so every probe uses -ic.

Asserts, per shell (zsh and bash):

  • The install wrote the RC file, and it sources the alias file exactly once
  • Every alias and name() {} in brew-cask-aliases-additional is defined in a fresh interactive shell (the list is parsed from the file, so it can't drift)
  • The git() wrapper resolves to a shell function, not the plain binary
  • latest_release is on PATH
  • A second run is a no-op — the property the next_steps.sh design exists to produce
  • An unsupported shell (fish) gets no RC file written at all

Nothing touches the real $HOME: HOME and GIT_CONFIG_GLOBAL are both redirected into a temp root that is removed on exit. That second one matters — install_checkout_release.sh runs git config --global.

Not part of just lint, which is static and fast; this runs three installers per shell. Run it before merging anything that touches install/.

just check-install

Contributors

MichaelDimmitt

Issues