4.3ReferenceMarkdown
agentlane.json
agentlane.json says what a lane of the project holds: the mobile app, the web app, the services and their ports, per-lane resources, hooks, preconditions, capture hygiene, the build cache and the driver. up, doctor and restart read it from the current folder or the ones above it, and agentlane schema prints its JSON Schema.
The setup skill writes this file for you. This page is for reading it and changing it by hand. The site builds each field table from the JSON Schema in the package, so the tables match the version they document.
Point $schema at the copy in node_modules and your editor checks the file as you type:
agentlane.json
{
"$schema": "node_modules/agentlane/schema/agentlane.schema.json"
}doctor's config line validates the file and names each field that breaks the schema. npx agentlane schema prints the schema. Every command in the file runs with sh -c in the folder that holds agentlane.json, with the lane's AGENTLANE_* variables, the values of its resources, and LANG and LC_ALL set to a UTF-8 locale: en_US.UTF-8 on macOS and C.UTF-8 on Linux. Environment variables lists what each command gets.
Top level
$schemastring- The path or URL of this schema, for editors.
appobject- The mobile app: what
upbuilds, installs and launches on the claimed simulator or emulator. webobject- The web app: the service that serves it and the page to open.
up --platform web(the default when there is no app) claims ports and no device, starts the services, and ends on doctor with the app's URL, also given to commands asAGENTLANE_WEB_URL. servicesobject by name- The long-running servers the app needs, by name. Each gets a claimed port in
AGENTLANE_<NAME>_PORT(the name upper-cased, dashes as underscores). resourcesobject by name- What each lane gets of its own besides ports, such as a database, by name.
upruns each create once per lane, in this order, after the setup hook and the build preconditions (also under--no-setup). The values a create exports then reach the lane's services, the hooks after setup, andagentlane exec, asAGENTLANE_<NAME>_PORTdoes; a command never takes an exported variable from the caller's environment. When the lane ends (release, the session-end release, or a reap of a lane whose owner died or was taken over), each teardown runs, last created first. hooksobject- Fields:
setup,build,launch,signin,teardown. preconditionsarray of object- Checks
upruns before any slow step. A failing check refuses with its fix. hygieneobject- Fields:
location,appearance. buildCacheobject- Lets the toolkit skip the native build when its inputs have not changed. The key also covers the platform, the build variant, the toolchain and the contents of the env file the build uses. The toolchain is the Xcode version for iOS. For Android it is the version of the JDK at
AGENTLANE_JAVA_HOMEor JAVA_HOME (else the JDK 17 the toolkit finds), which the build hook gets as JAVA_HOME, the Gradle distribution in android/gradle/wrapper/gradle-wrapper.properties when that file is not git-ignored (a generated wrapper follows the inputs that generate it, such as the lockfile), and the revision of every installed Android SDK build-tools, platform, NDK and CMake package. driverobject- The project drives its app with the toolkit (Maestro flows);
upanddoctorthen check for Java 17.
app
The mobile app: what up builds, installs and launches on the lane's simulator or emulator. app.ios and app.android hold what differs per platform, and replace bundleId, output and device when up runs for that platform.
app.platform"ios" or "android"required- The platform
upclaims a device for, unlessup --platformnames another. app.bundleIdstringrequired- The bundle id or package name.
app.schemestring- A URL scheme the app handles. It is approved on the simulator before it boots, so opening a link never stops at "Open in ...?".
app.launch"dev-client" or "bundler-pin" or "hook"required- How the app is launched. dev-client: an Expo dev client opened on the bundler with
--initialUrl. bundler-pin: a React Native app whose bundler location is written to its defaults and read back, then launched. hook: the project's launch hook. app.bundlerstring- The service the app loads its JavaScript from. Default: the only service of type metro.
app.variantstring- The build variant, given to hooks as
AGENTLANE_VARIANTand used by the build cache. Default:"Debug". app.outputstring- The app the build hook produces (an .app or .apk), relative to this file. The toolkit installs it. Leave it out when the build hook installs the app itself; the installed app is then read back for the cache.
app.deviceobject- Its fields follow.
app.device.typestring- A simulator device type, or an Android device profile such as pixel_8. Default: the newest iPhone the runtime supports, or pixel_8.
app.device.runtimestring- A simulator runtime, or an Android system image (a package id or an API level). Default: the newest installed iOS runtime, or the newest Google APIs image.
app.device.strictboolean- Take only a device of exactly this type and runtime. Without it, when the shared pool is full, a lane takes a free device of another type rather than deleting one to make this type. Default:
false. app.iosobject- What differs on iOS: these replace app.bundleId, app.output and app.device when
upruns for iOS. app.ios.bundleIdstring- The bundle id or package name.
app.ios.outputstring- The app the build hook produces (an .app or .apk), relative to this file. The toolkit installs it. Leave it out when the build hook installs the app itself; the installed app is then read back for the cache.
app.ios.deviceobject- Fields:
type,runtime,strict. app.androidobject- What differs on Android: these replace app.bundleId, app.output and app.device when
upruns for Android. app.android.bundleIdstring- The bundle id or package name.
app.android.outputstring- The app the build hook produces (an .app or .apk), relative to this file. The toolkit installs it. Leave it out when the build hook installs the app itself; the installed app is then read back for the cache.
app.android.deviceobject- Fields:
type,runtime,strict.
web
The web app: the service that serves it and the page to open. up --platform web claims ports and a browser, no device, starts the services and opens the page.
web.servicestring- The service that serves the web app. Default: the only service of type web.
web.pathstring- The page to open, on the service's port. Default:
"/". web.browserobject- The lane's own browser, which
upopens on the web app. Each lane gets its own profile folder, debugging port and driver session, released with the lane. The toolkit installs the driver and its browser at pinned versions in its own data folder (agentlane browser install). Drive it with the driver's own CLI underagentlane exec, which sets the driver's session, the web app's URL and the lane's saved login. The signin hook writes that saved login, in Playwright's storage-state format, to the file named by$AGENTLANE_STORAGE_STATE, and the browser starts with it.
web.browser
The lane's own browser. Browsers for web apps explains the drivers.
web.browser.driver"playwright" or "agent-browser"- playwright: Playwright's own CLI, playwright-cli, and Playwright tests run with
exec -- npx playwright test. agent-browser: Vercel's agent-browser CLI, headless. Both drive the toolkit's pinned Chrome for Testing. Default:"playwright". web.browser.headedboolean- Show the browser window, so a person can watch it. Default: headless. Playwright only: agent-browser runs headless, on the headless shell of Chrome for Testing. Default:
false.
services
The long-running servers the apps need, by name. A name is lowercase letters, digits and dashes, and it becomes the port variable: api-v2 gets AGENTLANE_API_V2_PORT. Ports and dev servers shows them in use.
services.<name>.typestringrequired- The port block the service's port comes from: metro, api, web, or a name of your own with
ports. services.<name>.ports[integer, integer]- [first, last]: the port block for a type of your own. The Mac's own blocks (metro, api, web, and any in its registry config) take precedence.
services.<name>.startstringrequired- The command that runs the server in the foreground on
$AGENTLANE_<NAME>_PORT. It is started in its own process group and logged to a file per lane. services.<name>.cwdstring- The directory to start it in, relative to this file.
services.<name>.platformsarray of "ios" or "android" or "web"- The platforms that need it, such as ["ios", "android"] for a bundler the web app does not use.
up,doctorandrestartfor another platform leave it out. Leave it out to run it for every platform. services.<name>.readyhttpReady or tcpReadyrequiredservices.<name>.timeoutSecondsnumber- How long to wait for the readiness check. Default:
60. services.<name>.dialobject- The app dials this service: launch it with this argument, so it talks to this lane's server.
services.<name>.dial.argumentstringrequired- The launch argument, such as -apiBaseUrl.
services.<name>.dial.valuestring- The argument's value; {port} is the service's port. Default:
"http://localhost:{port}".
ready
ready is one of two checks. An HTTP check:
ready.kind"http"requiredready.pathstringrequired- The path to GET.
ready.statusinteger- The status that means ready. Default:
200. ready.bodystring- Text the response body must contain.
ready.hoststring- The host the readiness check connects to. Default:
"127.0.0.1".
Or a TCP check, which passes when the port accepts a connection:
ready.kind"tcp"requiredready.hoststring- The host the readiness check connects to. Default:
"127.0.0.1".
resources
Data each lane gets its own copy of, such as a database, by name. up runs each create once per lane, in the order listed, after the setup hook. Teardowns run when the lane ends, last created first. A database per lane walks through one.
resources.<name>.createstringrequired- A shell command that makes the resource for this lane. It writes each value it exports as a NAME=value line (quotes around the value are removed) to the file named by
$AGENTLANE_EXPORTS. Its output goes to its log, and a failing create stopsupwith it. It runs again at the nextupwhen it failed or never finished, so it must cope with what a partial run left. resources.<name>.exportsarray of string- The variables create writes, such as DATABASE_URL. Create must write each of them and no other. Names starting with
AGENTLANE_, and LANG and LC_ALL, are the toolkit's. resources.<name>.teardownstringrequired- A shell command that removes the resource when the lane ends. What it runs is recorded when create starts: this command, its folder and its variables (the lane's, plus the values create exported), so it runs even after this file changes and after the session that made the lane died. When the folder is gone (the worktree was deleted), it runs in the lane's log folder. A failed teardown is kept and tried again at the next release or reap, so it must cope with a resource that is already gone.
resources.<name>.cwdstring- The directory create and teardown run in, relative to this file.
resources.<name>.teardownTimeoutSecondsnumber- How long teardown may run before it is stopped and counted as failed. Default:
120.
hooks
Shell commands the project owns. Each one reads the lane from the environment, runs without asking anything, and exits non-zero when it didn't do its job. up writes each hook's output to hooks/<name>.log in the lane's folder.
hooks.setupstring- A shell command run with
sh -cfirst, to install dependencies. hooks.buildstring- A shell command run with
sh -cto build the app for the claimed device. hooks.launchstring- A shell command run with
sh -cto launch the app when app.launch is "hook";AGENTLANE_LAUNCH_ARGSholds the dial arguments. hooks.signinstring- A shell command run with
sh -cafter launch, to sign in; for the web app it writes the lane's saved login, in Playwright's storage-state format, to$AGENTLANE_STORAGE_STATE. hooks.teardownstring- A shell command run with
sh -cbyagentlane release, after the services stop and before the resources' teardowns.
preconditions
Checks up runs before a slow step, each with the fix to print when it fails. Use one per tool a hook calls that the project doesn't install, one for the dependency install, and one per env file a hook needs.
preconditions[].namestringrequired- What is checked, as a short phrase.
preconditions[].runstringrequired- A shell command that exits 0 when the precondition holds.
preconditions[].fixstringrequired- What to do when it fails.
preconditions[].before"claim" or "build"- claim: checked before anything is claimed. build: checked after the setup hook, before the build. Default:
"claim". preconditions[].platformsarray of "ios" or "android" or "web"- The platforms it applies to. Leave it out to check it for every platform.
agentlane.json
{
"preconditions": [
{ "name": "CocoaPods is installed", "run": "command -v pod", "fix": "brew install cocoapods", "platforms": ["ios"] },
{ "name": "node_modules is installed", "run": "test -d node_modules", "fix": "run pnpm install", "before": "build" }
]
}hygiene
What capture hygiene sets on the lane's device. Leave it out for the defaults: the location 37.3349, -122.009, and light appearance. Simulators and emulators lists every step.
hygiene.locationobject- Its fields follow.
hygiene.location.latitudenumberrequiredhygiene.location.longitudenumberrequiredhygiene.appearance"light" or "dark"
buildCache
Lets up skip the native build when its inputs haven't changed. The build cache explains the key.
buildCache.inputsarray of object or objectrequiredbuildCache.cacheableVariantsarray of stringrequired- The build variants whose output may be stored and served. Leave out any variant that embeds its JS bundle, such as a Release build.
buildCache.envFilestring- An env file the build bakes in, relative to the config file's directory. Its contents enter the key; a missing file counts as absent. Use this for files git ignores, which a files input never sees.
buildCache.maxAgeDaysnumber- An entry unused for longer than this is pruned. Default:
14. buildCache.maxEntriesinteger- Only the most recently used entries up to this count are kept. Default:
6.
A files input
buildCache.inputs[].kind"files"requiredbuildCache.inputs[].pathsarray of stringrequired- Files, directories or globs (
*,**), relative to the directory holding the config file. Matched as git glob pathspecs over tracked files and untracked files git does not ignore; each enters the key by path, mode and content. buildCache.inputs[].excludearray of string- Files, directories or globs to leave out of
paths. buildCache.inputs[].platformsarray of "ios" or "android"- The platforms whose key includes this input. Leave it out to include it for every platform.
A command input
buildCache.inputs[].kind"command"requiredbuildCache.inputs[].runstringrequired- A shell command run with
sh -cin the config file's directory, with the lane's environment. Its stdout enters the key; a non-zero exit means no key, so the build runs uncached. buildCache.inputs[].platformsarray of "ios" or "android"- The platforms whose key includes this input. Leave it out to include it for every platform.
driver
driver.flowsstring- The folder of committed flows, relative to this file.
With a driver block, up and doctor check for Java 17, and maestro under exec is agentlane's Maestro build on the lane's device.