aibris

command module
v0.12.2 Latest Latest
Warning

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

Go to latest
Published: Sep 21, 2026 License: MIT Imports: 1 Imported by: 0

README

aibris

Go Version License CI Go Report Card

AI + debris. A small CLI for cleaning up the filesystem leftovers from AI coding agents (Codex CLI, Claude Code, Cursor, Windsurf): Git worktrees, agent session stores, AI logs, and recorded-cwd agent state — with generic build debris (node_modules, build caches, pip/uv caches) as complementary coverage so scan stays a complete picture of one home.

AI tools are productive, but they shed a lot of temporary state while they branch, build, test, and retry. aibris scans $HOME for the places that debris collects, shows you how much space is found, how much is reclaimable, and what is protected — then deletes only after filters, a preview, and confirmation.

Platforms

  • macOS: first-class. The recommended install is the Homebrew tap below. install.sh remains the checksummed Homebrew-free path.
  • Linux: first-class via install.sh. No sudo needed by default.
  • Windows: experimental archives. See the canonical Windows support contract for native installation, tested behavior, and unaudited boundaries. install.sh remains Unix/Bash-only.

Install

macOS (Homebrew)
brew install sungjunlee/tap/aibris

This is a third-party tap owned by sungjunlee, repository https://github.com/sungjunlee/homebrew-tap. It is not reviewed by homebrew/core. The fully-qualified command trusts that formula (Homebrew 6.0 item trust), not the whole tap. Do not run brew trust sungjunlee/tap.

The formula sha256 is published by the same publisher as checksums.txt (TOFU, not a second signer).

On Apple Silicon the binary lands in $(brew --prefix)/bin (usually /opt/homebrew/bin). That is not /usr/local/bin. The formula also installs bash, zsh, and fish completions plus man pages into the Homebrew prefix. Homebrew's standard setup (eval "$(brew shellenv)" in .zprofile) puts Homebrew site-functions on fpath before compinit, so the brew zsh completion needs no extra .zshrc line. install.sh still writes only the installing user's ~/.local (and fish ~/.config) files; see completions and man pages.

Sharing a Mac does not make aibris multi-user. Keep these facts separate:

  1. whether aibris is on that account's PATH
  2. who owns the Homebrew prefix and can brew upgrade
  3. which $HOME aibris will scan (the account that runs aibris)
Without Homebrew

install.sh remains the unsigned main script; only the downloaded archive is checked against checksums.txt.

curl -fsSL https://raw.githubusercontent.com/sungjunlee/aibris/refs/heads/main/install.sh | bash

Install from the current main branch when you want unreleased changes:

curl -fsSL https://raw.githubusercontent.com/sungjunlee/aibris/refs/heads/main/install.sh | bash -s -- main

Install a specific release:

curl -fsSL https://raw.githubusercontent.com/sungjunlee/aibris/refs/heads/main/install.sh | bash -s -- 0.12.0

The installer downloads GitHub Release binaries and verifies checksums.txt. The default install path uses GitHub's releases/latest/download URLs for prebuilt binaries. main builds from source with Go.

By default, aibris installs to ~/.local/bin and does not require sudo. If that directory is not on your PATH, the installer prints the exact command to add it for your shell. To install into a shared prefix instead:

curl -fsSL https://raw.githubusercontent.com/sungjunlee/aibris/refs/heads/main/install.sh | bash -s -- --prefix /usr/local/bin
Verify release artifacts

Release archives ship checksums.txt (verified by install.sh), an SPDX SBOM (<archive>.sbom.json), and a GitHub artifact attestation produced by the release workflow. Copy-paste verification for a downloaded archive:

# Attestation: binds the archive to the release workflow build
gh attestation verify aibris_darwin_arm64.tar.gz --owner sungjunlee

# Checksums (same file install.sh checks)
sha256sum -c checksums.txt --ignore-missing

# SBOM published alongside the archive
syft convert aibris_darwin_arm64.tar.gz.sbom.json -o spdx-json

Quick start: scan → dry-run → clean

The core loop is three commands:

aibris scan             # 1. discover what's taking space
aibris clean --dry-run  # 2. preview a cleanup plan without deleting
aibris clean            # 3. review the plan and confirm before deletion
1. Scan

aibris scan inventories debris under $HOME (or under --root subpaths) and leads the summary with found size, the largest reclaim path when it beats default, and home-volume used% / free / band (tight for JSON low). It also reports a default-clean estimate and what is held back by age, --risky, or protection:

Exclusions

scan and clean accept repeatable --exclude paths or glob patterns to hide private, slow, or intentionally retained trees from discovery:

aibris scan --exclude ~/work/secret-project
aibris clean --exclude ~/worktrees/keep-me --dry-run

