Codalotl
Codalotl is a Go-focused coding agent. It is optimized for Go package workflows: package-scoped context, package-aware tools, and automatic post-edit checks in package mode.
Codalotl is a Go-focused coding agent. It is optimized for Go package workflows: package-scoped context, package-aware tools, and automatic post-edit checks in package mode.
go install github.com/codalotl/codalotl@latest
codalotl version
export OPENAI_API_KEY="sk-..."
codalotl
codalotl requires various Go tools be installed: gopls, goimports, gofmt./package .
To use Codalotl's Go-specific features, you'll need to enter Package Mode: /package path/to/pkg. This isolates the agent to primarily working on this package. The following mechanisms are used:
In Package Mode, the agent is isolated to work in a single package: directly reading and writing files and listing directories are limited to this package.
The agent does NOT have a shell tool (in my experience, LLMs cannot help but use shell and violate their instructions to explore outside their package, even with strong prompting).
In exchange for these limitations, the agent gets confidence to work in the current package without analysis-paralysis of working in a large codebase. As long as you, the human developer, set the correct package, this is a very large benefit.
That being said, the agent DOES have levers to work in a multi-package environment:
grep and directly reading various files throughout a codebase.You can manually give the agent context outside its package by using @ to mention specific files or directories - the agent will be able to directly read them, even if outside the package.
Every session in Package Mode starts with a bundle of context for the current package. This context includes:
So, before the agent even starts, it knows which files exist, which code is defined where, who uses the package, and the package's build/test status. Compare that to traditional agents: they'll usually start off using ls in various directories, then grep to find out where things are, then reading files to find relevant code. Traditional agents might only check for failing tests/build later, throwing a wrench in their assumptions. All of this is given a small, neat package from the get-go.
You can explore this initial context using Codalotl CLI: codalotl context initial path/to/pkg will print to stdout this initial context.
Any patches the agent applies to the codebase will be automatically gofmted (in the same tool call as the patch). This can cut out a lot of back and forth of failing builds and multiple tool calls.
All patches made will automatically check for build errors and lint issues (in the same tool call as the patch). Lints are configurable and extensible. Again, cuts out a lot of back and forth.
The TUI is the interactive coding agent.
Commands:
/quit, /exit, /logout: exit the TUI./new: start a new session (keeps active package if already in package mode)./skills: list installed skills and any skill loading issues./models: list current model and available callable models./model <id>: switch models and start a new session./package <path>: enter package mode./package: leave package mode./generic: leave package mode.Primary controls:
Enter: send message.Ctrl-J: insert newline in input.ESC:
Ctrl-C:
Up/Down: cycle message history.Page Up/Page Down/Home/End/Mouse wheel: scroll message area.Ctrl-O or terminal double-click: toggle overlay mode.The info panel (right side, if width allows), shows:
Enter/Exit Overlay Mode with Ctrl-O or by double-clicking the terminal area.
Overlay Mode reveals two buttons, appearing below certain messages/tool calls in the Messages Area:
copy: lets you copy message and text from the TUI. The current workaround for being unable to select text.details: shows a dialog with raw tool input/output and raw context sent to the LLM.codalotl supports interactive (TUI) and noninteractive (CLI) workflows.
Argument semantics for <path/to/pkg> (where relevant):
some/pkg and Go-style ./some/pkg work).... package patterns are not implemented.Launches the interactive TUI.
codalotl
Shows command usage.
codalotl --help
This path skips startup validation.
Prints installed version, and may include update status if available quickly.
codalotl version
Prints effective configuration and config sources. See Config File below.
codalotl config
Runs one noninteractive agent turn from CLI.
codalotl exec -p ./internal/cli "fix failing test"
Flags:
-p, --package <path>: run in package mode rooted at this package path.-y, --yes: auto-approve permission checks.--no-color: disable ANSI formatting.--model <id>: override configured preferred model for this run.Print public API documentation context for a package.
codalotl context public ./internal/cli
Print initial package context bundle used for package-mode.
codalotl context initial ./internal/cli
Print package listing for the current module.
codalotl context packages
Flags:
-s, --search <go_regexp>: filter package list by Go regexp.--deps: include direct dependency packages from go.mod (require entries excluding // indirect).Reflow Go documentation comments in one or more paths.
codalotl docs reflow some/pkg
Flags:
-w, --width <int>: override configured reflowwidth for this run.--check: dry-run (print files that would change; do not write).Output style is similar to gofmt -l: one file per line if modified.
Configuration is loaded from JSON files plus environment.
Codalotl will search for config.json in the following locations, merging config values:
.codalotl/config.json (highest priority)~/.codalotl/config.json (lowest priority)Schema:
{
"providerkeys": {
"openai": "sk-..."
},
"reflowwidth": 120,
"lints": {
"mode": "extend",
"disable": [],
"steps": []
},
"disabletelemetry": false,
"disablecrashreporting": false,
"preferredprovider": "",
"preferredmodel": ""
}
Key fields:
providerkeys.openai: OpenAI API key (ENV is also supported and preferred).reflowwidth: default doc reflow width (default 120).lints: lint pipeline config (see Lints below).preferredprovider, preferredmodel: default model selection hints.disabletelemetry, disablecrashreporting: opt out of event/error and panic reporting.To see your config, run codalotl config.
Currently, only OpenAI models are supported. More providers will be added over time.
To set your model via the TUI:
/models/model <id>To set your model via the config file:
{
"preferredmodel": "gpt-5.2-medium"
}
To set your model for an exec run:
codalotl exec --model gpt-5.2-medium "your prompt"
Set your API key, we recommend setting an ENV variable.
For example, you may add the following to something like your .bashrc:
export OPENAI_API_KEY="sk-..."
Alternatively, you can set it in .codalotl/config.json:
{
"providerkeys": {
"openai": "sk-..."
}
}
Codalotl reads AGENTS.md instructions and injects them into the agent context automatically. The LLM does NOT need to manually Read AGENTS.md.
In package mode, multiple AGENTS.md files may be added to context if multiple exist (looking from package dir upward to sandbox dir).
Skills are local instruction bundles (SKILL.md) available to the agent, following the specification at agentskills.io.
Some built-in system skills are auto installed.
You can add your own skills by placing them in a skill search path (and then starting a new session with /new):
.codalotl/skills in current directory and each parent directory (e.g., project-based skills).~/.codalotl/skills: skills the user wants for all projects.Skills can be listed in the TUI with /skills.
You can invoke skills by explicitly mentioning with a $ prefix in a message (ex: use $skill-creator to make a new skill that...). The LLM may automatically decide to use a skill based on the task it is trying to accomplish.
Package mode note:
Lint pipeline config controls which checks/fixes run, and in which situations they run. Each linting tool can be either be check-only, or check-and-fix.
Run situations:
initial: when automatic initial package context is built (lints just check).patch: automatically after patches (lints auto-fix).fix: when the Fix Lints tool is specifically run (lints auto-fix).Defaults and preconfigured IDs:
gofmt.id: reflow, staticcheck, golangci-lint.How to think about lint situations:
initial fast and low-noise. It feeds the agent's starting context, so slow lints reduce responsiveness. Noisy lints distract the LLM.fix) instead of always-on runs.Recommended baseline config:
{
"reflowwidth": 120,
"lints": {
"mode": "extend",
"steps": [
{ "id": "reflow" },
{ "id": "staticcheck" }
]
}
}
Custom lint step config:
id, optional situations, and check/fix commands.
check command. Check-and-fix linters should define commands for both check and fix.command: executable to run (for example gofmt, staticcheck, golangci-lint).args: argument list passed to command; each entry supports templates.cwd: working directory for the command.messageifnooutput (optional string): status text shown when the command emits no output. Used to guide LLM.outcomefailifanyoutput (optional boolean): treat any stdout/stderr output as a failing outcome.{{ .path }}: absolute path to the target package directory.{{ .moduleDir }}: absolute path to the module root (directory containing go.mod).{{ .relativePackageDir }}: package path relative to {{ .moduleDir }}.{{ .RootDir }}: sandbox dir.initial, check is required; if a step runs in patch or fix, at least one of check or fix is required.Example custom step:
{
"lints": {
"mode": "extend",
"steps": [
{
"id": "govulncheck",
"situations": ["fix"],
"check": {
"command": "govulncheck",
"args": ["./{{ .relativePackageDir }}"],
"cwd": "{{ .moduleDir }}",
"messageifnooutput": "no issues found"
}
}
]
}
}
Extend vs replace:
mode: "extend" starts from defaults and appends your steps.mode: "replace" ignores defaults and uses only your steps.disable removes resolved steps by id (unknown IDs are ignored).mode: "replace" with steps: [] to disable all lints.Per-step situations behavior:
null: run in all situations.[]: run in no situations.If you enable reflow (it normalizes documentation width and formatting), a one-time repo-wide reflow is recommended (otherwise you'll see reflow-related diffs in later tasks/commits).
One-time reflow of a module:
go list -f '{{.Dir}}' ./... | sort -u | xargs -I{} codalotl docs reflow "{}"
Codalotl has policy-based safety controls, not OS-level sandboxing. It's designed to prevent you from easily shooting yourself in the foot, but doesn't prevent attackers from doing so. UX is prioritized over hard security. You can achieve security by running in a container/VM.
Authorization model:
Shell command policy:
Use @ file/dir mentions to allow read access to files outside the sandbox or outside the current package.
Telemetry and reporting:
{
"disabletelemetry": true,
"disablecrashreporting": true
}
Current practical status:
Known unsupported or intentionally omitted areas: