diff --git a/docs/Gemfile b/docs/Gemfile new file mode 100644 index 0000000..3310869 --- /dev/null +++ b/docs/Gemfile @@ -0,0 +1,4 @@ +source "https://rubygems.org" + +gem "github-pages", group: :jekyll_plugins +gem "jekyll-remote-theme" diff --git a/docs/_config.yml b/docs/_config.yml new file mode 100644 index 0000000..c2b4c86 --- /dev/null +++ b/docs/_config.yml @@ -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 — 1shooperman/cli-tools" diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..92eb530 --- /dev/null +++ b/docs/index.md @@ -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 | diff --git a/docs/installation.md b/docs/installation.md new file mode 100644 index 0000000..dc13fc9 --- /dev/null +++ b/docs/installation.md @@ -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 | diff --git a/docs/tools/cache-gpg.md b/docs/tools/cache-gpg.md new file mode 100644 index 0000000..758c847 --- /dev/null +++ b/docs/tools/cache-gpg.md @@ -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 | diff --git a/docs/tools/convert-video.md b/docs/tools/convert-video.md new file mode 100644 index 0000000..4790a36 --- /dev/null +++ b/docs/tools/convert-video.md @@ -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] +``` + +## 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` | diff --git a/docs/tools/gh-actions-sast.md b/docs/tools/gh-actions-sast.md new file mode 100644 index 0000000..c907c41 --- /dev/null +++ b/docs/tools/gh-actions-sast.md @@ -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/@v` — 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 diff --git a/docs/tools/gitprune.md b/docs/tools/gitprune.md new file mode 100644 index 0000000..104baf6 --- /dev/null +++ b/docs/tools/gitprune.md @@ -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 diff --git a/docs/tools/gitrefresh.md b/docs/tools/gitrefresh.md new file mode 100644 index 0000000..7262218 --- /dev/null +++ b/docs/tools/gitrefresh.md @@ -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. diff --git a/docs/tools/index.md b/docs/tools/index.md new file mode 100644 index 0000000..e10bf10 --- /dev/null +++ b/docs/tools/index.md @@ -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 | diff --git a/docs/tools/sast.md b/docs/tools/sast.md new file mode 100644 index 0000000..b21b515 --- /dev/null +++ b/docs/tools/sast.md @@ -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