An exclusion pattern is only honored when it resolves inside the approved scan roots; patterns that escape the roots (absolute paths elsewhere, .. traversal, or symlinks pointing outside) are rejected and reported. Exclusions affect discovery only: they remove paths from scan results and can never make a path cleanable.

Persistent exclusions live in $XDG_CONFIG_HOME/aibris/ignore (falling back to ~/.config/aibris/ignore), one pattern per line with # comments. A repo-local .aibris-ignore file directly under a scan root works the same way. Flag and ignore-file patterns are merged; without any of them, defaults are unchanged.

Example
$ aibris scan --root ~/aibris_demo

scan
  roots  ~/aibris_demo

  scanning node_modules
  scanning build-cache 
  scanning pip-cache   
  scanning cursor      
  scanning claude      
  scanning ai-logs     
  scanning windsurf    
  scanning codex       
  found    pip-cache      0 items   0 B

  found    cursor         0 items   0 B

  found    claude         0 items   0 B

  found    windsurf       0 items   0 B

  found    ai-logs        1 items   94.2 MB

  found    codex          0 items   0 B

  found    build-cache    0 items   0 B

  found    node_modules   2 items   20.0 KB

summary
  94.2 MB found   92% used   34.0 GB free   tight
  found       3 items
  found size  94.2 MB
  default clean (estimate) 0 B
  age-blocked 20.0 KB younger than 7d
  risky       94.2 MB requires --risky

by category
  ai-logs         1   94.2 MB
  node_modules    2   20.0 KB

largest
   94.2 MB  ai-logs       codex-logs   global             today
   12.0 KB  node_modules  projA        -                  today
    8.0 KB  node_modules  projB        -                  today

retention (protected content, read-only)
  codex-sessions   2026-08  units 55  members 55  4.5 MB  orphaned 0/0 B

next
  aibris clean --dry-run
  aibris scan --json

Reading the summary:

  • headline — found size plus home-volume used% / free / band. JSON volume.band low prints as tight. When --pressure or --strip would reclaim more than default, that path is named on the same line. Used% and free bytes in this example are illustrative.
  • found — everything on disk in scope (94.2 MB here).
  • default clean (estimate) — what a default aibris clean would reclaim. It is an estimate; run aibris clean --dry-run for the exact plan.
  • age-blocked and risky — space held back by the default 7d age filter or by the explicit --risky gate for AI logs.
  • retention — a read-only inventory of protected Codex session content; it never becomes a cleanup candidate. See docs/PROTECTED_RETENTION.md.
2. Preview (dry-run)

aibris clean --dry-run plans the deletion without touching anything. This example widens the age filter and scopes to node_modules:

$ aibris clean --no-guide --dry-run --age 1s --category node_modules --root ~/aibris_demo

clean
  roots  ~/aibris_demo

  policy  age>1s, risky=false, active-worktrees=protected
  scan    cached, 15s old

scan summary
  scanned    8 sources   3 physical items   94.2 MB   3 evidence rows
  eligible   2 items   20.0 KB
  protected/skipped 1 item   94.2 MB

by category
  category             found     eligible  protected/skipped evidence  main reason
  ai-logs         1  94.2 MB   0      0 B         1  94.2 MB        1  outside category/tool filters
  node_modules    2  20.0 KB   2  20.0 KB         0      0 B        2  eligible for cleanup

  matched  2 candidates   20.0 KB

clean plan
  mode     dry-run
  targets  2 items   20.0 KB

targets
      size  category      name         project            age/status     action       reason
   12.0 KB  node_modules  projA        -                  today          remove-path  dependency directory; can be reinstalled
    ~/aibris_demo/projA/node_modules
    8.0 KB  node_modules  projB        -                  today          remove-path  dependency directory; can be reinstalled
    ~/aibris_demo/projB/node_modules

[DRY-RUN] No files were removed.

The plan separates eligible (reclaimable) targets from protected/skipped space, shows the exact paths, and only executes after you drop --dry-run and confirm.

3. Clean

Run the same command without --dry-run to execute. aibris prints the plan, asks Proceed? [y/N]:, and only then deletes:

aibris clean --no-guide --age 1s --category node_modules --root ~/aibris_demo

Automation can drive the same loop with machine-readable output — see JSON output:

aibris scan --json                        # machine-readable inventory
aibris clean --no-guide --dry-run --json  # machine-readable cleanup plan

What it cleans

Category Examples Default clean
AI worktrees Finite known containers plus $HOME conventions such as .tool/worktrees and project-local worktrees Classic: orphaned; guided: evidence-based, any tool
Agent state Claude and Cursor project stores Orphaned only by proof; default selection waits for --agent-state-grace (24h)
AI logs Codex, Claude, Windsurf logs Only with --risky
Dependencies project node_modules directories Yes
Build caches Go, npm, Gradle, Cargo, Xcode Yes
Python caches pip and uv cache directories Yes

The first three rows are agent-produced state — aibris's subject. The last three are generic build debris: aibris covers them so scan reports a complete picture of a home, but general-purpose cleaners already handle them and winning on them is not an objective. Category-level definitions and future store constraints live in docs/CATEGORY.md.

Common commands

aibris scan                    # discover what's taking space
aibris scan --json             # machine-readable output (see docs/JSON_SCHEMA.md)
aibris scan --root ~/.codex    # narrow scan to a home subdirectory

aibris clean                   # guided or classic cleanup with confirmation
aibris clean --dry-run         # preview without deleting
aibris clean --root ~/.codex --dry-run
aibris clean --age 7d          # classic filter, or guided minimum idle age
aibris clean --age 30d         # older than 30 days
aibris clean --age 1mo         # month shorthand
aibris clean --age 1y          # older than 365 days
aibris clean --category node_modules   # only node_modules
aibris clean --tool codex,claude       # only specific tools
aibris clean --risky           # include ai-logs
aibris clean --interactive     # confirm each item
aibris clean --include-active-worktrees # include active worktrees
aibris clean --agent-state-grace 0      # drop the orphaned agent-state idle floor (default 24h)
aibris clean --no-guide        # force the classic cleanup audit
aibris clean --guide           # force guided worktree review (any tool)
aibris clean --force           # skip the confirmation prompt only
aibris clean --guide --force --receipt-file cleanup.json  # machine-readable execution receipt

All flags come from aibris --help, aibris scan --help, and aibris clean --help. See docs/DOGFOOD.md for real local scan transcripts used to validate release behavior.

Safety

  • Preview first: --dry-run plans without deleting; every real clean asks for confirmation (--force skips only the prompt, never a safety lock)
  • --interactive confirms each item individually
  • Default age floor: classic cleanup defaults to --age 7d (units h, d, w, mo, y, plus Go duration units such as s); negative ages are rejected
  • --risky required to touch AI logs
  • Active worktrees excluded by default; opt in with --include-active-worktrees only intentionally
  • Agent state is proof-classified (live / orphaned / undetermined); only proven-orphaned entries can be selected, and only after the --agent-state-grace idle floor (24h default)
  • Guided review locks dirty, active, or recently used worktree units and keeps protected rows visible but unselectable
  • Home-scoped roots: scans start at $HOME; --root only narrows to existing directories under it. Deletions outside $HOME, symlink escapes, and unvalidated paths are rejected
  • Protected content is read-only: Codex session retention aggregates are inventory only — see docs/PROTECTED_RETENTION.md

The full safety model, guided policy ordering, cache-reuse identity checks, and partial-scan behavior are specified in docs/SPEC.md.

Documentation

Agent workflow

AI assistants can drive the same loop with JSON: scan, summarize by project/category/age, run a dry-run plan, ask the user, then execute with identical selectors (only --dry-run removed):

aibris scan --json
aibris clean --no-guide --category worktree --age 7d --dry-run
aibris clean --no-guide --category worktree --age 7d

Contributing

See CONTRIBUTING.md and AGENTS.md for architecture and development guidelines. New tools can be added by implementing the DebrisProvider interface.

Roadmap

See ROADMAP.md. The project intentionally remains in the 0.x series until the maintainer is satisfied; milestones are capability gates, not promised release dates or an implied v1.0.0 schedule.

The 0.x compatibility and deprecation policy defines which documented CLI and JSON contracts are stable during that period.

License

MIT — see LICENSE.

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
internal
cleanjson
Package cleanjson: cmd-to-cleanjson adapter functions moved from cmd/clean_json.go
Package cleanjson: cmd-to-cleanjson adapter functions moved from cmd/clean_json.go
codexhome
Package codexhome resolves the Codex home directory.
Package codexhome resolves the Codex home directory.
exclude
Package exclude resolves user exclusion patterns against approved scan roots.
Package exclude resolves user exclusion patterns against approved scan roots.
scanreport
Package scanreport is the cobra-free scan report: one in-memory View, with JSON and human renderers.
Package scanreport is the cobra-free scan report: one in-memory View, with JSON and human renderers.
testutil
Package testutil provides shared helpers for hermetic aibris tests.
Package testutil provides shared helpers for hermetic aibris tests.
volume
Package volume reports host-volume pressure for scan output.
Package volume reports host-volume pressure for scan output.
tools
gen-release-assets command
Command gen-release-assets generates the shell completion scripts and man pages that are packaged in release archives.
Command gen-release-assets generates the shell completion scripts and man pages that are packaged in release archives.

Jump to

Keyboard shortcuts

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