GitHub - debarshibasak/clawx: Run versioned, checksummed and approval-gated tasks with Claude Code, Codex, Gemini and other agent CLIs.

GitHub

16 min read Original article ↗
  ██████╗██╗      █████╗ ██╗    ██╗██╗  ██╗
 ██╔════╝██║     ██╔══██╗██║    ██║╚██╗██╔╝
 ██║     ██║     ███████║██║ █╗ ██║ ╚███╔╝
 ██║     ██║     ██╔══██║██║███╗██║ ██╔██╗
 ╚██████╗███████╗██║  ██║╚███╔███╔╝██╔╝ ██╗
  ╚═════╝╚══════╝╚═╝  ╚═╝ ╚══╝╚══╝ ╚═╝  ╚═╝
   ╱╱╱  agent-driven package manager

CI Release

Install

curl -fsSL https://raw.githubusercontent.com/debarshibasak/clawx/master/install.sh | sh

macOS and Linux. The script detects your platform, verifies the release archive against the release's checksums.txt, and installs to /usr/local/bin (falling back to ~/.local/bin) — reporting each step as it goes:

  [1/5] ✔ Detecting platform   darwin/arm64
  [2/5] ✔ Resolving release    v0.2.2
  [3/5] ⠹ Downloading release  ███████████░░░░░░░░░░░  52%  1.8M/3.5M
  [4/5] ✔ Verifying checksum   sha256:cc309ae1c107
  [5/5] ✔ Installing           /usr/local/bin/clawx

Pin a version with CLAWX_VERSION=v0.2.2, change the destination with CLAWX_INSTALL_DIR, or set NO_COLOR=1 for plain output (also the default when stdout is not a terminal, so CI logs stay clean). From a checkout, make install-latest runs the same script. See Windows and other install options below.

Clawx shells out to an agent CLI, so you also need one of claude, codex, opencode, gemini or agy on your PATH. The default is claude; select another with CLAWX_PROVIDER.


Reusable, versioned, checksummed tasks for coding agents — run with Claude Code, Codex, Gemini CLI, OpenCode, or Antigravity. Search → inspect → approve → execute, with a log of everything that ran.

clawx demo: search, info, approval, execution, history

The whole idea in 30 seconds: find a package, ask an agent what it would do, review the approval prompt (checksum, parameters, tool grants), let your agent execute it, and see the run land in your history. The output above is replayed from a real recorded session (docs/demo/).

A Clawx package is a markdown file with YAML front matter. The front matter declares metadata — name, version, typed parameters, dependencies, the tools the package wants. The body becomes the system prompt of an agent CLI. "Installing" a package means: fetch it from a registry, verify its SHA256 against the index, show an approval prompt, execute it under the agent you chose, and append the outcome to an execution log. There is no code generation and no compilation — the install is a governed agent invocation.

Warning

Security model — read this before running packages.

A package is a prompt executed by an agent with real tool access on your machine. Treat running one with the same suspicion as curl | sh.

  • allowed_tools is enforced at the subprocess boundary only under the claude provider, where it is forwarded as --allowedTools. Under codex, opencode, gemini, and agy it is disclosure in the approval prompt, not a Clawx-enforced boundary — those CLIs govern tool access through their own sandboxing and approval modes.
  • SHA256 verification proves the file you run is byte-identical to what the registry indexed. It says nothing about whether those bytes are safe. A registry is a trust root: only add registries you trust, and use clawx info to have a tool-less agent summarize a package before running it.
  • Agents are not deterministic and can misinterpret instructions. The approval prompt and the execution log exist to bound and audit that risk, not to eliminate it.

Why not shell scripts?

Fair question — it's the first one everybody asks. A shell script encodes a mechanism: the exact commands that worked on the machines its author anticipated. A Clawx package encodes intent — the goal, the constraints, the verification steps — and the agent picks the mechanism for the machine in front of it. The same dockerize package containerizes a Go, Node, or Python repo because it detects the ecosystem instead of assuming it; a script would need a case statement per ecosystem, per package manager, per layout, and it still breaks on the repo its author never saw.

On top of that, packages carry infrastructure scripts never accumulated:

  • Typed parameters — declared in front matter with defaults; missing required ones are prompted for, not discovered as an unbound variable at runtime.
  • Dependenciesdepends_on resolves transitively against your registries. A dependency whose provides binaries are already on your PATH counts as met; anything genuinely missing is listed for your approval before it is installed.
  • Provider portability — one package runs under claude, codex, opencode, gemini, or agy; switching agents is an env var, not a rewrite.
  • A governed run — SHA256 verification against the registry index, then an approval prompt listing the tools, env vars, and parameter values before anything executes.
  • An execution trail — every run appends package, version, SHA, exit code, and duration to ~/.clawx/execution.log. You can answer "what ran on this machine, when, and did it succeed?"

And the honest counterpoint: an agent run is slower than a script and not deterministic — the same package produces a different transcript each time. If your task is fully mechanical, keep the shell script (a package can simply call it). Clawx is for the judgment-shaped tasks where scripts rot: auditing, migrating, configuring against whatever the repository actually contains.

How it compares

Clawx Shell scripts Makefiles Ansible Agent skills Prompt libraries
Unit encodes intent + constraints commands build graph + commands desired state instructions for one agent text
Handles environments the author never saw yes (agent adapts) no no only what modules cover yes n/a — nothing executes
Typed parameters yes ad-hoc $1 vars yes no no
Dependencies between units yes no targets, same file roles no no
Works across agent CLIs yes (5 providers) n/a n/a n/a no — one product copy-paste anywhere
Pre-run approval listing tool access yes no no no product-dependent no
Content verification (checksum vs index) yes no no galaxy signing (opt-in) no no
Execution log yes no no yes no no
Deterministic no yes yes mostly no n/a
Runs without an agent / offline no yes yes yes no yes

Candidly: if the task is deterministic, a script or Makefile is strictly better. If you manage fleets of machines toward a desired state, that's Ansible. Agent skills are the closest cousin — but they're tied to a single agent product and ship without versioned distribution, checksums, approval gates, or an execution log. Prompt libraries share text; nothing fetches, verifies, executes, or records it. Clawx occupies the gap: distributable, verifiable, auditable tasks that need judgment at runtime.

Showcase

The packages that show what the model is for — multi-step, context-aware work, not brew install with extra steps:

go-modernize — audit an aging Go repo: toolchain drift, deprecated APIs (ioutil, strings.Title, ...), idiom drift, outdated deps, vet/lint. Writes a risk-grouped MODERNIZE.md; with -p apply=true it applies the mechanical fixes and proves build and tests stay green (it refuses to touch a dirty working tree, and reverts anything that breaks). This is the package in the demo above.

clawx run go-modernize                    # report only
clawx run go-modernize -p apply=true      # apply safe fixes, re-verify

ci-baseline — detect the ecosystem, then set up the three layers everyone postpones: a linter config, a GitHub Actions workflow running the repo's actual build/test/lint commands, and pre-commit hooks (pre-commit or lefthook). Respects anything that already exists, runs the linter once, and tells you whether the first CI run will be green.

clawx run ci-baseline -p hook_manager=lefthook

docker-image-diet — build your image, rank its layers, rewrite the Dockerfile (multi-stage split, slimmer base, cache hygiene, .dockerignore), rebuild, and report before/after sizes from real builds. If it can't make the image smaller, it restores the original and says so.

clawx run docker-image-diet

Alongside those: repo-security-review, setup-github-actions, dockerfile-audit, migrate-eslint-config, prepare-open-source-release, and 350+ more install, setup, audit, and scaffolding packages in the built-in registry.

Other install options

Archives for darwin/linux (amd64, arm64) and windows/amd64 ship with every release, alongside a checksums.txt — grab one manually from the releases page if you prefer.

Windows (PowerShell)

The Windows archive is named clawx_<tag>_windows_amd64.tar.gz. In PowerShell, download it with the matching checksums.txt, verify the SHA256, and put clawx.exe in a directory on your user PATH:

$tag = "v0.2.1" # replace with the release tag you downloaded
$archive = "clawx_${tag}_windows_amd64.tar.gz"
$base = "https://github.com/debarshibasak/clawx/releases/download/$tag"

Invoke-WebRequest "$base/$archive" -OutFile ".\$archive"
Invoke-WebRequest "$base/checksums.txt" -OutFile .\checksums.txt
$expected = Get-Content .\checksums.txt |
  Where-Object { $_ -match "\s$([regex]::Escape($archive))$" } |
  ForEach-Object { ($_ -split "\s+")[0] } |
  Select-Object -First 1
if (-not $expected) { throw "No checksum found for $archive" }
$actual = (Get-FileHash ".\$archive" -Algorithm SHA256).Hash.ToLowerInvariant()
if ($actual -ne $expected.ToLowerInvariant()) { throw "SHA256 verification failed" }

tar -xzf ".\$archive"
$installDir = Join-Path $env:USERPROFILE "bin"
New-Item -ItemType Directory -Force $installDir | Out-Null
Move-Item -Force .\clawx.exe (Join-Path $installDir "clawx.exe")
$userPath = [Environment]::GetEnvironmentVariable("Path", "User")
$pathEntries = @($userPath -split ";" | Where-Object { $_ })
if ($pathEntries -notcontains $installDir) {
  [Environment]::SetEnvironmentVariable("Path", (($pathEntries + $installDir) -join ";"), "User")
}
$env:Path = "$installDir;$env:Path"
clawx --help

PowerShell stores Clawx state under %USERPROFILE%\.clawx (the equivalent of ~/.clawx on macOS/Linux). clawx list uses $env:PAGER when stdout is a terminal and falls back to more; use clawx list --no-pager or set $env:CLAWX_NO_PAGER = "1" for non-interactive output.

WSL is a separate environment: a Linux Clawx binary uses the Linux home directory (~/.clawx) and Linux provider CLIs. A Windows binary launched from PowerShell uses %USERPROFILE%\.clawx and needs the selected provider CLI on the Windows PATH; the two environments do not share state automatically.

Or build from source:

go build -o clawx .      # or: make build
go install .             # or: make install

Shell completion

The completion command is generated by Cobra. After installing clawx, use the setup for your shell below and start a new shell (or source the generated file) to enable tab completion.

Bash

For bash-completion v2, install the generated function in the user completion directory:

mkdir -p "${BASH_COMPLETION_USER_DIR:-$HOME/.local/share/bash-completion/completions}"
clawx completion bash > "${BASH_COMPLETION_USER_DIR:-$HOME/.local/share/bash-completion/completions}/clawx"

On systems without bash-completion, source a file from your shell startup instead:

clawx completion bash > "$HOME/.clawx-completion.bash"
printf '\nsource "$HOME/.clawx-completion.bash"\n' >> "$HOME/.bashrc"
source "$HOME/.clawx-completion.bash"

Zsh

For the stock macOS zsh, keep the completion function in a user directory and add that directory to fpath:

mkdir -p "$HOME/.zsh/completions"
clawx completion zsh > "$HOME/.zsh/completions/_clawx"
printf '\nfpath=("$HOME/.zsh/completions" $fpath)\nautoload -Uz compinit && compinit\n' >> "$HOME/.zshrc"
autoload -Uz compinit && compinit

If zsh was installed with Homebrew, use its site-functions directory instead (/opt/homebrew on Apple Silicon, /usr/local on Intel):

zsh_site="$(brew --prefix)/share/zsh/site-functions"
mkdir -p "$zsh_site"
clawx completion zsh > "$zsh_site/_clawx"
autoload -Uz compinit && compinit

Fish

Fish loads completion files from this directory automatically in new shells:

mkdir -p "$HOME/.config/fish/completions"
clawx completion fish > "$HOME/.config/fish/completions/clawx.fish"

Install clawx with clawx

Already have clawx? It updates itself the way it runs everything else — the built-in registry ships an install-clawx package that fetches the latest release, verifies its checksum, and installs the binary:

