Skip to content

Latest commit

 

History

History
124 lines (81 loc) · 14.4 KB

contributing.md

File metadata and controls

124 lines (81 loc) · 14.4 KB

Development workflow

Contributor docs · Setup and first contribution

After building the CLI, use this page to choose checks and prepare a change.

Development loop

Run the smallest relevant example while implementing, then run the required checks once the change is complete.

go run ./cmd/agnostic-ai validate
go run ./cmd/agnostic-ai list
go run ./cmd/agnostic-ai sync -t claude --dry-run

Use a temporary project when experimenting with imported or generated files. Adapter tests should pass a small bundle to Emit, then read the resulting files back from disk.

Choose checks for your change

Review the whole diff against the PR base, including tests, fixtures, generated files, and embedded inputs. Run the checks in every applicable row below.

  • Documentation, audit data, and source instructions use the focused checks for their changed inputs. Do not add a full local gate only to validate prose.
  • Adapter, shared Go, or runtime behavior changes require make ci-local, plus applicable checks below that it does not cover. Unknown impact uses this full gate too.
  • Classify test-only and fixture-only changes by the behavior they exercise. Rerun the affected checks; tests and fixtures for adapter, shared Go, or runtime behavior still require the full gate.
  • Run expensive local checks serially, including across workers and worktrees. Use focused reproductions during diagnosis, then run the selected gate once the change set is complete. Check each command's own exit code, never a filtering pipe.
Change Checks
Adapter, shared Go, runtime behavior, or unknown impact make ci-local; focused package and integration tests for the acceptance scenario
Inner edit loop, before the checks above make test-short: skips end-to-end and timing tests, so it never replaces a gate
Concurrency make test-race (included in make ci-local)
Dependencies (go.mod) or binary size make size-check (included in make ci-local); raise scripts/binary-size-budget only when the growth is worth it, and say why in the PR
Shell scripts or CLI end-to-end behavior make test-shell (included in make ci-local, requires bashunit on PATH at the BASHUNIT_VERSION in ci.yml)
Project setup, branch changes or package versions go test ./tests/integration -run TestProjectLifecycle -count=1; Linux and macOS CI plus Windows smoke
Config struct or schema fields go run ./cmd/schemagen; review the updated schema and include it
Project source specs or adapters go run ./cmd/agnostic-ai validate, go run ./cmd/agnostic-ai lint, then go run ./cmd/agnostic-ai sync and go run ./cmd/agnostic-ai sync --check; review tracked output changes and keep ignored output ignored
Adapter output Adapter tests and relevant saved expected output files (golden fixtures), including integration and round-trip tests; preview with sync --dry-run and follow capability fixtures when support changes
Playground or code used by WebAssembly (WASM) make playground-build, then make playground-serve and exercise affected behavior in a browser; see playground development
Documentation or audit data Check relative links, anchors, and changed data against its consumers; run existing checks for affected data and execute changed command examples in a temporary project
Docs site (docs/site/) make site-serve to preview, then make site-check and make site-test, with the pinned Zola; count skipped tests, not only the exit code. See Docs site
Editor extension Use Node.js 22+ for VS Code builds; follow its development guide and CI job

make preflight covers formatting, lint (including govet), and Go tests. It is useful during development but does not replace the full gate above. make test and make test-race run scripts/test-go.sh, which splits internal/cli into shards that run at the same time. make ci-local adds race tests, the CLI and WASM builds, the WASM tests, schema drift, source lint, shell tests, binary size, and editor checks. Use SKIP_JETBRAINS=1 only when Java or Gradle is unavailable (mise install gets the pinned JDK), report the skip, and require JetBrains CI when its inputs changed. make ci-local skips the Web client job, govulncheck, the VS Code package step, the JetBrains plugin build and the pull-request-only plugin version-bump job. Neither command replaces applicable site checks or required remote CI.

Record the commands, results (including failures and skips), tested commit or tree, and relevant working-tree, generated, embedded, or external inputs. Include toolchain versions and environment limits that affect the result, without secrets. A binary used for sync must match its source and embedded inputs; rebuild it or use go run after those inputs change.

Reuse manual results only when their inputs and environment still match. A commit SHA alone cannot establish that for uncommitted files, stale binaries, or external inputs. After changing code, tests, or fixtures, or after a rebase, merge, or review fix, rerun the checks whose inputs changed.

All selected checks must pass before pushing. Missing tools, skipped tests, and pending or absent required CI are limits to resolve, not green checks. Before merging, wait for required checks on the current PR head and the remote OS checks below when applicable. Audit fixers stop at reviewable PRs; merging requires an explicitly authorized merge workflow. Releases still require the full local and remote gates in cut-release.

The project lifecycle tests use a generated project with 500 entries, temporary clones and linked checkouts, and a local test installer. They check initial setup, installation using saved package versions, branch changes, project checks, and migration plans that leave files unchanged. They do not connect to coding tools or call a model. On Windows, the launcher tries to save a failed command's result outside the project. Follow-up checks have time and output limits.

To investigate first-launch failures without the large project, run go test ./tests/integration -run '^TestProjectLifecycle_FirstLaunchAfterFreshInstall$' -count=1 -v. This installs into eight separate small projects and stops at the first setup error. It uses the same test installer and Windows launcher. Passing runs do not explain an earlier failure.

make lint names the problem when golangci-lint is missing or not the pinned version; rerun make tools after the required version changes. A linter older than your Go toolchain can report a type-checking failure in files you never touched.

