Documentation menu
Dashboard & analytics
Managed runners
Team & notifications
Billing & plans
Workflow files
Latchkey CLI changelog
What each release of the Latchkey CLI added, changed and fixed, newest first, from 0.3.0 on.
In short
- Every Latchkey CLI release from 0.3.0 on, newest first, with what it added, changed and fixed.
latchkey versionprints the version you have, andnpm install -g @latchkeydev/cliupgrades to the newest.
Each entry lists what a release of the Latchkey CLI (@latchkeydev/cli and the standalone latchkey binaries) changed for you and your coding agents, dated the day it was published, in UTC. Run one-off jobs from the CLI describes the commands as they work today.
0.17.0#
Released 2026-11-13.
Added#
latchkey workflows rerun <run-id> --repository <owner/name>runs the jobs of a Latchkey CI run that did not pass again, with every job that needs one of them, as a new attempt of the same run at the same commit, and prints the attempt and the run's page. Every other job that passed is not run or billed again, and the command does not wait for the attempt. A job bound to an environment that needs an approval waits for one, unless it is held in a trial run or a pipeline on trial, or its environment does not accept the run, and the command names those environments on stderr, as far as Latchkey can still read them from an earlier attempt. With--output jsonit prints one object withrun_id,attempt,allocated,run_urlandwaits_for_approval, andcodeRERUN_NEEDS_APPROVALwith its sentence inmessagewhen that list names any. A refusal prints its sentence on stderr and exits 1. It needs a key withruns:control.latchkey workflows cancel <run-id> --repository <owner/name>cancels every job of a Latchkey CI run's current attempt that has not finished, through the one cancel pathlatchkey canceluses, and the jobs it had not created yet are never created. It prints the attempt and the run's page, and with--output jsonone object withrun_id,attempt,cancel_requested,not_createdandrun_url. A refusal prints its sentence on stderr and exits 1. It needs a key withruns:control.latchkey runandlatchkey preflightnow say on stderr when the batch a job is started under, by--batchorLATCHKEY_BATCH, has no budget, with the command that sets one (latchkey budget set <batch> <dollars>), and the job still starts. Nothing is said when Latchkey could not read the budget or the batch's spend, since the batch may still have a budget, andlatchkey preflight --batch-budgetnever says it. With--output json,latchkey runprints no line: thecreatedevent's newbatch_budget_statusreadsset,noneorunread, and is null when the job has no batch.
Changed#
- The bundled skill now covers
latchkey workflows rerunandlatchkey workflows cancel, and the MCP toolsrerun_runandcancel_run, where it said nolatchkeycommand takes a run id and no key can cancel a whole run. - The bundled skill now says a
healsentry belowstage3 withcategoryflaky_testis self-heal's flaky-test re-run, which ran the failed step again unchanged, so itsoutcomefixedmeans the re-run passed, not that anything was fixed.
Fixed#
latchkey workflows --helpand the bundled skill now say a job thatlatchkey workflows runstarts and that is bound to an environment that needs an approval waits for one, unless it is held in a trial run or a pipeline on trial, or its environment does not accept the run, where they made a trial run the only exception.
0.16.0#
Released 2026-11-11.
Added#
latchkey preflight --workflow <file> --repository <owner/name>runs the jobs of one workflow file, as Latchkey compiles it, on your working tree as it is now, before you commit or push it. The repository is packed whole, from its top level, by the rules oflatchkey run, and the change is measured against the merge base ofHEADand the default branchorigin/HEADnames, as this clone last fetched it. Before any runner starts, each job is judged: it runs as written, it runs its dry run, it is skipped by its own condition or for a job it needs, it fails before it starts, or it is not run, with a reason, such as a job that reads a secret, since a preflight is handed none. A preflight paints no check, opens no pull request, starts no self-heal and saves no cache entry. It exits 0 only when no job failed, none was left not run, and a job ran, and 195 only when it left a job not run, or ran no job, and every job it ran passed or was skipped by its own condition or for a job it needs;latchkey preflight --helplists the rest. With--output jsonit prints one object once its run has ended. When git cannot say what the change is, it is refused withCLI_GIT_UNREADABLEand nothing is sent. It needs a key withjobs:run, and a repository connected to Latchkey CI.
Changed#
latchkey waitcan now print that self-healjudged step 3's failure flaky and re-ran the step unchanged, thenit passed, or that itre-ran step 3 unchanged in case its failure was flaky, thenthe re-run did not make the step pass, where it said self-heal fixed the step or could not fix it, and theSelf-healrow oflatchkey statuscan say the same.- The bundled skill now covers
latchkey preflight, including the run it answers, whichlatchkey workflows listnever lists, and says a job's own check, such asLatchkey / ci.yml / test, can show as queued or in progress while its job waits or runs, where it said Latchkey writes no pending check. - A key that starts with
lk_dev_is from Latchkey's dev environment and is no longer sent to the prod API (api.latchkey.devorlatchkey.dev): the command stops before anything is sent and exits 1 withCLI_API_KEY_WRONG_ENVIRONMENT. A key that starts with neitherlk_live_norlk_dev_still only warns.
Fixed#
- When
latchkey runreads the files git tracks, it now sets git's filesystem monitor empty, notfalse: a git before 2.36 runsfalseas a program found onPATH, where a relative entry can find one in the repository being packed. A directory namedgitonPATHno longer stops that read, and on Windows every variable whose name starts withGIT_orLATCHKEY_, in any case, is kept out of git's environment. - The README and the bundled skill now give the compressed size ceiling as 200 MiB, the bound the CLI has always held, where they said 200 MB.
- The bundled skill now says a job held in its workflow file's
concurrency:group (JOB_HELD_IN_GROUP) can end without starting if a newer run joins the group first, where it said it ends without starting: the newer run cancelled before Latchkey ends the held job leaves it waiting. - An API key from
--token,LATCHKEY_TOKENor the saved config is now trimmed of the spaces, tabs and line breaks around it before it is checked and sent, andlatchkey login --tokensaves it trimmed, or stops withEmpty API key.and exits 2 when the key is only whitespace, where it exited 1. A key ending in a line break, such as aLATCHKEY_TOKENset with a trailing newline, no longer stops the command withinvalid authorization header, and anlk_live_key with whitespace before it no longer draws the warning that it does not start withlk_live_.
0.15.0#
Released 2026-11-09.
Added#
latchkey workflows list --repository <owner/name>, with--commit <sha>or--pr <number>, lists the Latchkey CI runs of a commit, named by its full id, or of a pull request over the last 90 days, newest first. With--output jsonit prints one object withrepository,runsandtruncated, each run the object the MCP toolget_run_statusanswers. With more than 50 runs it exits 1 withLIST_TRUNCATED, unless--allow-truncatedtakes the newest 50. It needs a key withjobs:read.latchkey wait --commit <sha>andlatchkey wait --pr <number>, with--repository <owner/name>, wait on Latchkey CI runs instead of jobs: the runs at a commit, named by its full id, or a pull request's runs at its newest commit. When the runs end it prints a table of them and exits 0 if each one succeeded or was skipped, 1 otherwise, and with--output jsonit prints onerun_endedevent per run, then asummaryevent. It exits 194 withRUN_NOT_EXPECTEDwhen the repository is not connected to Latchkey CI, or when every run it follows ended with no job because no workflow file matched, and 197 withRUN_WAIT_LIMIT_REACHEDwhen its last look before it gave up met Latchkey's limit on the waits it holds for a workspace at once.
Changed#
- Before a command sends its key, it prints
Latchkey API: <host>on stderr, naming the host the key goes to, once a process and in json mode too, so a key pointed at the wrong environment shows before anything answers. Onlatchkey runandlatchkey watch,--quietleaves it off. - The bundled skill now covers finding the runs of a commit or a pull request with
latchkey workflows listandlatchkey wait --commitor--pr, and with the MCP toolslist_runsandwait_run. latchkey watch --helpnow gives the exception the bundled skill already gave: on GitHub Actions, the one re-run of a failing test that Latchkey allows while the workflow has an open flaky-test finding is not escalated when Latchkey could read the failing tests from the test runner's report and the re-run failed the same way, so the run surfaces once, under its one id.
0.14.0#
Released 2026-11-06.
Changed#
latchkey migrate plannow prints a pipeline already on trial asOn trial, where it printedStays, and the help no longer sayslatchkey migrate applyneeds the repository in advisory mode: it needs the repository connected to Latchkey CI. Latchkey opens such an apply for any version of the CLI. The bundled skill's refusals ofmigrate applynow name a plan that moves a pipeline already on trial, in place of a repository not in advisory mode.latchkey watch --helpand the bundled skill now saylatchkey watchpolls the failures self-heal recorded but did not fix and hands off the first new failure of each job (of each run on Latchkey on GH), and that a failure whose step self-heal refused to read carries no root cause or failing file. The prompt it hands your agent now says self-heal recorded the failure but did not fix it, and thatget_failure_bundlereturns what Latchkey kept of it. Only the words changed:watchpicks the failures it hands off by the same rule as 0.13.0, from the list Latchkey returns to any version of the CLI.
0.13.0#
Released 2026-11-04.
Added#
latchkey list --state activelists only the jobs still on their way: every queued, provisioning or running job, up to 100, newest first, however many newer jobs have finished.--batchnarrows it, and--beforeand--limitare refused, since it is read whole rather than a page at a time. With--output jsonit printsjobsandtruncated, true when more than 100 were on their way, and in text a line on stderr says so. A Latchkey API that cannot read the jobs still on their way would answer with jobs in every state, so it is refused withCLI_LIST_FILTER_UNSUPPORTEDand nothing is listed.--state all, the default, lists every job as before.
Changed#
- The bundled skill now covers reading what is still on its way with
latchkey list --state active, and itsCLI_LIST_FILTER_UNSUPPORTEDrow names--state active.
0.12.0#
Released 2026-11-04.
Changed#
- When
latchkey runrefuses an empty directory, it now says what to do: run from your project's directory, or pass--no-contextfor a command that needs no files. The bundled skill'sCLI_CONTEXT_EMPTYrow names the flag too. - With
--output json,latchkey list,latchkey batch showandlatchkey statusalways holdrun_id, the Latchkey CI run a job belongs to, andserved_by, how it got its runner (warm,parkedorcold_start), eachnullwhen Latchkey sends none. A CLI from 0.4.0 on already prints both when Latchkey sends them, and the text output has not changed. - The bundled skill now says to split a suite through the package's own
testscript (npm test -- --shard=2/4), so every shard runs the package'spreteststeps as CI does. It also covers moving to Latchkey CI: a run reads only the secrets set in Latchkey, never a GitHub secret of the same name, so an owner or admin carries them over before the switch pull request merges, and once it merges, a moved pipeline is read from the commit's Latchkey checks,get_run_statusorlatchkey list, because GitHub Actions no longer runs it. - The bundled skill now names
merge_groupamong the events a workflow file runs on: each group a merge queue builds, matched on the branch the group targets.
0.11.0#
Released 2026-11-03.
Changed#
latchkey migrate plannow says a moving job bound to an environment waits for an owner or admin to approve it once its pipeline runs live, where it used to say in a live run. In a repository on Latchkey CI, a pipeline runs on trial, even inside a live run, while the GitHub Actions file it replaces is still at the commit.- The bundled skill now says that
failure_explanationnames the first step that failed, and that step's exit code when it has one, on a workflow-file job that failed withfailure_reasonnull, and that output the CLI cannot write never changes its exit code. It also covers pipelines on trial inside a live run: whatadvisory:does in their jobs, thefailure_explanationstartingHeld on trial:of a held job,list_trial_verdictsnaming inworkflow_paththe pipeline on trial each entry compares, andget_run_statussaying intrialwhy some of a run's pipelines ran on trial.
Fixed#
- A full disk under a redirected stdout or stderr no longer makes the CLI exit 1, which reads as a failed job: when either stream cannot be written, the CLI exits with the code it would have given. It drops the rest of its stdout and, unless the reader went away (
| head), says so once on stderr, and it drops what it cannot write to stderr without a word. A log it could not write is still on the job, andlatchkey logs <id>reads it again.
0.10.0#
Released 2026-11-02.
Added#
latchkey workflows run <workflow> --repository <owner/name>starts a run of a Latchkey CI workflow file that declareson: workflow_dispatch, at the repository's default branch or at the branch or tag--refnames, with the file's inputs given as--input <name=value>. It prints a link to the run's page without waiting for the run, and running it again starts a second run, billed as its own. The key needs theworkflows:runscope. An input is recorded on the run and shown on its page, and a job's log does not hide it, so never put a token or password in one.latchkey budget set <batch> <dollars> --max-concurrent <n>limits how many of a batch's jobs run at once, a whole number from 1 to 1000. The rest wait in the queue and start as the batch has room. An API key can set a batch's first limit or lower it, never raise or remove it, andlatchkey budget showprints the limit.
Changed#
latchkey statusshows a Self-heal row for each self-heal attempt on the job that fixed a failure or could not, andlatchkey runandlatchkey waitprint each as a line after the job's outcome. When self-heal's agent reported a fix but the job ended without passing, the line says the fix was reported, not made. With--output json,run'scompleteevent andwait'sendedandsummaryevents carry the job'shealslist asstatusprints it.- The bundled skill now covers starting a workflow file with
latchkey workflows runor therun_workflowMCP tool, pacing a burst of jobs with its batch's limit, why a batch job can wait behind Latchkey CI jobs near the workspace's limit, reading heal records and trial verdicts over MCP (list_heals,get_healandlist_trial_verdicts), splitting a test suite across matrix legs, and what self-heal reads from an uploaded working tree. - The npm package's homepage is now the Latchkey CLI documentation page, and its README links this changelog.
0.9.0#
Released 2026-10-28.
Added#
latchkey oidc request-token --audience <audience>gets a short-lived identity token for your cloud from inside a job of a Latchkey CI run. It prints the token, or with--out <file>writes it to a file only its owner can read. Likelatchkey cache, it talks to the job's runner and needs no API key.latchkey validate <file>checks a workflow file the way Latchkey compiles it for a run, without starting anything. A refused file prints its first refusal with its line; a file that compiles prints its jobs and the most one run of the file can cost at list rates. It exits 0 when the file compiles and 1 when it is refused.
Changed#
- The standalone binaries now embed Node 24, so the macOS binaries need macOS 13.5 or newer. On older macOS, install with npm.
latchkey environments listadds an Approval column saying whether an environment's jobs wait for an owner or admin to approve them.latchkey migrate plansays when a moving job bound to an environment will wait for an approval in a live run, and, for a pipeline that stays on GitHub Actions but runs after one that moves, whether it stops running or runs less often once the switch pull request is merged.- A batch named
.or..alone is refused by every command that takes a batch name (exit 2).
Fixed#
- An
--envvariable named__proto__is now sent with the job instead of being dropped.
0.8.0#
Released 2026-10-27.
Changed#
- A batch name can no longer hold
/or%.latchkey run,latchkey listandlatchkey waitnow refuse one, including one set inLATCHKEY_BATCH, before reaching Latchkey (exit 2), aslatchkey budgetandlatchkey batch showalready did.
0.7.0#
Released 2026-10-26.
Changed#
latchkey migrate planmarks a step whose dry-run command the plan refused: its "Needs a person" line gives the reason, and the item stays open until you answer with a command the workflow file can run.- The answers file for
latchkey migrate plan --answers <file>can give adry_runanswer with adry_run_command, which the plan writes as a trial-run step in place of the answered one. - The bundled skill now covers trial runs (
advisory:on jobs and steps),concurrency:groups in workflow files, and thelatchkey/artifact-uploadandlatchkey/steps.artifact-download
0.6.0#
Released 2026-10-24.
Added#
latchkey waitwaits until the jobs you name, or every job of a batch with--batch <name>, have ended, printing each outcome as it ends and then a table of state, exit code, run time, cost and batch. It exits 0 only when every job exited 0, and Ctrl-C stops the wait, never a job.latchkey batch show <name>shows one batch: its budget, what its jobs have cost at list rates, its jobs by state and why its queued jobs wait.latchkey budget show <batch>prints the budget and spend alone.latchkey environments list --repository <owner/name>lists the branches each environment of a repository accepts.latchkey listtakes--batch <name>for one batch's jobs and--before <value>to page further back, shows a COST column, andlatchkey statusshows a finished job's cost.- When a newer CLI is out, a command printing text says so on stderr, at most once a day and never in CI. Set
LATCHKEY_NO_UPDATE_NOTICEto turn it off.
Changed#
- Inside a git work tree,
latchkey runpacks every file git tracks, even one a.gitignorepattern matches, as a fresh clone would have it. The credential deny list,--excludeand.latchkeyignorestill apply, and--no-git-indexpacks by the.gitignorefiles alone. - Every refusal carries a code. With
--output json, a refused command prints one object with its code, and the bundled skill lists every code. latchkey runrefuses a leadingbash -corsh -c(exit 2), since that shell would run only the first word of its script. Pass the script as one quoted argument instead.
0.5.0#
Released 2026-10-24.
Added#
latchkey artifact uploadandlatchkey artifact downloadpass files between the jobs of one Latchkey CI run. A failed upload or download exits 1, so the step fails, and an upload leaves out dot-files such as.envunless you pass--include-hidden-files.latchkey migrate plan <owner/name>reads a repository's GitHub Actions workflow files and prints its plan for moving to Latchkey CI, with each item that needs your answer.latchkey migrate applyopens the one pull request that adds the Latchkey CI workflow files, andlatchkey migrate statusshows where it stands.latchkey stepslists the Latchkey steps a workflow file can name withuses: latchkey/<name>@<version>, with their inputs and defaults.
Changed#
- A job whose run an owner or admin rejected for its environment exits 130 from
latchkey runandlatchkey logs --follow, as a stop rather than a failure to fix.
0.4.1#
Released 2026-10-19.
Fixed#
- The help text, README and bundled skill now match how 0.4.0 behaves: the exit codes list
skipped(exit 1), logs stay readable for 7 days from when the job started, andlatchkey cacheworks only inside a Latchkey CI job or alatchkey runjob. latchkey budget sethelp says an API key can set a batch's first budget up to the workspace's spend limit, and that an owner or admin raises a budget on the Billing page.
0.4.0#
Released 2026-10-19.
Added#
latchkey run --context <dir>packs another directory instead of the current one, and--exclude <pattern>holds paths back without editing a file. No--excludepattern can ship a file the credential deny list blocks.latchkey run --budget <dollars>stops a job once it has cost that much (exit 3), and--batch <name>orLATCHKEY_BATCHputs jobs in a batch.latchkey budget set <batch> <dollars>caps a batch. Alatchkey runrefused at its batch's budget exits 193 and creates no job.latchkey cache restoreandlatchkey cache saverestore and save a cache entry from inside a job. No cache condition fails the job.latchkey secrets set <name>sets a secret a workflow step can read, for the workspace or one repository. The value comes from a pipe or a hidden prompt, never the command line.
Changed#
latchkey runprints a link to each job's page in the dashboard, andlatchkey watchlinks a failure to its Latchkey run page.latchkey statusshows more when Latchkey sends it: running and queued jobs against the workspace's limit, the jobs ahead of a queued job and why it waits, the cost so far, its batch, key and budget, when it last wrote output, and what ended it.latchkey listadds BATCH and KEY columns.--timeoutaccepts up to 3 hours, and a job's logs stay readable for 7 days from when it started.latchkey run --detachexits with the job's mapped code when the submit already ended the job, askippedjob exits 1, and every--output jsonevent carriesat.
Fixed#
- Text from Latchkey that reaches your terminal is stripped of control, text-direction and invisible format characters, and a failure reason a job reported itself is shown as the job's own words.
0.3.0#
Released 2026-08-15.
Added#
latchkey listlists your workspace's recent jobs, newest first, including the ones still running, so you can recover a job id that scrolled away.
Changed#
latchkey watchalso reportslatchkey runjobs that self-heal recorded but did not fix, and every failure it prints carries its root cause and failing file when one was recorded.
Fixed#
- When the log tail of
latchkey runorlatchkey logs --followgives up after repeated network errors, the CLI checks the job once more and exits with its own code if it finished, where it used to exit 1. - The log tail catches up faster on a backlog of colored or non-ASCII output.