AGENTS.md · juggler-ai/juggler
AGENTS.md from juggler-ai/juggler: 309 lines covering Build / Test / Lint / Dev, Linting, Tests, Git commits and more.
Template by juggler-ai
Chalk Labs
Need help deploying AGENTS.md · juggler-ai/juggler?
Chalk Labs sets up agents like this inside real teams: connected to your tools, tested on your data, with a human in the loop where it matters.
Install
Works with Codex, Cursor, GitHub Copilot, Gemini CLI, OpenCode, Claude Code. Read the repository before you give any tool access to your data.
curl -fsSL https://raw.githubusercontent.com/juggler-ai/juggler/develop/AGENTS.md -o AGENTS.md
Read it and adapt it to your project before use.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Use cases: code-generation, testing
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
What's in it
An AGENTS.md file: instructions coding agents (Codex, Cursor, Copilot, Gemini CLI and others) read before working in a repo.
- For
- Codex, Cursor, GitHub Copilot, Gemini CLI, OpenCode, Claude Code
- Length
- 309 lines
- File
AGENTS.md
Sections
- Build / Test / Lint / Dev
- Linting
- Tests
- Git commits
- Changelog
- Conventions
- Architecture
- Web UI
- Debugging the viewer
- Paths
- Vendored forks
First lines (shown under the repo's AGPL-3.0 license)
# Juggler ## Build / Test / Lint / Dev ```bash make build # Lint + build Go binaries (bin/juggler, bin/juggler-app, bin/juggler-test) make test # All tests (unit + integration + browser); RUN='<name>' runs one make go-build # Build Go binaries only (skip linting) make test-full # Lint + tests. Run before opening a PR. make lint # All linters (Go + JS + CSS) — the only way to lint everything make fix # Auto-fix what the linters can (gofmt, eslint/stylelint --fix); then re-lint make dev # Build and run server make build-windows # Cross-compile bin/windows/*.exe (pure-Go, no cgo) ``` `make test-full` (lint, build and every test) **must** pass before any task is complete; iterate with `make test RUN='<name>'`. `make build` is for launching the app — `make test` already builds everything it tests. ### Run them in the foreground They are ordinary commands that take a few minutes (`make test` is typically 3–6). Run the bare command with a timeout long enough to cover it — 20 minutes — and wait for it to finish. **Never** start a build or test run as a background task, poll it, watch it with a monitor, wait on its pid, or loop until the process exits. It gains nothing: you get the identical output several turns later, having spent those turns guessing an interval — too short burns turns, too long stalls the task, and "wait for the process to disappear" wedges on the first thing that outlives it. If a run genuinely exceeds the timeout, that is a hang worth reporting, not a reason to relaunch it detached. **Never pipe them through `tail`, `head`, `grep` or `tee`, redirect them to a file and read it back, or append `|| true`.** The output is already the summary (see Tests below), and `tail` is the worst choice of the lot: a failure is written top-down, so truncating to the tail keeps the summary line you already had and cuts the assertion that says what broke. ## Linting - **`make lint` and `make lint-files` are the only sanctioned ways to lint.** Never invoke `golangci-lint`, `go vet`, `gofmt`, `eslint`, or `stylelint` directly — every config, flag, ignore pattern, and pinned tool version lives in the `Makefile` / `scripts/lint-files`, and a hand-rolled invocation silently diverges from what CI enforces. - To lint specific files (routed by extension to the same linters): ```bash make lint-files FILES="cmd/juggler/worker/foo.go web/js/bar.js" ``` - **Before fixing lint failures by hand, run `make fix`** — it applies every auto-fix the linters can (gofmt, `golangci-lint --fix`, `eslint --fix`, `stylelint --fix`) using the same configs and globs as `make lint`, then tells you to re-lint. It never fixes type errors (lint-types), dead code (lint-deadcode), or missing imports in the docs' JavaScript examples (lint-docs) — those still need a human. `make fix` and `make fix-files` are the only sanctioned ways to auto-fix; don't run `gofmt -w`, `eslint --fix`, or `stylelint --fix` directly (same drift reason as lint). Per-file: ```bash make fix-files FILES="cmd/juggler/worker/foo.go web/css/bar.css" ``` ## Tests - `make test` runs the whole suite (Go unit + integration + browser) without `-v`, so its output already is the summary: one `ok <pkg> <time>` line per passing package, and on failure only the failing tests' own output. Each layer announces itself, the first failing layer stops the run — so a failure is the last thing on screen — and a `✗` line under it names the layer. The same text is teed to `bin/test*.log` purely for afterwards; the log and the terminal hold the same thing, so there is nothing to tail or grep. - **To run one specific test, pass `RUN='<regex>'`** — a `go test -run` pattern matched against test-function names. It also turns on `-v` so you see that test's own output, and silences the packages that hold no matching test (which under `-v` would otherwise announce themselves and bury the one you asked for). This is the sanctioned way to iterate on a single test; **don't run `node`, the browser harness, or `go test` by hand** — the target builds the right binary, sets the flags CI uses, and tees the log for you. ```bash make test RUN='TestDiffView' # one test, whichever layer it's in make test RUN='TestDiffView/collapsed' # one subtest make test-go RUN='TestWorker' # restrict to the fast unit layer ``` - Browser tests launch `bin/juggler-testsrv --assets-from-disk`, serving the local `web/` tree. That is the test-capable server `make test` builds beside the app (`make test-build` on its own), stamped `-test` so a server a suite spawned says so when it talks to the update endpoint; `bin/juggler` stays the app you launch. Once it exists, web-only edits don't need a rebuild — rerun `make test RUN='<name>'` (Go builds are incremental, so this is cheap). Rebuild only for Go / embedded-asset / build-file changes. - Browser-test lanes share one offscreen pool window. They do not reliably paint, so a test must not await `requestAnimationFrame` or a post-layout `ResizeObserver` delivery; exercise a synchronous seam instead. Lane viewport width also varies by platform and may cross the 36rem phone breakpoint, so geometry that depends on a breakpoint belongs in an explicitly sized iframe. - rAF delivery in a lane is platform-split: frames never arrive on macOS or Linux (WebKitGTK), but Windows (WebView2) delivers them — so product code deferred through `requestAnimationFrame` is exercised only on Windows CI. Test such behaviour by calling the deferred function directly. - The pool is `JUGGLER_TEST_WINDOWS` subprocesses x `JUGGLER_TEST_IFRAMES` lanes, and the lanes inside one subprocess share a single content process — one JS heap, one main thread. Raising iframes while dropping windows to 1 serialises the suite onto that thread and produces cascades of arbitrary timeouts. - **A lane is an iframe, and the lanes in one window share a single session history.** A `pushState` or `back()` in any lane traverses that joint history and delivers the `popstate` to whichever lane's entry it popped — so one lane closing a menu could dismiss the overlay another lane had just opened. Nothing in a lane may touch `window.history` casually: the overlay Back-button sentinel (`popup-manager.js`) stands down unless the app owns the history (`window.top === window`), and the two suites that test it switch it on for their own duration via `__setBackIntegrationForTests` while stubbing the History API. **A test must never traverse the real one**, however carefully it balances its own entries: a sibling lane loading its next test page puts an entry on top of the shared stack, so the `back()` lands on the sibling — which is sent back a document — and this lane is delivered no `popstate` at all. A stub answering with a `popstate` of its own, in a later task, reproduces everything a real traversal was there to show. - **Model limits go stale silently. `TestCatalogDrift` is how you find out.** Providers publish new models and retire old ones constantly, and a wrong context window has no symptom — the model works and merely compacts far sooner than it needed to. The audit compares what each provider serves right now against what the built-in catalogs say, using whatever keys you have configured, and names the providers it had to skip: ```bash JUGGLER_MODELS_AUDIT=1 make test-go RUN='TestCatalogDrift' ``` It is opt-in (one network call per provider) and skipped in `make test`. Run it after any vendor announcement, and before a release. The no-network half, `TestCatalogInvariants`, runs every time and checks every catalogued model for limits that cannot be right. - Suite timings are load-sensitive. A browser test that fails in a full run and passes alone is not a regression in the code it asserts on — re-run the exact subtest in isolation before investigating it. It is not automatically "just load" either: that shape has twice turned out to be a real harness fault that only a busy machine reaches. - **Every wait in a test rides the per-test deadline** (`budgetFor` / `deadlineFor` in `web/js-tests/utilities/test-deadline.js`), never a bare nominal timeout of its own. A number chosen when a lane had the pool to itself measures the pool rather than the code once nine lanes share a machine. `unit:test-budget` asserts this contract; add a case to it when you add a wait. - A wait whose expiry does not itself fail the test — one that answers a dialog or a prompt something else is blocked on — must record why it gave up. Silence there turns a missed deadline into a hang that gets reported much later, against whatever was in flight at the time. ## Git commits - Commit messages: **one line, minimal, past tense** (e.g. `Fixed cross-conversation cancel leak`). ## Changelog - Add entries under `[Unreleased]` in `CHANGELOG.md` as you make user-facing changes; release tooling rolls that section into a dated version section when a release is cut. - **Each release is a single flat list of changes** — no `Added`/`Changed`/ `Fixed` subsection headers. - **Entries are terse one-liners**: ~12 words, the user-visible headline only. Match the length of the existing entries. ## Conventions
Signals
- Stars
- 804
- Forks
- 55
- Open issues
- 12
- Last commit (this folder)
- Oct 19, 2026 (11 days ago)
- Last release
- Oct 23, 2026 (8 days ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- AGPL-3.0
- Repository
- github.com/juggler-ai/juggler
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
More from juggler-ai
Done for you
Rather not set it up yourself?
Chalk Labs scopes, builds and runs agents for your team: the task audit, the eval harness, the integrations and the weekly ops report. Fixed scope, priced before we start.
See how we build AI agents →Read the case studies
Chalk Labs is a two-founder AI and growth studio. We build AI agents, CRMs and MVPs for Web3 and AI companies, and have shipped 50+ product and token launches.
- launches shipped
- 50+
- launches shipped
- media placements
- 500+
- media placements
- founders on every account
- 2
- founders on every account
Press we've placed: Forbes · CoinDesk · Decrypt · Cointelegraph · The Block
Rahil Jain, Co-founder, Chalk Labs. Ex-Goldman Sachs engineer. You talk to the person who builds it.
Get AGENTS.md · juggler-ai/juggler running in your business
Tell us what you want to automate. A founder replies within one working day with a plan, not a pitch deck.
Cite this page
AGENTS.md · juggler-ai/juggler. Agent Mart. https://agentmart.dev/templates/juggler-ai-juggler-agents-md (last updated 2026-10-24)