Like every run, it goes through the approval prompt first, and the execution is logged to ~/.clawx/execution.log.

Quickstart

Clawx ships with a built-in default registry (the registry/ directory of this repo served over GitHub raw), so it works with no setup:

clawx list                        # browse the catalog
clawx search docker               # find packages by name/description
clawx info go-modernize           # what would this package do?
clawx run go-modernize            # fetch, verify, approve, execute
clawx history                     # what has run on this machine?
clawx rolladice                   # what should I run next?

clawx help prints the full guide — commands, package format, security model, environment variables and local state.

Watching a package run

By default a run prints one live progress line — elapsed time, todo completion and the current tool call — and stays quiet otherwise:

⠹ claude · 12s · todos 1/4 · 3 tool calls · Bash: go vet ./...

Pass --verbose (or set CLAWX_VERBOSE=1) to stream the agent's narrative, its tool calls and its todo list as they happen:

$ clawx run go-modernize --verbose

Baseline is green (build ✅, tests ✅). Auditing the source now.
→ Bash: go vet ./...
── todos ──
  [x] Establish build/test baseline
  [>] Audit for deprecated APIs
  [ ] Write MODERNIZE.md

The agent's final summary is shown only in verbose mode.

Commands

Command Signature Does
add clawx add <url> [--server] [--name] [--ref] Register a registry: a git repo (default) or a clawx HTTP server.
list clawx list [--refresh] [--no-pager] List packages across every configured registry, paged through $PAGER when printed to a terminal.
search clawx search <term> [term...] [--refresh] Search packages by name and description; multiple terms must all match.
run clawx run <name>[@version] [-p k=v] [--prompt] [--verbose] [-y] Fetch, verify, approve, execute. The critical path. Aliased as install.
info clawx info <name> [--no-summary] Package metadata, plus a tool-less agent summary of what it would do.
rolladice clawx rolladice [--fast] [--dir] [--no-agent] [--limit] Scan your workspace and the registries, recommend what to install next.
uninstall clawx uninstall <name> [-y] Drop the install record from local state.
update clawx update [name] Re-fetch packages, reinstall when the SHA or version changed.
history clawx history [--limit] Replay the NDJSON execution log.
pipeline clawx pipeline <pipeline.yaml> [--dry-run] Execute a multi-step pipeline of packages in sequence. clawx run <file.yaml> does the same.
server clawx server --dir <path> [--port] Run the registry HTTP server. index.yaml is built at request time.
version clawx version [--short] Print the version, commit, build date, and platform. clawx --version prints just the version.

clawx rolladice

Rolls the dice on what to install next. It scans the current directory for projects (ecosystem manifests), libraries (parsed out of those manifests), containers (Dockerfile, compose, Kubernetes, Helm, devcontainer) and notable files (CI, IaC, build, test, lint, data, docs) — then matches all of that against the catalogs served by your registries.

  Detected:
    [*] go                 go.mod (github.com/acme/svc)
    [*] dockerfile         Dockerfile
    [*] kubernetes         deploy/app.yaml
    [*] ci:github-actions  .github/workflows/ci.yml

  Roll:

    1. base-setup               v1.0.0     score 72
       Prepare a Go service repository with linting and CI
       - required by installed analytics
       - matches your workspace: go, ci
       clawx run base-setup

Ranking is deterministic and runs offline: unmet dependencies of installed packages outrank packages that build on installed ones, which outrank workspace-signal and shared-vocabulary matches. The shortlist is then handed to the agent, which explains the picks — a read-only call with no tools granted.

  • --fast skips both the workspace walk and the agent, ranking purely from what you already have installed. It returns in milliseconds.
  • --no-agent prints the offline shortlist without invoking any agent.

Only manifest files are ever opened. .env files and your source files are recorded by path and never read.

Package format

YAML front matter delimited by ---, followed by the markdown body that becomes the agent's system prompt. Only name is required.

---
name: setup-project
version: 1.0.0
description: Scaffold a new project directory
author: adaptive-scale
author_email: team@adaptive.live
allowed_tools:
  - bash
env_required: []
depends_on: []
params:
  - name: project_name
    type: string          # string | int | bool
    required: true
    description: Directory to create
  - name: language
    type: string
    required: false
    default: go
---

You are a project scaffolding assistant. Use the Input Parameters provided to…

depends_on packages are resolved transitively before the package runs. A dependency is considered satisfied if clawx has installed it before, or if every executable it declares under provides is already on your PATH — so a machine that already has Docker is never asked to install it. Whatever is left is shown as a tree and installed only after you approve:

This package requires 1 dependency that is not on this system:
    └─ install-docker (not found)

Install 1 missing dependency? [y/N]:

An install-* package declares what it puts on PATH:

name: install-gh-cli
provides:
  - gh

Omit provides when there is no PATH binary to look for — a GUI app or a shell function — and clawx falls back to its own installation records. Fixtures live in testdata/packages/.

Want to write one? Create your first Clawx package in five minutes walks through template → local test → pull request, with a real transcript.

Add a custom registry

  • git (default) — clawx add github.com/owner/repo [--ref main]. The repo is cloned under ~/.clawx/cache/repos/ and the index is built from its *.md files.
  • serverclawx add http://host:8080 --server. Any clawx server instance, which builds index.yaml by scanning its --dir at request time.

To try the server flavor against the bundled fixtures:

./clawx server --dir ./testdata/packages --port 8080   # terminal 1

./clawx add http://localhost:8080 --server             # terminal 2
./clawx list
./clawx run hello-world

Indexes are cached on disk with a TTL (default 1h); --refresh bypasses it. Opt out of the built-in default registry with CLAWX_NO_DEFAULT_REGISTRY=1.

Providers

The agent CLI sits behind a Provider interface selected by CLAWX_PROVIDER.

Provider Invocation allowed_tools
claude (default) --system-prompt-file <tmp> Forwarded as --allowedToolsenforced at the subprocess boundary.
codex codex exec -, prompt via stdin Not forwarded; governed by Codex's own approval/sandbox modes.
opencode opencode run, prompt via stdin Not forwarded; governed by OpenCode's own config.
gemini system prompt via GEMINI_SYSTEM_MD=<tmp>, user prompt via -p Not forwarded; governed by Gemini CLI's approval modes and settings.
agy agy -p <prompt> (Antigravity CLI; alias: antigravity) Not forwarded; governed by agy's own permission prompts.

This is the asymmetry the warning at the top of this README is about: allowed_tools is a real security boundary only under claude. Everywhere else it is disclosure shown in the approval prompt.

clawx info and clawx rolladice are the exceptions — both are read-only calls whose system prompt forbids tool use, and under claude no --allowedTools flag is passed at all.

Environment

Variable Effect
CLAWX_PROVIDER Agent CLI: claude (default), codex, opencode, gemini, agy.
CLAWX_PROVIDER_BIN Absolute path to the agent binary, bypassing PATH lookup.
CLAWX_NO_DEFAULT_REGISTRY=1 Don't inject the built-in default registry.
CLAWX_INSTALL_IDS=1 Generate and persist a UUID per install.
CLAWX_VERBOSE=1 Stream agent output as if --verbose was passed.
CLAWX_NO_PAGER=1 Never page clawx list output, even on a terminal.
PAGER Pager used by clawx list (default: less -FRX, then more).

Local state

Everything persisted lives under ~/.clawx/:

config.json        registries + cache TTL
cache/<sha>.json   cached registry indexes
cache/repos/       cloned git-backed registries
installed.json     install records
execution.log      NDJSON execution history

Contributing

The easiest contribution doesn't require reading any Go: write a package. Start with Create your first Clawx package in five minutes, then look at the good first issue label. CONTRIBUTING.md covers the codebase itself, docs/ARCHITECTURE.md explains how the pieces fit, and ROADMAP.md is where the project is headed. Security reports go through SECURITY.md.

Development

make build     # go build -o clawx .
make test      # go test ./...
make vet       # go vet ./...
make fmt       # gofmt -s -w .
make smoke     # serve ./testdata/packages on :8080