This file provides essential information for AI agents working on the LFX CLI codebase. It focuses on development workflows, architecture understanding, and build processes needed for making code changes.
The LFX CLI (lfx) is a developer-facing command-line tool for
authenticating with the Linux Foundation's LFX platform and making
authenticated API calls, following the same interaction model as the gh
CLI (lfx auth login → lfx auth token).
- Language: Go (see
go.modfor the minimum required version) - CLI framework:
urfave/cli/v3for subcommand routing - Docs generation:
urfave/cli-docs/v3for LLM/agent-friendly Markdown reference docs (lfx docs) - Release automation: GoReleaser for multi-arch binary builds published to GitHub Releases
lfx-cli/
├── cmd/
│ └── lfx/ # Main application entry point
├── internal/
│ └── commands/ # CLI subcommand implementations
├── .goreleaser.yaml # Multi-arch release build configuration
├── go.mod # Go module definition
├── Makefile # Build automation
├── README.md # User documentation
└── AGENTS.md # This file (AI agent guidelines)
This repo is under active scaffolding. Auth and API commands are currently stubs; real implementations land in follow-on work:
lfx auth login/status/logoutlfx auth tokenlfx api
Credential storage (system keychain via 99designs/keyring) and the Auth0
CIMD client are tracked separately.
No container build: this project produces binary artifacts only,
distributed via GitHub Releases, the install.sh curl-style installer
hosted on gh-pages, and go install. There is no Dockerfile, Helm
chart, or container image pipeline.
# Verify Go is installed at or above the version in go.mod.
go versionmake build
# or directly: go build -ldflags="-s -w" -o bin/lfx ./cmd/lfxmake run ARGS="auth login"
# or directly: ./bin/lfx auth loginmake fmt # Format code
make vet # Run go vet
make lint # Run golangci-lint (if installed)
make revive # Run revive (if installed)
make goreleaser-check # Validate .goreleaser.yaml (if goreleaser installed)
make check # Run all of the abovemake test # Run Go tests
make test-coverage # Run tests with coverage reportmake cleanCommands are implemented in internal/commands and registered with the
root *cli.Command in cmd/lfx/main.go.
- Create or extend a file in
internal/commands/(e.g.,auth.gofor anauthsubcommand group) - Implement a
New<Name>Command()function that returns a*cli.Command, with nestedCommandsfor subcommand groups - Register it in
cmd/lfx/main.go'sCommandsslice
// Package commands implements the lfx CLI subcommands.
package commands
import (
"context"
"fmt"
"github.com/urfave/cli/v3"
)
// NewExampleCommand builds the `lfx example` command.
func NewExampleCommand() *cli.Command {
return &cli.Command{
Name: "example",
Usage: "Brief description of what the command does",
Action: func(_ context.Context, cmd *cli.Command) error {
fmt.Println("example: not yet implemented")
return nil
},
}
}Every file in a package must start with the same // Package <name> ...
doc comment immediately above the package declaration. Revive's
package-comments rule itself only requires one such comment per package,
but MegaLinter's GO_REVIVE linter defaults to GO_REVIVE_CLI_LINT_MODE: list_of_files, invoking revive with a flat list of files instead of
./.... Under that mode revive loses per-package grouping and flags any
file lacking the comment, so duplicating the identical comment across
every file in a package is a required workaround for how MegaLinter calls
revive here, not an inherent revive requirement. Do not vary the wording
between files in the same package.
The hidden lfx docs command generates Markdown reference documentation
for all commands via cli-docs.ToMarkdown(), intended for local agent use
and for publishing to the gh-pages branch:
lfx docs # Print to stdout
lfx docs --output ./docs # Write to ./docs/cli.mdThe gh-pages branch is a static asset branch (not source code) served at
https://linuxfoundation.github.io/lfx-cli/. It holds:
install.sh-- the curl-style installer referenced in the READMEclient-metadata.json-- the CIMD (Client ID Metadata Document) for the LFX CLI's Auth0 Device Code client; this URL is the client_id (seeauth0-terraform'sclients_cimd.tffor the corresponding client definition)docs/cli.md-- generated CLI reference docs, republished on every tagged release by the Publish Tagged Release workflow'spublish-docsjob (see.github/workflows/release-tag.yml)
Only edit install.sh or client-metadata.json directly on gh-pages
when the install flow or CIMD metadata changes; docs/cli.md is
regenerated automatically and should not be hand-edited.
Releases follow semantic versioning (vMAJOR.MINOR.PATCH).
The current series is v0.x; do not increment the major version unless
explicitly instructed.
| Change type | Version component |
|---|---|
| Bug fixes, help text/schema wording tweaks, operational changes (CI, release config) | patch |
| New commands or substantial updates to existing commands | minor |
| Breaking changes or explicit instruction | major (only when told) |
Do not create or push git tags manually. Instead, use the GitHub
Releases UI (or gh CLI) to create a release; GitHub will create the tag
automatically, and the Publish Tagged Release GitHub Actions workflow
will run GoReleaser to build and publish multi-arch binaries.
# Determine the next version by inspecting the latest tag.
LATEST=$(git tag --sort=-v:refname | head -1)
echo "Latest tag: $LATEST"
NEXT=v0.1.1 # bump appropriately from the latest tag
gh release create "$NEXT" \
--generate-notes \
--latestAfter creating the release, verify that the Publish Tagged Release workflow triggered by the new tag completes successfully; otherwise release binaries may be missing even though the GitHub Release exists.
- Add Commands: Create new commands in
internal/commands/following the established pattern - Package Comments: Every new
*.gofile must include the same// Package <name> ...doc comment as the rest of its package - Code Quality: Run
make checkbefore commits - Documentation: Update README.md for user-facing changes