Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,24 @@ One table outside that file works the same way: `GROUPS` in
an entry outlives its command. A command it misses still shows, under
"Other", but CI will not let that ship.

## `commands search` and its query sets

`mapbox commands search` ranks commands by the words in their names,
summaries, descriptions, help-group lines and argument help, so **editing a
command's `about`, an argument's `help` or a line in `DESCRIPTIONS` changes
search results**, not only `--help`. The `eval_set_*` tests in
`src/commands.rs` run the query sets in `tests/fixtures/commands_search/` and
fail when a set ranks more than a few queries fewer right than its recorded
score. Each file's header says where its queries came from and how much the
search was tuned against them. `cargo test eval_set -- --nocapture` prints
the scores and every miss, and that directory's README explains each set and
how to read its score.

When a change raises a score, record it in the same commit. Dropping past the
slack is a decision to explain in the PR. Don't tune against the sets by
special-casing a query; fix the kind of miss. New real queries go in a new
file, so there is always one set the search has not been fitted to.

## What the tests can and cannot tell you

`cargo test` answers to fake tokens and a fake server. It runs offline, on a
Expand Down
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,15 @@ that may never merge. They are not releases and are not listed here.
from `tilequery get` and the renderer kept matching the old name.
`-o json` is unchanged.

- New `mapbox commands search "<task>"` finds the commands that match a
task, best first, and `mapbox commands list` lists every command with its
summary. Both are local keyword lookups: no request, no token. `json`
gives `[{command, summary, score}]`, where `score` (0 to 1) is how much
of the query the command's own text covers. The query is sent in telemetry as its length
only. Top-level help now points to `commands search` (agents see it in
their hint), and an unknown command with no near spelling suggests it in
the error's `fix`. No existing command or output changes.

- `mapbox usage` reads as a chart: one row per product with no blank
lines between, every sparkline as wide as the period, bars scaled from
zero so their height is proportional to the value, and the tallest
Expand Down
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ clap = { version = "4", features = ["derive", "env", "string", "wrap_help"] }
# top-level help, which src/help_layout.rs renders itself and so has to wrap
# to the terminal itself.
terminal_size = "0.4"
# Typo tolerance for `mapbox commands search`. Already in the graph through
# clap's own "did you mean" suggestions; the same version.
strsim = "0.11"
# Renders `mapbox completion <shell>` from the same `Command` tree everything
# else here is built from. Kept to the default features on purpose: the
# dynamic-completion half is `unstable-dynamic`, and value completion is out
Expand Down
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ mapbox styles list
- [Named profiles](#named-profiles)
- [Commands](#commands)
- [API commands](#api-commands)
- [Finding a command](#finding-a-command)
- [Diagnostics and settings](#diagnostics-and-settings)
- [Shell completion](#shell-completion)
- [Tileset CLI](#tileset-cli)
Expand Down Expand Up @@ -308,6 +309,17 @@ account it belongs to, alongside the event. With no token of your own and
no way to fetch the CLI's, the event is dropped.
`MAPBOX_CLI_NO_TELEMETRY=1` or `mapbox config set telemetry off` turns it off.

### Finding a command

```sh
mapbox commands search upload a font # the commands that match a task, best first
mapbox commands list # every command with its summary
```

Both are local keyword lookups over the CLI's own commands: no model, no
request and no token. Agents get the same matches as JSON. See
[Commands](./docs/commands.md#commands).

### Diagnostics and settings

```sh
Expand Down
135 changes: 135 additions & 0 deletions docs/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,9 @@ nests, and is typed `mapbox styles draft get`.
**[History](#history)** — [history.list](#mapbox-history-list) ·
[history.show](#mapbox-history-show)

**[Commands](#commands)** — [commands.search](#mapbox-commands-search) ·
[commands.list](#mapbox-commands-list)

**[Doctor](#doctor)** — [doctor](#mapbox-doctor)

**[Usage](#usage)** — [usage](#mapbox-usage)
Expand Down Expand Up @@ -4736,6 +4739,138 @@ Log no longer available: it expired or was removed to keep diagnostic logs

---

## Commands

Finding a command by what it does. Both read the same command surface
`mapbox --schema` describes, so they cover every command this build has,
and both are local: no request and no token. `json` gives each command as
`{command, summary}`, plus a `score` from `search`; `mapbox <command>
--schema` has the rest.

### `mapbox commands search`

The commands that match a task, best first. It is keyword matching, not a
model: each word of the query is matched against a command's name, summary
and description, its group's description and its arguments' help, with a
command's name counting most. A word can be a prefix (`geo`), a different
ending of the same stem (`geocoding` for `geocoder`) or one typo away
(`uplaod`), unless some command's text uses the word as it is: "match" is a
word, not a typo for "batch". A plural matches its singular. A few common
words stand in for the ones commands use ("remove" for "delete", "rename"
for "update").
Words like "how", "my", "to" and "mapbox" are ignored. It cannot find a
command whose text uses none of the query's words, so a query names the
action and the thing acted on: "upload a font", not "get my typeface onto
Mapbox". Matches far below the best one are left out. A task no command
does usually still comes back with a few weak guesses, so check the
summaries before running one.

Under `json`, each match has a `score` from 0 to 1: how much of the query
the command's own text covers. 1 means its name and summary use every word
of the query, a few tenths is a word found elsewhere, and under 0.1 is
barely a match. It is not a confidence, so don't use it as a cutoff: the
right command can score lower than a wrong one on another query.

The query can be quoted or not. One with no words at all, such as an
empty string, is a usage error (exit 2). No match is not an error: `text`
prints nothing and says so on stderr, `json` prints `[]`, and both exit 0. The
`commands` group itself is left out of the results. Telemetry records the
query's length, never its text.

#### Parameters

| Parameter | Effect |
| --- | --- |
| `<query>...` | What you want to do, in a few words. |
| `--limit <n>` | How many matches to show. Defaults to `5`; `0` shows every match. |

#### Examples

```sh
mapbox commands search upload a font

mapbox commands search "snap a gps trace to roads"

mapbox commands search tiles --limit 0
```

#### Outputs

<table>
<tr><th width="50%"><code>text</code></th><th width="50%"><code>json</code></th></tr>
<tr><td>

```
COMMAND SUMMARY
mapbox fonts upload Upload a font
mapbox fonts list List fonts for an owner
mapbox fonts delete Delete a font
```

</td><td>

```json
[
{
"command": "mapbox fonts upload",
"score": 1.0,
"summary": "Upload a font"
},
{
"command": "mapbox fonts list",
"score": 0.65,
"summary": "List fonts for an owner"
},
...
]
```

</td></tr>
</table>

### `mapbox commands list`

Every command with its summary, sorted by name.

#### Examples

```sh
mapbox commands list
```

#### Outputs

<table>
<tr><th width="50%"><code>text</code></th><th width="50%"><code>json</code></th></tr>
<tr><td>

```
COMMAND SUMMARY
mapbox accounts list-scopes List scopes
mapbox accounts list-tokens List tokens
mapbox accounts retrieve-token Retrieve a token
...
```

</td><td>

```json
[
{
"command": "mapbox accounts list-scopes",
"summary": "List scopes"
},
{
"command": "mapbox accounts list-tokens",
"summary": "List tokens"
},
...
]
```

</td></tr>
</table>

## Doctor

### `mapbox doctor`
Expand Down
Loading
Loading