carlos / platform Public

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:

  1. carlos versions -app <a> — list an app's shipped releases.
  2. carlos promote with 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 canary

None 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 channels does: through the console API when signed in, straight at the bucket when CARLOS_DEPLOYMENT_BUCKET/_DIR is set.
  • Naming: versions reads naturally beside channels, though it collides conceptually with the existing carlos version (build id). releases avoids 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 register and init both 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.