scut

module
v0.5.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 1, 2026 License: MIT

README

scut

Release Pull Request Go Version

CLI tool for LLM agents. Provides a consistent interface for agent authors to interact with tools, the environment, and each other via hooks, rules, and instructions.

Installation

curl -fsSL https://install-scut.ajbeck.dev | sh

By default, the installer downloads the latest GitHub Release for your platform, verifies checksums.txt, and installs scut to ~/.local/bin.

Install a specific version or destination:

curl -fsSL https://install-scut.ajbeck.dev | sh -s -- --version v0.1.0 --bin-dir /usr/local/bin

Go users can also install from source:

go install github.com/ajbeck/scut@latest

Or build locally:

./walle build

The binary is written to bin/scut.

See Installation for release assets, supported platforms, and install-script behavior.

Hooks

scut implements Claude Code hooks as subcommands under scut claude hook <event>. Claude Code invokes these as subprocesses, piping JSON to stdin and reading JSON from stdout.

PostToolUse — Auto-formatting

The post-tool-use hook automatically formats files after Claude's Write or Edit tool calls. It dispatches by file extension:

Extension Formatter Notes
.go gofmt (via go/format) Files with syntax errors are left unchanged
.md, .mdx goldmark-prettier-markdown Preserves prose wrapping style

Files with other extensions are passed through unchanged.

Configuration

Wire supported agents with the unified setup command:

scut init                         # detected agents, project scope
scut init --all --dry-run          # preview setup targets
scut init --all --dry-run --verbose # preview rendered config
scut init --codex --scope=user     # explicitly set up Codex user hooks
scut init --all --bake-log-level=debug

Agent-specific commands remain available when you need lower-level control:

scut claude config install              # project scope: .claude/settings.json
scut claude config install --scope=user # user scope: ~/.claude/settings.json
scut claude config install --dry-run    # preview without writing
scut codex config install               # project scope: .codex/hooks.json

Claude setup installs entries for all 29 hook events plus the status line, merging non-destructively with any existing settings.json. Codex setup defaults to the post-tool-use formatter hook in hooks.json; use --only on scut codex config install to opt into additional Codex hook events. In project scope, scut init auto-detects agents only when .claude/ or .codex/ exists; pass --all, --claude, or --codex to force setup. See the Usage docs and CLI reference for flags, merge semantics, and the uninstall / status subcommands.

Check an installation without changing files:

scut doctor                  # check Claude Code + Codex across project/user scopes
scut doctor --codex --json    # machine-readable Codex diagnostics

scut doctor reports ok, info, warn, and error findings for PATH setup, parse errors, missing scut hook entries, Codex inline hook conflicts, disabled Codex hooks, and project trust reminders. See Doctor for the diagnostics model.

For reference, this is the PostToolUse entry the command writes:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "scut claude hook post-tool-use",
            "statusMessage": "Formatting..."
          }
        ]
      }
    ]
  }
}

Fields:

  • matcher — filters which tool calls trigger the hook. "Write|Edit" matches either tool.
  • type — handler type. Currently only "command" is supported.
  • command — the CLI command Claude Code executes as a subprocess. Claude Code pipes the tool use event as JSON to stdin and reads the hook's JSON response from stdout.
  • statusMessage — optional label shown in Claude Code's status line while the hook runs.
How it works
  1. Claude writes or edits a file using the Write or Edit tool.
  2. Claude Code fires a PostToolUse event and pipes the event payload (including tool_name, tool_input with file_path, and tool_response) to the hook's stdin.
  3. scut claude hook post-tool-use extracts the file path, checks the extension, and runs the appropriate formatter.
  4. The formatted content is written back to the file in place. The hook returns an empty JSON response — formatting is silent and transparent to the agent.
Exit codes
Code Meaning
0 Success. stdout is parsed as the hook's JSON response.
2 Blocking error. stderr is surfaced as an error message to the agent.
Other Non-blocking error. Logged but execution continues.
Other hook events

scut has subcommands wired for all 29 Claude Code hook events and all 10 documented Codex command-hook events (e.g. session-start, pre-tool-use, user-prompt-submit, stop, etc.). Most non-formatting hooks currently deserialize input and return empty or placeholder responses. See the Claude Code hooks documentation and Codex hooks documentation for the full event references.

scut claude hook --help
scut codex hook --help

Status Line

scut claude status-line renders a persistent status bar at the bottom of the Claude Code terminal. It displays context window usage, model label, current path, git branch with dirty/ahead-behind indicators — all computed in-process with zero subprocess overhead.

