Repository navigation
v3.0.0
ATC 3.0.0
- No more shell commands.
atc exec -- ./gradlew …is gone. You now writeatc exec gradle tasks assembleDebug, and ATC builds and runs the real command itself. - 34 built-in operations for Gradle, Bazel, Xcode,
adb,simctland emulator snapshots, available from the CLI and as MCP tools. - Bad input is rejected before anything runs (exit code
7), with a fix suggested for each problem. - Batch plans hold a device only for the steps that need it, and later steps can reuse it.
- Build coordination is always on: one build per workspace, shared build slots, RAM checks.
- Built-in
--briefoutput replacesbuild-brief. - Breaking: 2.x
execcommands,atc guard,command-array batch plans andcoordinateBuildsno longer work. See Upgrading.
Upgrading
npm install -g @rock3r/atc@3- Update the ATC plugin/hooks in your agent (Claude Code, Codex, Copilot, Cursor, Antigravity, Gemini CLI, Pi). The 2.x hook will keep blocking
adb/gradle/xcodebuildcalls until you do. - Replace
atc exec -- …in prompts, skills and scripts with the new syntax below. Multi-step sequences go inatc batchplans. - Drop
atc guardcalls and thecoordinateBuildssetting.
The migration guide covers every changed command.
Note
Hooks from 2.x may be causing issues until you fully upgrade to 3.x following the steps above.
Batch plans
Steps are now typed operations instead of command arrays, so 2.x plans won't load. Each step can have dependsOn, cwd, env and a claim, and a step can borrow an earlier step's device with "claim": { "reuse": "<step>" }. The device is held only for the steps that use it.
atc batch --file plan.json --validate prints the exact command for each step without running anything.
Validation and --force
Bad input is rejected up front, with every problem listed at once:
$ atc exec gradle tasks "bad;name" -x
[atc] Request rejected (2 problems):
/tasks/0: "bad;name" is not a Gradle task name or path (e.g. assembleDebug, :app:test).
→ If this value is legitimate, re-run with --force --reason "<why>" …
/tasks/1: "-x" is not a Gradle task name or path (e.g. assembleDebug, :app:test).
→ This value cannot be overridden. Request support at https://github.com/rock3r/atc/issues …
If a Gradle task, Bazel label or Xcode name is legit but unusual, pass --force --reason "<why>". Forced runs show up in atc status --forced. --force can't add new operations, pass values starting with -, or skip claims, locks or RAM checks.
Other changes
- Exit codes:
7means ATC rejected the request and ran nothing (2.x used2for this;2now only means busy).124means the operation hit itstimeoutSec. --briefon build operations replacesbuild-brief: full log goes to<stateDir>/logs/, you get a short summary.- Build coordination is always on: one build per workspace, a shared pool of build slots, RAM checks.
--build,--phaseandcoordinateBuildsare removed. - Hooks now only track the agent session and free its leases when it ends. They no longer inspect shell commands, so a raw
adbor./gradlewcall from an agent runs uncoordinated.
atc claim, free, renew, status, snapshot, gc, config and guide are unchanged.
New atc exec syntax
| 2.x | 3.0 |
|---|---|
atc exec --build -- ./gradlew assembleDebug |
atc exec gradle tasks assembleDebug |
atc exec --claim "--type phone" -- ./gradlew connectedDebugAndroidTest |
atc exec gradle tasks connectedDebugAndroidTest --claim --type phone |
atc exec -- bazel test //app:tests --config=ci |
atc exec bazel test //app:tests --config ci |
atc exec -- xcodebuild -scheme App test |
atc exec xcode test --scheme App |
atc exec -- adb install -r app.apk |
atc exec android install app.apk --replace |
atc exec -- xcrun simctl launch booted com.ex.App |
atc exec ios launch com.ex.App |
There are 34 operations across Gradle, Bazel, Xcode, Android, iOS and emulator snapshots; atc exec --help lists them. MCP clients get the same set as atc_gradle, atc_bazel, atc_xcode, atc_android, atc_ios, atc_snapshot and atc_batch.
Need something that isn't covered? Take a lease with atc claim and run the tool yourself against the leased serial/UDID. ATC just won't coordinate that call.
Full changelog: v2.1.0...v3.0.0