This file provides guidance for AI agents working with the salesforce-cli codebase.
salesforce-cli is a command-line interface for Salesforce written in Go. It uses OAuth 2.0 for authentication with secure token storage in the system keychain.
Binary name: sfdc
Module: github.com/open-cli-collective/salesforce-cli
# Build
make build
# Run tests
make test
# Run tests with coverage
make test-cover
# Lint
make lint
# Format code
make fmt
# All checks (format, lint, test)
make verify
# Install locally
make install
# Clean build artifacts
make cleansalesforce-cli/
├── cmd/sfdc/main.go # Entry point
├── api/ # Public Go library (Salesforce REST API client)
│ ├── client.go # Client struct, HTTP helpers
│ ├── types.go # Data types (SObject, QueryResult, etc.)
│ └── errors.go # Error types and parsing
├── internal/
│ ├── cmd/ # Cobra commands
│ │ ├── root/ # Root command, Options struct, global flags
│ │ ├── initcmd/ # sfdc init (OAuth setup wizard)
│ │ ├── configcmd/ # sfdc config {show,test,clear}
│ │ └── completion/ # Shell completion
│ ├── auth/ # OAuth 2.0 implementation
│ │ ├── auth.go # GetHTTPClient, token exchange
│ │ └── config.go # Credential paths
│ ├── config/ # Configuration file management
│ ├── keychain/ # Secure token storage
│ │ ├── keychain.go # Cross-platform interface
│ │ ├── keychain_darwin.go # macOS Keychain
│ │ ├── keychain_linux.go # Linux secret-tool
│ │ ├── keychain_windows.go # Windows fallback
│ │ └── token_source.go # PersistentTokenSource wrapper
│ ├── errors/ # Shared error types
│ ├── version/ # Build-time version injection
│ └── view/ # Output formatting (table/json/plain)
├── .github/workflows/
│ ├── ci.yml # Build, test, lint on PR/push
│ ├── auto-release.yml # Create tags on main push
│ └── release.yml # Build and release binaries
├── packaging/
│ ├── chocolatey/ # Windows Chocolatey package
│ └── winget/ # Windows Winget manifests
├── snap/ # Snap package (name: ocli-sfdc)
├── Makefile # Build, test, lint targets
├── .goreleaser.yml # Cross-platform builds
└── .golangci.yml # Linter config
Uses OAuth 2.0 Web Server Flow with automatic token refresh:
- Tokens stored in platform keychain (macOS Keychain, Linux secret-tool)
- Falls back to
~/.config/salesforce-cli/token.jsonwith 0600 permissions PersistentTokenSourceautomatically persists refreshed tokens
Commands use an Options struct for dependency injection:
type Options struct {
Output string // table, json, plain
NoColor bool
Stdin io.Reader // Injectable for testing
Stdout io.Writer
Stderr io.Writer
}Each command package exports a Register function:
func Register(rootCmd *cobra.Command, opts *root.Options) {
cmd := &cobra.Command{
Use: "config",
Short: "Manage configuration",
}
cmd.AddCommand(newShowCmd(opts))
rootCmd.AddCommand(cmd)
}Use the View struct for formatted output:
v := view.New(opts.Output, opts.NoColor)
v.Table(headers, rows) // Table output
v.JSON(data) // JSON output- Unit tests in
*_test.gofiles alongside source - Use
testify/assertfor assertions - Table-driven tests with
t.Run() - Use
httptest.NewServer()to mock API responses - Use
t.TempDir()for file operations
Run tests: make test
Coverage report: make test-cover && open coverage.html
Variables are checked in precedence order (first match wins):
| Setting | Precedence |
|---|---|
| Instance URL | SFDC_INSTANCE_URL → SALESFORCE_INSTANCE_URL → config |
| Client ID | SFDC_CLIENT_ID → SALESFORCE_CLIENT_ID → config |
| Access Token | SFDC_ACCESS_TOKEN (direct, bypasses OAuth) |
Use conventional commits:
type(scope): description
feat(query): add SOQL query command
fix(auth): handle token refresh errors
docs(readme): add installation instructions
| Prefix | Purpose | Triggers Release? |
|---|---|---|
feat: |
New features | Yes |
fix: |
Bug fixes | Yes |
docs: |
Documentation only | No |
test: |
Adding/updating tests | No |
refactor: |
Code changes that don't fix bugs or add features | No |
chore: |
Maintenance tasks | No |
ci: |
CI/CD changes | No |
Releases are automated with a dual-gate system:
Gate 1 - Path filter: Only triggers when Go code changes (**.go, go.mod, go.sum)
Gate 2 - Commit prefix: Only feat: and fix: commits create releases
This means:
feat: add command+ Go files changed → releasefix: handle edge case+ Go files changed → releasedocs:,ci:,test:,refactor:→ no release
Key dependencies:
github.com/spf13/cobra- CLI frameworkgithub.com/fatih/color- Colored terminal outputgolang.org/x/oauth2- OAuth 2.0 clientgithub.com/stretchr/testify- Testing assertions
Base URL pattern: https://{instance}.my.salesforce.com/services/data/vXX.0/
Key endpoints:
/services/data/- API versions/services/data/vXX.0/query?q=SELECT...- SOQL queries/services/data/vXX.0/sobjects/- Object operations/services/data/vXX.0/sobjects/{Object}/describe- Object metadata