This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
# Build the binary (requires CGO for BLS crypto)
CGO_ENABLED=1 CGO_CFLAGS="-O2 -D__BLST_PORTABLE__ -std=gnu11" GO111MODULE=on go build -o ./cmd/flow/flow ./cmd/flow
# Or use Make
make binary
# Run directly without building
go run cmd/flow/main.go [command]# Run all tests
make test
# Equivalent: CGO_ENABLED=1 CGO_CFLAGS="-O2 -D__BLST_PORTABLE__ -std=gnu11" GO111MODULE=on go test -coverprofile=coverage.txt ./...
# Run a single test package
CGO_ENABLED=1 CGO_CFLAGS="-O2 -D__BLST_PORTABLE__ -std=gnu11" go test ./internal/accounts/...
# Run a specific test
CGO_ENABLED=1 CGO_CFLAGS="-O2 -D__BLST_PORTABLE__ -std=gnu11" go test ./internal/accounts/... -run TestFunctionName
# Skip network-dependent tests (e.g. in sandboxed environments)
SKIP_NETWORK_TESTS=1 make testmake lint # Run golangci-lint
make fix-lint # Auto-fix lint issues
make check-headers # Verify Apache license headers on all Go files
go generate ./... # Regenerate generated code (required before lint)The CLI is a Cobra-based application with three main layers:
cmd/flow/main.go — wires all subcommands into the root flow command.
The command.Command struct wraps a cobra.Command with two execution modes:
Run— for commands that don't need a loadedflow.jsonstateRunS— for commands that require an initialized project state (*flowkit.State)
Command.AddToParent() handles all shared boilerplate: loading flow.json, resolving network/host, creating the gRPC gateway, initializing flowkit.Services, version checking, analytics, and error formatting. All new commands should use this pattern.
Every command's run function returns a command.Result interface with three output methods: String() (human-readable), Oneliner() (grep-friendly inline), and JSON() (structured). The framework handles --output, --filter, and --save flags automatically.
Each feature area is its own package with a top-level Cmd *cobra.Command that aggregates subcommands. Pattern:
accounts.Cmd(internal/accounts/) — registered inmain.goviacmd.AddCommand(accounts.Cmd)- Subcommands (e.g.,
get.go,create.go) define a package-levelvar getCommand = &command.Command{...}and register viainit()or the parent'sinit()
Key packages:
internal/super/— high-level "super commands":flow init,flow dev,flow generate,flow flixinternal/super/generator/— code generation engine for Cadence contracts, scripts, transactions, and testsinternal/dependencymanager/—flow depscommands for managing on-chain contract dependenciesinternal/config/—flow configsubcommands for managingflow.jsoninternal/emulator/— wraps the Flow emulator
The CLI delegates all blockchain interactions to the github.com/onflow/flowkit/v2 module (external). The flowkit.Services interface is the primary abstraction for network calls. The local flowkit/ directory is a historical artifact (migrated to the external module) and contains only a README and schema.
Defined in internal/command/global_flags.go, applied to every command: --network, --host, --log, --output, --filter, --save, --config-path, --yes, --skip-version-check.
flow.json is the project config file. flowkit.Load() reads it. The internal/config/ commands modify it. state.Networks(), state.Accounts(), etc. provide typed access.
- Commands follow
noun verbpattern (flow accounts get) - Prefer flags over positional args; use args only for the primary required value
--output jsonmust always work for machine-readable output- Errors go to stderr; normal output to stdout
- Progress indicators for long-running operations via
logger.StartProgress()/logger.StopProgress() - Long-running commands support
--yesto skip confirmation prompts
All Go source files must have the Apache 2.0 license header. Run make check-headers to verify.