Skip to content

v3.0.0

Choose a tag to compare

@github-actions github-actions released this 16 Oct 16:34
· 63 commits to main since this release
ef6e313

ATC 3.0.0

  • No more shell commands. atc exec -- ./gradlew … is gone. You now write atc exec gradle tasks assembleDebug, and ATC builds and runs the real command itself.
  • 34 built-in operations for Gradle, Bazel, Xcode, adb, simctl and 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 --brief output replaces build-brief.
  • Breaking: 2.x exec commands, atc guard, command-array batch plans and coordinateBuilds no longer work. See Upgrading.
Agent sends a request to ATC; ATC validates it, then either runs the real command under the build slot, workspace lock and device lease, or rejects it with exit code 7.

Upgrading

  1. npm install -g @rock3r/atc@3
  2. 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/xcodebuild calls until you do.
  3. Replace atc exec -- … in prompts, skills and scripts with the new syntax below. Multi-step sequences go in atc batch plans.
  4. Drop atc guard calls and the coordinateBuilds setting.

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.

Three-step batch: assemble runs with no device, install claims a phone, launch reuses it, and the phone is released after launch.

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: 7 means ATC rejected the request and ran nothing (2.x used 2 for this; 2 now only means busy). 124 means the operation hit its timeoutSec.
  • --brief on build operations replaces build-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, --phase and coordinateBuilds are removed.
  • Hooks now only track the agent session and free its leases when it ends. They no longer inspect shell commands, so a raw adb or ./gradlew call 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