No way to list an app's shipped versions; promote should offer a picker when none is given Feature Request open
Migrated from github.com/carlosframework/platform issue #83, opened 2026-08-07. GitHub issues are closed for this repo; see AGENTS.md, "Work is tracked on amadan, not GitHub".
Still outstanding: carlos promote still hard-requires a version argument; it should offer a picker when none is given (carlos releases already solved discovery).
---
Summary
There is no way to ask "what versions of this app have I shipped?" from the CLI. A version that has been shipped but not yet promoted is invisible to every verb, even though it is the thing you are about to promote.
Two requests, one small and one that follows from it:
carlos versions -app <a>— list an app's shipped releases.carlos promotewith no<version>should offer a picker rather than failing on usage.
Why
The complete top-level verb list today is:
version edge add remove route instances ship promote channels rollback
ledger auth accounts apps env secrets release-keygen ops status agent
bootstrap adopt vet canaryNone of them lists shipped versions. The closest are:
carlos channels -app <a>— only versions that have been promoted (channel → version).carlos instances— only the version each route has adopted, and only on the box you run it on.
So the set "shipped but not promoted" — which is precisely every release between ship and its first promote — has no representation in the CLI at all. The only authority is the bucket, at apps/<sqid>/<app>/releases/<version>/, which means reaching for an S3 client. Per CLAUDE.md that is the definition of a product gap:
> If a day-to-day task has no API/CLI command, that is a product gap, not a > license to drop to AWS: plan and build the command (or file the gap) > instead of working around it.
How it shows up
A first-time user on a fresh self-hosted deployment shipped an app, saw it listed as shipped in the web console, and then found carlos channels empty and nothing serving. The question "what did I actually ship, and what is the version string I now have to type?" had no CLI answer — the version had to be read out of the console UI or the bucket.
This is a first-run path: it happens between someone's first ship and their first promote, i.e. to everyone, once.
1. carlos versions -app <a>
Suggested output — the useful columns are the ones that tell you what is safe to promote and what is already live somewhere:
VERSION SHIPPED TARGETS CHANNELS
b918b56 2026-08-07T11:02:14Z linux-amd64 —
dd87bf6 2026-08-06T20:52:03Z linux-amd64 canary/first- A
—in CHANNELS is the interesting case: shipped, pointed at by nothing. - Should work in both modes, like
channelsdoes: through the console API when signed in, straight at the bucket whenCARLOS_DEPLOYMENT_BUCKET/_DIRis set. - Naming:
versionsreads naturally besidechannels, though it collides conceptually with the existingcarlos version(build id).releasesavoids that at the cost of matching the bucket path rather than the word users say. Either seems fine; flagging the collision rather than picking.
2. promote with no version should offer a picker
Today:
usage: carlos promote -app <a> [-hotfix] [-account …] [-console …] <version> <channel>Omitting <version> is a usage error (cli.go:1673). Since the CLI would now be able to list versions, the friendlier behaviour is to show them and let the user choose — the same shape miren cluster add uses when given no cluster.
$ carlos promote -app echo canary/first
1) b918b56 shipped 2026-08-07T11:02:14Z (no channels)
2) dd87bf6 shipped 2026-08-06T20:52:03Z canary/first
choose a version:Two constraints worth respecting:
- Only when interactive. With no TTY it must keep failing loudly on usage, never prompt into a void. (Miren's
server registerandinitboth render nothing without a TTY, which turns a normal prompt into an apparent hang — a good example of the failure mode to avoid.) - The ladder still gates the choice. Picking a version from a list must not become a way around
edge's "nothing is promoted onto edge" rule or beta/stable's ordering; the picker chooses the version, not the gate.
Related
Same first-run surface as #79 and #81.