Skip to content

feat(cli): add short aliases to every resource command - #52

Open
mateuscardosodeveloper wants to merge 12 commits into
feat/tagosql-commandsfrom
feat/command-aliases
Open

mateuscardosodeveloper wants to merge 12 commits into
feat/tagosql-commandsfrom
feat/command-aliases

Conversation

@mateuscardosodeveloper

@mateuscardosodeveloper mateuscardosodeveloper commented Aug 24, 2026

Copy link
Copy Markdown
Collaborator

Summary

Gives every resource command a short alias on one scheme: a family prefix plus a two or three character verb. 77 aliases across 10 families, saving about seven characters per command.

tagoio en-ls                 tagoio entity-list
tagoio fl-up ./report.pdf    tagoio files-upload ./report.pdf
tagoio sq-run <id>           tagoio sql-execute <id>
tagoio dv-tkn <id>           tagoio device-token <id>
Family Prefix Count Sample
actions act- 7 act-ls, act-on, act-off
dictionaries dc- 6 dc-ls, dc-lng
secrets se- 5 se-ls, se-nf
run users ru- 5 ru-ls, ru-crt
analysis an- 5 an-ls, an-dlt
access management am- 5 am-ls, am-crt
TagoSQL sq- 8 sq-ls, sq-tbl, sq-rev
devices dv- 7 dv-crt, dv-tkn
entities en- 8 en-ls, en-dt, en-sch
files fl- 9 fl-ls, fl-prm, fl-dl

Verbs: ls nf crt ed dlt cp dt sch on off lng tbl rev run tkn prm tp up dl url mv rn.

Why

Reviewing the stacked series, the tech lead noticed the new commands had no aliases while shipped ones did (device-list has dl). Only 11 of the 41 new commands carried one, and the gap was uneven inside the series itself: access-management aliased all five of its commands, analysis CRUD aliased none.

entity-* and files-* predate the series and had never had an alias, so they are included rather than left as a second gap.

Naming decisions that took a call:

  • act- for actions, not ac-. The bare ac is analysis-console in the published package, so an ac-* family would put actions and analysis under one prefix. Costs one character on seven aliases.
  • act-on / act-off instead of shortening enable and disable. An earlier draft had adis and adel, two characters apart, one reversible and one not.
  • sq- for TagoSQL, replacing sql-ls and sql-run. Reusing the command's own sql- prefix saved almost nothing: sql-v against sql-version is one keystroke. The family now has one convention.
  • Two suffixes look like collisions and are not. fl-dl is a different string from dl (device-list), and fl-prm shares its suffix with dv-prm only across families, never within one.

Not aliased: init, login, set-env, list-env, whoami, data, copy-tab, backup, and the four backup subcommands. They run 4 to 8 characters against a 12.5 average for the aliased set, and several already are the short form. data is the shorthand for device data.

Test plan

  • npx vitest run: 1754 tests passing, 166 files
  • npx tsc --noEmit clean, npm run linter clean, npx oxfmt no rewrites
  • npm run build passes
  • New guard in src/lib/alias-registry.test.ts: 80 tests covering no duplicate token per scope, no alias shadowing a command name, and every expected pair registered
  • Guard proven by deliberate breakage: removed an alias (fails naming the command), added an undeclared alias to backup list (fails the table check). The non-recursive first version passed that second case
  • All 12 published aliases still resolve: ac ad am at bkp deploy dl export info inspect nc run
  • All 22 renamed aliases return unknown command
  • 15 alias-to-command mappings spot-checked across every family, including en-dt, fl-prm, sq-rev, act-off
  • Duplicate sweep, three independent ways: full tree walk including nested backup subcommands (178 tokens, 101 names, 77 aliases, 0 duplicates in any category), straight from the source files (77 aliases, no overlap with command names), and the CLI booting, since commander throws at registration on any duplicate
  • EXPECTED_ALIASES matches the tree exactly: 77 declared, 77 registered, no difference in either direction
  • Man snapshot moves 14 lines, all of them help example text; no command name or option shifted

Breaking changes

Eleven aliases are renamed: al, sl, rul, dl-list, sql-ls, sql-run, and the five am-* forms.

Every one exists only in this stack's open PRs. Checked master directly: none has been released, so no caller on npm can depend on them. The 12 aliases that do ship in 3.3.0 are untouched.

Keeping the old names would have shipped two competing formats, which is the inconsistency this PR exists to remove.

Risk (CIA)

Likelihood: 🟢 Low | Impact: 🟢 Low | Exposure: 🟢 Low

Additive alias registration plus 11 renames confined to unreleased branches. A duplicate cannot ship silently: commander throws at registration, so a collision fails the suite and the build. No command name, option, or handler changes.

Related

The README command table is rebuilt here as well. It listed roughly 20 of 89 commands, missing actions, dictionaries, secrets, run-users, access-management, sql, entities, and files entirely, so it was stale before this branch. Regenerated from the command tree in the existing shape.

That matters more than it looks: --help shows only the first alias per command (configure-help.ts calls help.alias(), singular), the man page records none, and there is no shell completion. The README table is the only complete inventory.

An independent design review argued for about 9 aliases instead of 77, on the grounds that the savings are thin and a uniform alias removes the signal al used to carry next to a bare action-info. The uniform scheme was chosen because consistency was the ask, and the short-verb format answers the strongest half of that objection: seven characters saved rather than the three the first draft managed. Recorded so the trade-off stays reversible.

Base is feat/tagosql-commands (#49). Merge that one first.

Seven aliases on a scheme shared by every family: a prefix plus a two or
three character verb. `act-ls`, `act-nf`, `act-crt`, `act-ed`, `act-on`,
`act-off`, `act-dlt`.

The prefix is `act-`, not `ac-`, because the bare `ac` is analysis-console
in the published package. An `ac-*` family would put two resources under
one prefix.

`act-on` / `act-off` rather than shortening enable/disable: a two-letter
difference between a harmless flag and its opposite is the kind of pair
that gets typed wrong.
`dc-ls`, `dc-nf`, `dc-crt`, `dc-ed`, `dc-lng`, `dc-dlt`.

Replaces `dl-list`, which was one character away from `dl` (device-list)
while pointing at an unrelated resource.
`se-ls`, `se-nf`, `se-crt`, `se-ed`, `se-dlt`. Replaces `sl`.
`ru-ls`, `ru-nf`, `ru-crt`, `ru-ed`, `ru-dlt`. Replaces `rul`.

`run-user-` is the longest prefix in the CLI, so these save the most: nine
characters on `run-user-create`.
`an-ls`, `an-nf`, `an-crt`, `an-ed`, `an-dlt`.

The six older commands in this namespace keep their published word
aliases: deploy, run, at, ac, ad, am. Renaming any of those would break
callers on npm.

Also drops the comment saying analysis-list could not have an alias
because `al`, `am`, `at`, `ac` and `ad` were taken. The prefixed scheme is
what resolves it, so the comment now records the reasoning instead of the
refusal.
`am-ls`, `am-nf`, `am-crt`, `am-ed`, `am-dlt`, replacing `am-list`,
`am-info`, `am-create`, `am-edit` and `am-delete`.

Those five were the first prefixed aliases in the CLI and set the pattern
this scheme follows; only the verb half changes. The help examples move
with them, since an example naming an alias that no longer resolves is
worse than no example.
`sq-ls`, `sq-nf`, `sq-crt`, `sq-ed`, `sq-run`, `sq-dlt`, `sq-tbl`,
`sq-rev`.

Replaces `sql-ls` and `sql-run`, which shared the command's own `sql-`
prefix and so saved almost nothing — `sql-v` against `sql-version` is one
keystroke. Moving the family to `sq-` gives it one convention instead of
two, and the help examples follow.
`dv-crt`, `dv-ed`, `dv-dlt`, `dv-tkn`, `dv-prm`, `dv-tp`, `dv-cp`.

The five published aliases in this namespace are untouched: dl, info,
inspect, bkp, nc.

`dv-` rather than `de-` or `dc-`: dictionaries already holds `dc-`, and
`dl` shows how fast a single letter after `d` stops being readable.
`en-ls`, `en-nf`, `en-crt`, `en-ed`, `en-dlt`, `en-dt`, `en-sch`, `en-cp`.

First aliases this family has had.
`fl-ls`, `fl-up`, `fl-dl`, `fl-url`, `fl-mv`, `fl-rn`, `fl-cp`, `fl-dlt`,
`fl-prm`.

First aliases this family has had.

Two suffixes look like collisions and are not: `fl-dl` is a different
string from `dl` (device-list), and `fl-prm` shares its suffix with
`dv-prm` (device-param) only across families, never within one.
Commander throws at registration on a duplicate — an alias colliding with
another alias or with a command name — which takes the whole CLI down at
startup rather than failing just the new command. The `al` and `am` near
misses were caught only because the man test happens to build the tree.

This makes the check explicit, asserting on the built program rather than
on the generated roff: the man page never records aliases, so the two
assertions in generate-man.test.ts match help example text and would stay
green if an alias were deleted. Their comments now say so, and point here.

The walk recurses, because `backup` nests four subcommands. Collisions are
per-scope: commander resolves a token against the containing command's own
list, so `backup create` and a top-level `create` could coexist. A flat
scan would both miss a collision under `backup` and invent ones that
cannot happen.

Proven by removing an alias and by adding an undeclared nested one — the
first fails naming the command, the second fails the table check.

The snapshot moves with the renamed aliases in the access-management and
sql help examples: fourteen lines, all of them example text.
The table listed roughly twenty commands out of eighty-nine, missing
actions, dictionaries, secrets, run-users, access-management, sql,
entities and files entirely — it was already stale before this branch.

Rebuilt from the command tree, keeping the existing shape: `alias, command`
terms, bold section headings, and the nested backup subcommands.

Nothing reads this file in CI, but with seventy-seven aliases it is the
only complete inventory outside `--help`, which shows just the first alias
per command.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant