/ˈhɑːn.dʒi/ (han-jee)
A small CLI soldier that goes hand in hand with a developer. An agentic answer for routine tasks.
Agent, RAG, Vector store, Goroutines, Worker Pool, Cobra CLI
go install . && hange -h # install locally
echo "sk-..." | hange auth # save your OpenAI API key (stdin or arg)
hange explain README.md cmd # explain files or folders
hange commit-msg "ctx" # generate a commit message for staged changes
# hange commit "ctx" # same as above, but also runs git commitShortest way to build the command is
go install . && hange versionThis project is powered by Go Cobra library that provides the framework for CLI applications.
Hange can be installed by 2 ways:
- Install it from GitHub repository by specific tag
go install github.com/yaroslav-koval/hange@latest
- Clone this repo locally and install using
go install . - Download a release binary (no Go toolchain required). Example for macOS arm64:
Consider moving
ver=v0.1.0 url=https://github.com/yaroslav-koval/hange/releases/download/$ver/hange_darwin_arm64 curl -sL "$url" -o hange && chmod +x hange ./hange version
hangeinto a directory on yourPATH(e.g.,/usr/local/bin) for easy access.
- openAI access token
- git (binary)
- go 1.25+ (only for installation by Go commands. Not needed if downloaded from a GitHub release)
- Default config file:
~/.hange(YAML). Override with--configflag or envHANGE_CONFIG_PATH. - Values can also come from env vars with prefix
HANGE_, e.g.HANGE_AUTH_OPENAI_TOKEN. - The OpenAI token is stored at
auth.openai.token, base64-encoded (not strong encryption). - A config file is created automatically if missing.
main.goboots the Cobra CLI and embedsconfig.yamlfor version output.cmd/contains Cobra commands (auth,explain,commit[-msg],version) with minimal wiring only.domain/holds the domain logic and entitiespkg/constsandpkg/envskeep cross-cutting constants and env var names used by the CLI wiring.mocks/stores generated interfaces;configs/badges/holds badge data.
Packages keep core interfaces at the root and place concrete adapters in nested folders. Example: domain/agent defines
the primary AIAgent along with secondary interfaces (CommitProcessor, ExplainProcessor); the OpenAI-backed
implementations live in domain/agent/commit and domain/agent/explain, and factories pick the adapter at runtime.
This
keeps the core logic reusable while swapping integrations per environment.
Tests are powered by Testify and Mockery
All the mocks stored in directory mocks. Mocks for all the existing in application interfaces can be generated by running:
make gen-mocksGenerated Cobra command reference lives in docs/commands. Start
with hange.md,
and use make gen-cli-docs to regenerate the markdown if commands or flags change.
Release notes live in CHANGELOG.md; use docs/CHANGELOG_TEMPLATE.md when drafting a new entry.
- Update code, bump
versioninconfig.yaml, and add a matching## vX.Y.Zsection at the top ofCHANGELOG.md. - Push to
main:.github/workflows/autotag-on-config.yamlverifies the changelog entry and creates tagvX.Y.Z( fails if tag exists). - Tag push triggers
.github/workflows/release.yml, which extracts the top changelog section as release notes and runs GoReleaser to publish binaries for macOS/Linux on amd64/arm64.
Different commands can call different models by their reasons:
explainworks withgpt-nanomodels, despitegpt-codexmodels would fit here better. Reason is work with files and vector stores, this feature is not available forcodexmodels.commit-msgandcommitcommands work withgpt-nano, commit content is embedded into input. Cost-efficient and the most fast model, commit shouldn't take much time.