Pull requests and pushes to main run the Go tests on Linux only, in six parallel jobs: internal/cli and tests/integration split by test name, and every other package together. The required Test (ubuntu-latest) check passes only when all six pass. Nightly and manual runs add the full macOS suite and a focused Windows smoke check. Windows smoke covers fresh package startup, handoff hooks, paths, import, and linked checkouts without the race detector. Its whole job stops after seven minutes, including setup. Dispatch gh workflow run ci.yml --ref <branch> for these checks before releases and when a branch touches paths, file watching, renames, permissions, or import. The full Windows Go race suite is optional and manual only: add -f full_windows=true. It runs in shards split by package and test name, and each shard stops after ten minutes. Linux and macOS Go jobs also stop after ten minutes. Windows OpenCode and editor jobs keep their native tests and stop after seven minutes. Editor jobs on pull requests run when their source or dependencies change.

Docs site

The site is Zola, and zola --version must match ZOLA_VERSION in the Makefile exactly. site-serve, site-check, and site-build refuse a different version. mise install gets the pinned Zola from mise.toml. To run the pinned build without mise or without replacing your install, download that release and put it first on PATH:

gh release download v0.23.6 --repo getzola/zola --pattern '*aarch64-apple-darwin.tar.gz'
tar xzf zola-v0.23.6-aarch64-apple-darwin.tar.gz
PATH="$PWD:$PATH" make site-serve   # http://127.0.0.1:1111

A mismatched Zola does not fail go test ./... locally; it skips the seven site build tests. Run make site-test with the pinned binary before trusting a change under docs/site/. Pull request CI installs the pinned Zola in the integration i-z shard and sets AGNOSTIC_AI_REQUIRE_ZOLA=1, which turns those skips into failures.

make site-serve and make site-build generate current target counts from adapters.Names() and config.DefaultTargets(). The generated docs/site/data/targets.toml supplies the landing page counts; docs/site/static/llms.txt comes from docs/site/llms.txt.tmpl. After changing registered targets, defaults, or the text template, run make site-generate and commit the generated files. make site-check and make site-test reject missing or stale output without rewriting it.

The social preview image is rendered from docs/site/og/card.html. After editing the card, run make site-og (it needs Chrome or Chromium; set CHROME if it is not found). Platforms cache the image by URL, so a redesign ships under a new file name: change the default output path in scripts/render-og-image.sh so make site-og renders there, and update image_url in docs/site/config.toml and the image tags in docs/playground/index.html.

A long reference page can be split into a topic index (a hub): a folder with an _index.md (template = "docs/hub.html", hub = true) and one page per topic, such as cli-reference/ and spec-format/. Link to a topic page as @/docs/<hub>/<page>.md#anchor. The hub redirects old #anchor links from before the split to the topic page that now holds them. Add new hubs to the sitemap and llms-full.txt lists in scripts/.

Update Zola and docs/site/templates/ in a separate change: bump ZOLA_VERSION in the Makefile, .github/workflows/playground.yml and .github/workflows/ci.yml, and zola in mise.toml, with the template edits, and compare _site/ built on both versions.

Conventions

Topic Convention
Format gofmt; use goimports for import grouping
Dependencies Prefer the standard library; justify new dependencies
Adapters Stateless, constructed with New(); no imports between target packages
Shared output code Put it in internal/adapters/internal/emit/
Tests Behavior names; t.TempDir() and testutil.Chdir(t, dir) for filesystem tests; no external mocking libraries
Errors Wrap with file or operation context and %w
Scope One concern per PR; separate unrelated refactors

Generated project configuration

The repository's .agnostic-ai/ specs generate root entry points and tool folders. Most output is ignored; .openhands/setup.sh is tracked for initial setup. Edit specs and review any tracked output change after syncing.

After a sync, Claude Code, Codex and Gemini CLI format each Go file they edit with gofmt -s -w, through the gofmt-on-edit hook. It runs on macOS and Linux; it has no Windows command. It needs ./agnostic-ai from make build, or agnostic-ai on PATH. It formats files in this checkout and in other worktrees of this repository. The hook skips files it cannot format and never fails an edit, so make fmt-check stays the gate.

The repository's output ignore block is maintained by hand. Preserve hierarchical patterns such as **/AGENTS.md and the !internal/adapters/*/testdata/** exception that keeps saved expected output files (golden fixtures) tracked. Add new adapter paths to .gitignore.

CI lints source specs. It does not run sync --check against a fresh checkout because generated files are not committed. After generating locally, sync --check can confirm local output matches the specs.

Write documentation people can use

Start with the reader's task, one complete example, and a clear next action. Explain a term where the reader first needs it. Keep each fact on one canonical page and link to it from related guides.

Cut repeated benefits and cautions. Put edge cases in a named disclosure or focused reference page, while keeping limits that affect the example visible. Preserve the details in HTML and agent exports, and keep old links pointing to relevant content.

Verify examples in a temporary project. Describe what the generated files prove separately from what the coding tool does at run time.

Documentation checklist

Keep tutorials focused on one working outcome. Put optional workflows in task guides and field details in references. Link to the main explanation instead of copying tables or setup instructions. Preserve existing page paths and section anchors when reorganizing docs.

Before submitting

Review the diff for unrelated edits and generated files. Describe the final behavior and the checks you ran in the PR. Record design choices that need an explanation in the decision log.

Read build dependency checks for package integrity, repeating vendor load checks, and the evidence needed to review security alerts.