|
| 1 | +# AGENTS.md |
| 2 | + |
| 3 | +Guidance for AI coding agents working in this repo. Every claim below is sourced from the |
| 4 | +Makefile, `go.mod`, `ci.yml`, `CONTRIBUTING.md`, or verified source files — do not add |
| 5 | +unverified commands or paths. |
| 6 | + |
| 7 | +## Overview |
| 8 | + |
| 9 | +`flow-cli` is the official command-line tool for the Flow blockchain: deploy contracts, run |
| 10 | +transactions/scripts, manage accounts/keys, and run a bundled emulator. Go 1.25.1 module |
| 11 | +(`github.com/onflow/flow-cli`), built on [Cobra](https://github.com/spf13/cobra). All |
| 12 | +blockchain logic is delegated to the external `github.com/onflow/flowkit/v2` module. Entry |
| 13 | +point is `cmd/flow/main.go`. License: Apache-2.0. |
| 14 | + |
| 15 | +## Build and Test Commands |
| 16 | + |
| 17 | +CGO is required (BLS crypto). `go build` / `go test` need these env vars set: |
| 18 | +`CGO_ENABLED=1 CGO_CFLAGS="-O2 -D__BLST_PORTABLE__ -std=gnu11"`. |
| 19 | + |
| 20 | +- `make binary` — build `./cmd/flow/flow`; ldflags inject version, commit, and analytics tokens |
| 21 | +- `make test` — `go test -coverprofile=coverage.txt ./...` with CGO flags set |
| 22 | +- `make ci` — `generate test coverage` (this is what GitHub Actions runs) |
| 23 | +- `make coverage` — emits `index.html` and `cover-summary.txt`, only when `COVER=true` |
| 24 | +- `make lint` — `golangci-lint run -v ./...`; depends on `make generate` |
| 25 | +- `make fix-lint` — golangci-lint with `--fix` |
| 26 | +- `make generate` — `go generate ./...`; run before `lint`, `ci`, or any test touching generated code |
| 27 | +- `make check-headers` — `./check-headers.sh`, verifies Apache-2.0 header on every `.go` file |
| 28 | +- `make check-tidy` — `go mod tidy` (CI runs this; fails if `go.mod`/`go.sum` drift) |
| 29 | +- `make clean` — removes binaries under `cmd/flow/` |
| 30 | +- `make versioned-binaries` — cross-compiles linux/darwin/windows × amd64/arm64 |
| 31 | +- `make publish` — uploads versioned binaries to `gs://flow-cli` via `gsutil` |
| 32 | +- `make release` — runs `ghcr.io/goreleaser/goreleaser-cross:v1.25.0` in Docker |
| 33 | +- `make test-e2e-emulator` — `flow -f tests/flow.json emulator start` |
| 34 | +- `SKIP_NETWORK_TESTS=1 make test` — skip tests that reach Flow mainnet/testnet (CONTRIBUTING.md) |
| 35 | +- `nix develop` — enter dev shell from `flake.nix`; then `go run cmd/flow/main.go` |
| 36 | + |
| 37 | +## Architecture |
| 38 | + |
| 39 | +Cobra CLI. `cmd/flow/main.go` wires every subcommand into the root `flow` command and defines |
| 40 | +eight command groups (super, resources, interactions, tools, project, security, manager, schedule). |
| 41 | + |
| 42 | +**`internal/command/`** — shared framework. `command.Command` wraps `cobra.Command` with two |
| 43 | +run modes: `Run` (no project state) and `RunS` (requires `*flowkit.State` loaded from |
| 44 | +`flow.json`). `AddToParent()` handles loading `flow.json`, gateway/network resolution, |
| 45 | +`flowkit.Services` init, version check, analytics, and error formatting. Global flags |
| 46 | +(`internal/command/global_flags.go`): `--network`, `--host`, `--log`, `--output`, `--filter`, |
| 47 | +`--save`, `--config-path`, `--yes`, `--skip-version-check`. Every `Result` must implement |
| 48 | +`String()`, `Oneliner()`, and `JSON()`. |
| 49 | + |
| 50 | +**`internal/super/`** — super commands (`flow init`, `flow dev`, `flow generate`, `flow flix`). |
| 51 | +Scaffolding engine under `internal/super/generator/` with `templates/` and `fixtures/`. |
| 52 | + |
| 53 | +**Feature packages** (`internal/<name>/`) — one per top-level command; each exports a |
| 54 | +`Cmd *cobra.Command` (or `Command`) registered in `main.go`: |
| 55 | +`accounts`, `blocks`, `cadence`, `collections`, `config`, `dependencymanager`, `emulator`, |
| 56 | +`events`, `evm`, `keys`, `mcp`, `project`, `quick` (`flow deploy`, `flow run`), `schedule` |
| 57 | +(transaction scheduler: `setup`/`get`/`list`/`cancel`/`parse`), `scripts`, `settings`, |
| 58 | +`signatures`, `snapshot`, `status`, `test`, `tools` (`dev-wallet`, `flowser`), `transactions`, |
| 59 | +`version`. Support: `internal/util/`, `internal/prompt/`. |
| 60 | + |
| 61 | +**`build/build.go`** — version/commit variables injected via `-ldflags` at build time. |
| 62 | +**`common/branding/`** — styling/ASCII constants. |
| 63 | +**`flowkit/`** (top-level) — **historical artifact**; contains only `README.md` and |
| 64 | +`schema.json`. All Go code moved to the external `github.com/onflow/flowkit/v2`. |
| 65 | +**`docs/`** — hand-maintained Markdown reference pages, one per command, published to |
| 66 | +developers.flow.com. |
| 67 | +**`testing/better/`** — shared test helpers. |
| 68 | + |
| 69 | +## Conventions and Gotchas |
| 70 | + |
| 71 | +- **`make generate` before `make lint` and CI workflows.** `lint` declares `generate` as a |
| 72 | + prerequisite; `ci` runs `generate test coverage` in that order. |
| 73 | +- **CGO is not optional.** Plain `go build ./...` / `go test ./...` without the CGO env vars |
| 74 | + above will fail on the BLS crypto dependency (`__BLST_PORTABLE__`). |
| 75 | +- **Register new commands via `command.Command.AddToParent(cmd)`** (not raw `cmd.AddCommand`) |
| 76 | + so shared boilerplate — `flow.json` load, gateway init, error formatting — runs. See |
| 77 | + `cmd/flow/main.go` for both registration styles. |
| 78 | +- **Command naming is `noun verb`** (`flow accounts get`, not `flow get-accounts`) — see |
| 79 | + "CLI Guidelines" in `CONTRIBUTING.md`. |
| 80 | +- **Prefer flags over positional args.** Use an arg only for the single primary required value. |
| 81 | +- **`--output json` must always work.** Every `Result` implements `JSON()`; never gate |
| 82 | + machine-readable output behind a subcommand. |
| 83 | +- **stdout for normal output, stderr for errors.** No stack traces on error; `--log debug` |
| 84 | + is the escape hatch. |
| 85 | +- **Every `.go` file needs the Apache-2.0 header.** `check-headers.sh` greps for |
| 86 | + `Licensed under the Apache License` or `Code generated (from|by)` and fails CI otherwise. |
| 87 | +- **goimports `local-prefixes: github.com/onflow/flow-cli`** (`.golangci.yml`) — internal |
| 88 | + imports group separately from third-party. |
| 89 | +- **Linters enabled:** `errcheck`, `govet`, `ineffassign`, `misspell`, plus `goimports` |
| 90 | + formatter. CI pins `golangci-lint v2.4.0` (`.github/workflows/ci.yml`). |
| 91 | +- **`SKIP_NETWORK_TESTS=1`** skips tests that reach mainnet/testnet nodes — use in Nix or |
| 92 | + egress-restricted CI (CONTRIBUTING.md "Skipping Network-Dependent Tests"). |
| 93 | +- **`syscall.Exit` in `cmd/flow/main.go` is intentional** — works around a gRPC cleanup |
| 94 | + regression that appeared in Go 1.23.1 (inline comment in `main.go`). |
| 95 | +- **`version.txt` is deprecated** for CLI versions after v1.18.0 (CONTRIBUTING.md |
| 96 | + "Releasing"). The semver is derived from the git tag via `-ldflags` into `build.semver`. |
| 97 | +- **Analytics tokens (`MIXPANEL_PROJECT_TOKEN`, `ACCOUNT_TOKEN`) are baked in at build time** |
| 98 | + via ldflags in the Makefile — rebuild, don't patch the binary. |
| 99 | + |
| 100 | +## Files Not to Modify |
| 101 | + |
| 102 | +- `go.sum` — regenerate via `go mod tidy` / `make check-tidy`, never hand-edit. |
| 103 | +- `flake.lock` — update via `nix flake update`. |
| 104 | +- `flowkit/` top-level directory — legacy stub; real code lives in `github.com/onflow/flowkit/v2`. |
| 105 | +- `version.txt` — deprecated post v1.18.0; leave it. |
| 106 | +- `cli-banner.svg`, `cli.gif` — release artifacts. |
0 commit comments