AGENTS.md
Operating guide for automated agents (and humans) working in this repository.
This repo is a Go-based CLI application (module: github.com/kardolus/chatgpt-cli) built with Cobra (commands) and Viper (configuration). Agent mode and policies live under agent/.
Use this document as the default working context: how to navigate the repo, how to make changes safely, and what “done” means.
1) Repo map (where things usually live)
cmd/— CLI commands, flags, wiring (Cobra).internal/— core application logic (non-exported).api/— API clients + domain/types for providers.agent/— agent runtime: planning, tools, budgets, policy.config/— config defaults/templates.docs/— documentation.scripts/— repo workflows used by Make targets.test/— tests + fixtures (including MCP test servers).vendor/— vendored dependencies (do not edit by hand).
Rule of thumb:
If it changes user-facing flags/output: start in
cmd/.If it changes behavior/business logic: it likely belongs in
internal/,api/, oragent/.
2) Build & test workflow (use Makefile first)
Prefer Make targets over ad-hoc commands; the scripts encode the intended workflow.
List targets:
make help
“Done” means tests pass:
make unitmake integration
Do not skip integration tests unless explicitly instructed.
Other useful targets:
make all-tests(tests + lint/format/tidy)make contractmake smokemake coveragemake install/make reinstall/make binariesmake updatedeps
Notes:
Run
go mod tidyonly when dependency changes are intended.Never edit
vendor/directly; use the dependency workflow (make updatedeps).
3) Go version
Go version is defined in
go.mod. Avoid using language/library features newer than that version unless the module version is intentionally bumped.
4) Testing expectations (required)
For any behavior change or new feature, add or update tests.
This repo uses:
sclevine/spectest structuregomegaassertions
Follow existing style (see agent/budget_test.go as a reference).
Minimum test coverage for a change:
Primary “happy path” behavior
Main failure/validation path
One invariant (e.g., no partial updates on failure)
Guidelines:
Prefer deterministic tests.
Avoid real network calls unless the project already uses fixtures/mocks.
For new external interactions, introduce an interface and test with fakes/mocks.
Use typed errors and verify with
errors.Aswhere appropriate.
5) Agent policy model (how the built-in agent enforces safety)
The default policy is implemented in agent/policy.go.
Tool kinds
Supported step/tool types:
shellllmfiles
If allowed_tools is configured, steps outside that set are denied.
Shell safety
Shell steps must include a non-empty
Command.Denied commands are checked against the exact command string (trimmed). If the command is
rmandDeniedShellCommandsincludesrm, it will be blocked.When
restrict_files_to_work_diris enabled andwork_diris set, the policy also rejects suspicious path-like shell arguments that escape the work dir (absolute paths,~,.., or path-looking args containing separators).
Practical implication:
Prefer running commands scoped to the repo (relative paths).
Avoid passing absolute paths or
..in shell args when workdir restriction is on.
File operations
File steps must include:
Op(lowercased internally)Path
Some ops have additional requirements:
patchrequiresData(unified diff)replacerequiresOldpattern
Allow/deny model:
allowed_file_opsis an allowlist. If it’s empty, all ops are allowed.If
writeis allowed,patchandreplaceare implicitly allowed.When
restrict_files_to_work_diris enabled, file paths are denied if they resolve outside the work dir.
6) How to make changes (agent-friendly workflow)
Locate ownership
cmd/for flags/output/wiringinternal//api//agent/for logic
Trace config and defaults
Viper wiring +
config/templates
Implement the smallest correct change
Keep diffs focused; avoid broad refactors unless requested
Add/update tests
Cover happy path, failure path, and an invariant
Run required targets
make unitmake integration
Sanity-check UX
Help text, error messages, and output formatting
7) Coding conventions used in this repo
Keep functions small and testable.
Follow existing patterns for:
errors (typed errors where useful)
logging (Zap is used here)
configuration (Viper + config templates)
Prefer clarity over cleverness.
8) Guardrails (do not violate)
Never commit secrets (API keys/tokens). Use env vars and documented config.
Do not modify
.git/.Do not touch generated/runtime directories unless explicitly asked:
cache/,history/(and similar local state)
Treat
vendor/as read-only.
9) If you truly need more context
Even when acting autonomously, get precise signals from the codebase:
Search for the exact command/flag under
cmd/.Search for config keys under Viper wiring and
config/.Find existing tests that exercise similar behavior and mirror their structure.
When requirements are ambiguous, prefer:
conservative behavior
backwards-compatible defaults
explicit validation errors