Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
source "https://rubygems.org"

gem "github-pages", group: :jekyll_plugins
gem "jekyll-remote-theme"
18 changes: 18 additions & 0 deletions docs/_config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
title: cli-tools
description: Personal shell utilities for git hygiene, GPG, video conversion, and Claude plugin static analysis.
remote_theme: just-the-docs/just-the-docs@v0.10.1
url: https://1shooperman.github.io
baseurl: /cli-tools

# Nav order for top-level pages
nav_order_default: 1

plugins:
- jekyll-remote-theme

# Just the Docs config
search_enabled: true
heading_anchors: true
color_scheme: dark

footer_content: "MIT License &mdash; <a href=\"https://github.com/1shooperman/cli-tools\">1shooperman/cli-tools</a>"
31 changes: 31 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
layout: home
title: Home
nav_order: 1
---

# cli-tools

Personal shell utilities for git branch hygiene, GPG cache warming, video conversion, and Claude plugin static analysis.

## Quick install

```sh
brew tap 1shooperman/tap
brew install cli-tools
```

All commands are placed on your `$PATH` automatically. See [Installation](installation) for manual setup and dependencies.

---

## Tools at a glance

| Command | What it does |
|---------|-------------|
| [`gitprune`](tools/gitprune) | Deletes stale local branches and compacts the repo |
| [`gitrefresh`](tools/gitrefresh) | Resets to a clean, up-to-date state against any branch |
| [`cache-gpg`](tools/cache-gpg) | Warms the GPG agent cache before a signing flow |
| [`convert-video`](tools/convert-video) | Converts any video file to H.264/AAC MP4 via ffmpeg |
| [`sast`](tools/sast) | Static analysis for Claude plugin `allowed-tools` frontmatter |
| [`gh-actions-sast`](tools/gh-actions-sast) | Checks GitHub Actions workflows for outdated action pins |
41 changes: 41 additions & 0 deletions docs/installation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
---
layout: default
title: Installation
nav_order: 2
---

# Installation

## Homebrew (recommended)

```sh
brew tap 1shooperman/tap
brew install cli-tools
```

All commands are placed on your `$PATH` automatically.

---

## Manual

Clone the repo and add `bin/` to your `$PATH`:

```sh
git clone https://github.com/1shooperman/cli-tools.git
export PATH="$PATH:/path/to/cli-tools/bin"
```

Add the `export` line to your shell rc file (`.zshrc`, `.bashrc`, etc.) to persist it across sessions.

---

## Dependencies

Some commands require external tools. Install only what you need:

| Tool | Required by | Install |
|------|-------------|---------|
| `ffmpeg` | `convert-video` | `brew install ffmpeg` |
| `gpg` | `cache-gpg` | `brew install gnupg` |
| `git` | `gitprune`, `gitrefresh` | ships with macOS |
33 changes: 33 additions & 0 deletions docs/tools/cache-gpg.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
layout: default
title: cache-gpg
parent: Tools
nav_order: 3
---

# cache-gpg

Warms the GPG agent cache by performing a throwaway clearsign operation.

## Usage

```sh
cache-gpg
```

No arguments. No output on success.

## Why

`git commit -S` prompts for your GPG passphrase when the agent cache is cold. Running `cache-gpg` before your commit flow pre-unlocks the key so the signing step doesn't interrupt with a passphrase prompt.

## What it does

Pipes the string `"test"` through `gpg --clearsign` and discards the output. That is enough to unlock the key and populate the agent cache for the configured cache TTL.

## Requirements

| Requirement | Install |
|-------------|---------|
| `gpg` installed and a signing key configured | `brew install gnupg` |
| GPG agent running | started automatically by `gpg` on modern systems |
47 changes: 47 additions & 0 deletions docs/tools/convert-video.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
layout: default
title: convert-video
parent: Tools
nav_order: 4
---

# convert-video

Converts a video file to H.264/AAC MP4 using ffmpeg.

## Usage

```sh
convert-video [--silent] <input-file>
```

## Arguments

| Argument | Description |
|----------|-------------|
| `input-file` | Path to the source video file (any format ffmpeg can read) |
| `--silent` | Suppress ffmpeg output |

## Examples

```sh
convert-video recording.mov # → recording.mp4
convert-video --silent clip.avi # → clip.mp4, no output
```

Output is written to the same directory as the input with the extension replaced by `.mp4`.

## Encoding settings

| Stream | Codec | Settings |
|--------|-------|----------|
| Video | `libx264` | CRF 23, `medium` preset |
| Audio | `aac` | 128k bitrate |

CRF 23 is the ffmpeg default and gives a good quality/size balance for most content.

## Requirements

| Requirement | Install |
|-------------|---------|
| `ffmpeg` | `brew install ffmpeg` |
48 changes: 48 additions & 0 deletions docs/tools/gh-actions-sast.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
---
layout: default
title: gh-actions-sast
parent: Tools
nav_order: 6
---

# gh-actions-sast

Scans GitHub Actions workflow files for action references pinned below a minimum version.

## Usage

```sh
gh-actions-sast
```

Must be run from the repository root. Scans `.github/workflows/*.yml` automatically — no arguments needed.

## What it does

Walks every `.yml` file under `.github/workflows/` and checks each `uses:` line for `actions/*@vN` references. Any action pinned below `v6` is flagged.

## Output

| Severity | Condition |
|----------|-----------|
| ERROR | Action version is below `v6` |
| WARN | Action is below `v6` but present in the exclude list |

```
ERROR ci.yml: actions/checkout@v4 is below v6
WARN ci.yml: actions/some-action@v3 is below v6 (excluded)
```

## Exit codes

| Code | Meaning |
|------|---------|
| `0` | No ERROR findings |
| `1` | One or more ERROR findings |

## Notes

- Only matches the pattern `actions/<name>@v<number>` — SHA-pinned or tag-pinned refs are not checked
- Passes cleanly when `.github/workflows/` does not exist
- Non-`.yml` files in `.github/workflows/` are skipped
- Pairs with [`sast`](sast) for broader CI security coverage
39 changes: 39 additions & 0 deletions docs/tools/gitprune.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
---
layout: default
title: gitprune
parent: Tools
nav_order: 1
---

# gitprune

Deletes local git branches that no longer exist on the remote, then runs garbage collection and prunes stale remote-tracking refs.

## Usage

```sh
gitprune # safe delete
gitprune --force # force delete unmerged branches too
```

## Flags

| Flag | Behavior |
|------|----------|
| _(none)_ | Uses `git branch -d` — refuses to delete unmerged branches |
| `--force` | Uses `git branch -D` — deletes unmerged branches regardless |

## What it does

1. Lists remote branches
2. Compares against local tracking branches
3. Deletes any local branch with no matching remote
4. Runs `git gc --prune=now` and `git fetch -p` to clean up stale refs
5. Runs `git gc` again for a final compaction

Output from gc and fetch is collapsed into a single overwriting status line so it doesn't flood your terminal.

## Notes

- Safe to run frequently — without `--force` it will never delete a branch with unmerged commits
- `gitrefresh` calls `gitprune --force` automatically at the end of its flow
36 changes: 36 additions & 0 deletions docs/tools/gitrefresh.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
layout: default
title: gitrefresh
parent: Tools
nav_order: 2
---

# gitrefresh

Resets a local clone to a clean, up-to-date state against any branch, then prunes stale local branches.

## Usage

```sh
gitrefresh # resets to main
gitrefresh dev # resets to dev
```

## Arguments

| Argument | Default | Description |
|----------|---------|-------------|
| `branch` | `main` | Branch to check out and pull |

## What it does

1. Checks out `branch`
2. Fetches from origin
3. Pulls latest
4. Runs `gitprune --force` **twice** — the second pass catches branches whose delete tracking refs were only cleaned up by the first pass

All git output is collapsed into a single overwriting status line.

## Notes

`gitrefresh` is a "nuke and reset" convenience — it force-prunes unmerged branches. Use plain `gitprune` if you want to keep unmerged work.
19 changes: 19 additions & 0 deletions docs/tools/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
layout: default
title: Tools
nav_order: 3
has_children: true
---

# Tools

cli-tools provides six commands covering git hygiene, GPG, video conversion, and static analysis.

| Command | Summary |
|---------|---------|
| [gitprune](gitprune) | Delete stale local branches and compact the repo |
| [gitrefresh](gitrefresh) | Reset to a clean, up-to-date state |
| [cache-gpg](cache-gpg) | Warm the GPG agent cache |
| [convert-video](convert-video) | Convert video to H.264/AAC MP4 |
| [sast](sast) | Scan Claude plugin frontmatter for risky tool grants |
| [gh-actions-sast](gh-actions-sast) | Check GitHub Actions for outdated action pins |
56 changes: 56 additions & 0 deletions docs/tools/sast.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
---
layout: default
title: sast
parent: Tools
nav_order: 5
---

# sast

Static analysis for Claude plugin markdown files. Scans `allowed-tools` declarations in YAML frontmatter for risky tool grants.

## Usage

```sh
sast # scans ./plugins
sast /path/to/plugins # scans a specific directory
```

## Arguments

| Argument | Default | Description |
|----------|---------|-------------|
| `plugins-dir` | `./plugins` (relative to CWD) | Directory to scan for `.md` files |

## Checks

| Severity | Pattern | Why it matters |
|----------|---------|----------------|
| ERROR | Bare `Bash` | Grants unrestricted shell access to any command |
| ERROR | `Bash(*)` | Wildcard constraint is effectively unrestricted |
| ERROR | `[*]`, `Agent(*)`, `Skill(*)` | Grants access to all tools or agents |
| WARN | Bare `WebFetch` | Allows fetching any domain without restriction |

Only `allowed-tools` lines within the first YAML frontmatter block (between the opening and closing `---`) are checked. Occurrences in the body are ignored.

## Exit codes

| Code | Meaning |
|------|---------|
| `0` | No ERROR findings (WARN-only still exits 0) |
| `1` | One or more ERROR findings |

## Example output

```
[ERROR] plugins/my-agent/agent.md: bare 'Bash' grants unrestricted shell access
[WARN] plugins/my-agent/agent.md: bare 'WebFetch' allows fetching any domain

SAST complete. Findings: 2
```

## Notes

- Designed to run in CI against a checked-out repo, or locally from a project root
- Exits 0 cleanly when `plugins-dir` does not exist (0 findings)
- Pairs with [`gh-actions-sast`](gh-actions-sast) for broader CI security coverage