████████████████│███ 50% | O4.6 | scut/internal/cmd | getting-started ✓ ↑1
Segment Description
Context bar 20-character progress bar with half-block resolution (38 levels). A red marker sits at 83% — the auto-compaction threshold. Mint <70%, amber 70–82%, red 83%+.
Model Abbreviated model label (e.g., S4.5, O4.6-1M)
Path Current directory relative to the git repo root (or ~/relative outside a repo). Long paths are compacted by collapsing intermediate segments.
Branch Current git branch from HEAD, truncated to 20 characters
Git indicators when clean, +N staged (mint), ~N unstaged/untracked (amber), ↑N ahead (mint), ↓N behind (amber)
Configuration

The status line is wired by scut claude config install alongside the hooks. The entry it writes:

{
  "statusLine": {
    "type": "command",
    "command": "scut claude status-line"
  }
}

To install only the status line without the hooks, pass --only=status-line:

scut claude config install --only=status-line

See Configure Claude Code for the full surface.

Performance

The status line fires after each assistant message (debounced at 300ms), when permission mode changes, or when vim mode toggles. scut is designed for this frequency:

  • No subprocesses: git branch and worktree status are computed via go-git (pure Go), not by forking git.
  • Single repo open: the .git directory is opened once per invocation and shared across all queries.
  • Concurrent collection: path resolution, git status, ahead/behind counts, and context bar rendering run in parallel goroutines.
  • Styled via lipgloss: ANSI escape codes are generated in-process using charmbracelet/lipgloss.

Logging

Enable structured JSONL logging for hook commands and the status line with the --log flag:

scut claude --log hook post-tool-use        # warn level (default)
scut claude --log-level=debug status-line   # debug level (implies --log)

Log files are written to ~/.scut/logging/ with date-partitioned filenames:

~/.scut/logging/
  20260403_post-tool-use.jsonl
  20260403_status-line.jsonl

Each line is a JSON object with standardized fields: time, level, msg, hook, session_id, duration_ms, plus hook-specific attributes.

To bake logging into the installed hook commands, pass --log (or --log-level=LEVEL) when installing:

scut claude config install --log
scut claude config install --log-level=debug

The generated command in settings.json becomes scut claude --log hook post-tool-use (or --log-level=debug).

Cleanup

Remove old log files with scut logging clean:

scut logging clean              # remove files older than 7 days (default)
scut logging clean --days 30    # remove files older than 30 days
scut logging clean --all        # remove all log files

Contributing

See CONTRIBUTING.md for development commands and pull request expectations.

Security

Report security issues privately. See SECURITY.md.

License

scut is released under the MIT License.

Directories

Path Synopsis
cmd
scut command
The scut command is a CLI tool for managing AI coding assistants.
The scut command is a CLI tool for managing AI coding assistants.
walle command
The walle command is scut's repository-local task runner.
The walle command is scut's repository-local task runner.
hooks
claudecode
Package claudecode provides types for Claude Code hook inputs and outputs.
Package claudecode provides types for Claude Code hook inputs and outputs.
codex
Package codex provides types for Codex hook inputs and outputs.
Package codex provides types for Codex hook inputs and outputs.
internal
cmd/claude
Package claude implements the "claude" agent command group.
Package claude implements the "claude" agent command group.
cmd/claude/config
Package config implements the "scut claude config" command group.
Package config implements the "scut claude config" command group.
cmd/claude/hook
Package hook implements the "claude hook" subcommand tree.
Package hook implements the "claude hook" subcommand tree.
cmd/codex
Package codex implements the "codex" agent command group.
Package codex implements the "codex" agent command group.
cmd/codex/config
Package config implements the "scut codex config" command group.
Package config implements the "scut codex config" command group.
cmd/codex/hook
Package hook implements the "codex hook" subcommand tree.
Package hook implements the "codex hook" subcommand tree.
cmd/doctor
Package doctor implements the "scut doctor" diagnostics command.
Package doctor implements the "scut doctor" diagnostics command.
cmd/format
Package format implements the "format" command group.
Package format implements the "format" command group.
cmd/gotools
Package gotools implements Go tool-inspired commands.
Package gotools implements Go tool-inspired commands.
cmd/logging
Package logging implements the "logging" command group.
Package logging implements the "logging" command group.
cmd/mcp
Package mcp implements MCP utility commands.
Package mcp implements MCP utility commands.
cmd/update
Package update implements the "scut update" command.
Package update implements the "scut update" command.
cmd/version
Package version implements the "version" command.
Package version implements the "version" command.
format
Package format provides code formatting utilities.
Package format provides code formatting utilities.
formatignore
Package formatignore matches formatter ignore files against paths.
Package formatignore matches formatter ignore files against paths.
godoc
Package godoc parses, resolves, and formats Go documentation.
Package godoc parses, resolves, and formats Go documentation.
logging
Package logging provides structured JSONL logging for scut commands.
Package logging provides structured JSONL logging for scut commands.
version
Package version provides build and version metadata for scut.
Package version provides build and version metadata for scut.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL