Document TUI controls, category synonyms, flag aliases, and compare JSON
AGENTS.md: - Add command table covering all five commands - Expand input tolerance section with flag alias table - Add filtering/sorting, auto JSON, and structured error sections - Include canonical examples for compare README.md: - Expand compare command docs with ranking explanation and --count flag - Replace tui stub with full keybinding reference (tab, /, s, g, c, a, l, r, [/], 1-9, u/d, b/f, ?, q) - Add compare-specific flags section and sort alias note - Add category synonym table showing all bidirectional mappings - Add flag alias resolution table (zipcode->zip, dept->department, etc.) - Add compare JSON schema documenting all response fields Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
38
AGENTS.md
38
AGENTS.md
@@ -2,16 +2,52 @@
|
|||||||
|
|
||||||
The `pubcli` CLI is intentionally tolerant of minor syntax mistakes when intent is clear.
|
The `pubcli` CLI is intentionally tolerant of minor syntax mistakes when intent is clear.
|
||||||
|
|
||||||
|
## Commands
|
||||||
|
|
||||||
|
| Command | Purpose | Requires |
|
||||||
|
|---------|---------|----------|
|
||||||
|
| `pubcli` | Fetch deals | `--store` or `--zip` |
|
||||||
|
| `pubcli stores` | List nearby stores | `--zip` |
|
||||||
|
| `pubcli categories` | List categories with counts | `--store` or `--zip` |
|
||||||
|
| `pubcli compare` | Rank nearby stores by deal quality | `--zip` |
|
||||||
|
| `pubcli tui` | Interactive deal browser | `--store` or `--zip`, interactive terminal |
|
||||||
|
|
||||||
|
## Input Tolerance
|
||||||
|
|
||||||
Accepted flexible forms include:
|
Accepted flexible forms include:
|
||||||
- `-zip 33101` -> interpreted as `--zip 33101`
|
- `-zip 33101` -> interpreted as `--zip 33101`
|
||||||
- `zip=33101` -> interpreted as `--zip=33101`
|
- `zip=33101` -> interpreted as `--zip=33101`
|
||||||
- `--ziip 33101` -> interpreted as `--zip 33101`
|
- `--ziip 33101` -> interpreted as `--zip 33101`
|
||||||
- `categoriess` -> interpreted as `categories`
|
- `categoriess` -> interpreted as `categories`
|
||||||
|
|
||||||
|
Flag aliases: `zipcode`/`postal-code` -> `--zip`, `dept` -> `--department`, `search` -> `--query`, `sortby`/`orderby` -> `--sort`, `max` -> `--limit`.
|
||||||
|
|
||||||
The CLI prints a `note:` line when it auto-corrects input. Use canonical syntax in future commands:
|
The CLI prints a `note:` line when it auto-corrects input. Use canonical syntax in future commands:
|
||||||
- `pubcli --zip 33101`
|
- `pubcli --zip 33101`
|
||||||
- `pubcli --store 1425 --bogo`
|
- `pubcli --store 1425 --bogo`
|
||||||
- `pubcli categories --zip 33101`
|
- `pubcli categories --zip 33101`
|
||||||
- `pubcli stores --zip 33101 --json`
|
- `pubcli stores --zip 33101 --json`
|
||||||
|
- `pubcli compare --zip 33101 --category produce`
|
||||||
|
- `pubcli compare --zip 33101 --bogo --count 3 --json`
|
||||||
|
|
||||||
When intent is unclear, errors include a direct explanation and relevant examples.
|
## Filtering and Sorting
|
||||||
|
|
||||||
|
Deal filter flags (`--bogo`, `--category`, `--department`, `--query`, `--sort`, `--limit`) are available on `pubcli`, `compare`, and `tui`.
|
||||||
|
|
||||||
|
Sort accepts: `relevance` (default), `savings`, `ending`. Aliases `end`, `expiry`, `expiration` map to `ending`.
|
||||||
|
|
||||||
|
Category synonyms: `veggies` -> `produce`, `chicken` -> `meat`, `bread` -> `bakery`, `cheese` -> `dairy`, `cold cuts` -> `deli`, etc.
|
||||||
|
|
||||||
|
## Auto JSON
|
||||||
|
|
||||||
|
When stdout is not a TTY, JSON output is enabled automatically. This means piping to `jq` or another process produces JSON without requiring `--json`.
|
||||||
|
|
||||||
|
## Errors
|
||||||
|
|
||||||
|
When intent is unclear, errors include a direct explanation and relevant examples. In JSON mode, errors are structured:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{"error":{"code":"INVALID_ARGS","message":"...","suggestions":["..."],"exitCode":2}}
|
||||||
|
```
|
||||||
|
|
||||||
|
Exit codes: `0` success, `1` not found, `2` invalid args, `3` upstream error, `4` internal error.
|
||||||
|
|||||||
85
README.md
85
README.md
@@ -95,16 +95,37 @@ pubcli categories -z 33101 --json
|
|||||||
|
|
||||||
### `pubcli compare`
|
### `pubcli compare`
|
||||||
|
|
||||||
Compare nearby stores and rank them by matching deal quality.
|
Compare nearby stores and rank them by filtered deal quality. Requires `--zip`. Stores are ranked by number of matched deals, then deal score, then distance.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pubcli compare --zip 33101
|
pubcli compare --zip 33101
|
||||||
pubcli compare --zip 33101 --category produce --sort savings
|
pubcli compare --zip 33101 --category produce --sort savings
|
||||||
|
pubcli compare --zip 33101 --bogo --count 3 --json
|
||||||
```
|
```
|
||||||
|
|
||||||
### `pubcli tui`
|
### `pubcli tui`
|
||||||
|
|
||||||
Keyboard-driven interactive browser for deal lists.
|
Full-screen interactive browser for deal lists with a responsive two-pane layout:
|
||||||
|
- async startup loading spinner + skeleton while store/deals are fetched
|
||||||
|
- visual deal sections (BOGO/category grouped) with jump navigation
|
||||||
|
|
||||||
|
Controls:
|
||||||
|
|
||||||
|
- `tab` — switch focus between list and detail panes
|
||||||
|
- `/` — fuzzy filter deals in the list pane
|
||||||
|
- `s` — cycle sort mode (`relevance` -> `savings` -> `ending`)
|
||||||
|
- `g` — toggle BOGO-only inline filter
|
||||||
|
- `c` — cycle category inline filter
|
||||||
|
- `a` — cycle department inline filter
|
||||||
|
- `l` — cycle result limit inline filter
|
||||||
|
- `r` — reset inline sort/filter options back to CLI-start defaults
|
||||||
|
- `j` / `k` or arrows — navigate list and scroll detail
|
||||||
|
- `u` / `d` — half-page detail scroll
|
||||||
|
- `b` / `f` or `pgup` / `pgdown` — full-page detail scroll
|
||||||
|
- `[` / `]` — jump to previous/next section
|
||||||
|
- `1..9` — jump directly to a numbered section
|
||||||
|
- `?` — toggle inline help
|
||||||
|
- `q` — quit
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pubcli tui --zip 33101
|
pubcli tui --zip 33101
|
||||||
@@ -113,13 +134,13 @@ pubcli tui --store 1425 --category meat --sort ending
|
|||||||
|
|
||||||
## Flags
|
## Flags
|
||||||
|
|
||||||
Global flags:
|
Global flags (available on all commands):
|
||||||
|
|
||||||
- `-s, --store string` Publix store number (example: `1425`)
|
- `-s, --store string` Publix store number (example: `1425`)
|
||||||
- `-z, --zip string` ZIP code for store lookup
|
- `-z, --zip string` ZIP code for store lookup
|
||||||
- `--json` Output JSON instead of styled terminal output
|
- `--json` Output JSON instead of styled terminal output
|
||||||
|
|
||||||
Deal filtering flags (`pubcli` root command):
|
Deal filtering flags (available on `pubcli`, `compare`, and `tui`):
|
||||||
|
|
||||||
- `--bogo` Show only BOGO deals
|
- `--bogo` Show only BOGO deals
|
||||||
- `-c, --category string` Filter by category (example: `bogo`, `meat`, `produce`)
|
- `-c, --category string` Filter by category (example: `bogo`, `meat`, `produce`)
|
||||||
@@ -128,17 +149,40 @@ Deal filtering flags (`pubcli` root command):
|
|||||||
- `--sort string` Sort by `relevance` (default), `savings`, or `ending`
|
- `--sort string` Sort by `relevance` (default), `savings`, or `ending`
|
||||||
- `-n, --limit int` Limit results (`0` means no limit)
|
- `-n, --limit int` Limit results (`0` means no limit)
|
||||||
|
|
||||||
|
Compare-specific flags:
|
||||||
|
|
||||||
|
- `--count int` Number of nearby stores to compare, 1-10 (default `5`)
|
||||||
|
|
||||||
|
Sort accepts aliases: `end`, `expiry`, and `expiration` are equivalent to `ending`.
|
||||||
|
|
||||||
## Behavior Notes
|
## Behavior Notes
|
||||||
|
|
||||||
- Either `--store` or `--zip` is required for deal and category lookups.
|
- Either `--store` or `--zip` is required for deal and category lookups. `compare` requires `--zip`.
|
||||||
- If only `--zip` is provided, the nearest store is selected automatically.
|
- If only `--zip` is provided, the nearest store is selected automatically.
|
||||||
- When using text output and ZIP-based store resolution, the selected store is shown.
|
- When using text output and ZIP-based store resolution, the selected store is shown.
|
||||||
- Filtering is applied in this order: `bogo`, `category`, `department`, `query`, `limit`.
|
- Filtering is applied in this order: `bogo` + `category`, `department`, `query`, `sort`, `limit`.
|
||||||
- Category matching is case-insensitive and supports practical synonyms (for example `veggies` matches `produce`).
|
- Category matching is case-insensitive and supports synonym groups (see below).
|
||||||
- Department and query filters use case-insensitive substring matching.
|
- Department and query filters use case-insensitive substring matching.
|
||||||
- Running `pubcli` with no args prints compact quick-start help.
|
- Running `pubcli` with no args prints compact quick-start help.
|
||||||
- When stdout is not a TTY (for example piping to another process), JSON output is enabled automatically unless explicitly set.
|
- When stdout is not a TTY (for example piping to another process), JSON output is enabled automatically unless explicitly set.
|
||||||
|
|
||||||
|
### Category Synonyms
|
||||||
|
|
||||||
|
Category filtering recognizes synonyms so common names map to the right deals:
|
||||||
|
|
||||||
|
| Category | Also matches |
|
||||||
|
|----------|-------------|
|
||||||
|
| `bogo` | `bogof`, `buy one get one`, `buy1get1`, `2 for 1`, `two for one` |
|
||||||
|
| `produce` | `fruit`, `fruits`, `vegetable`, `vegetables`, `veggie`, `veggies` |
|
||||||
|
| `meat` | `beef`, `chicken`, `poultry`, `pork`, `seafood` |
|
||||||
|
| `dairy` | `milk`, `cheese`, `yogurt` |
|
||||||
|
| `bakery` | `bread`, `pastry`, `pastries` |
|
||||||
|
| `deli` | `delicatessen`, `cold cuts`, `lunch meat` |
|
||||||
|
| `frozen` | `frozen foods` |
|
||||||
|
| `grocery` | `pantry`, `shelf` |
|
||||||
|
|
||||||
|
Synonym matching is bidirectional — using `chicken` as a category filter matches deals tagged `meat`, and vice versa.
|
||||||
|
|
||||||
## CLI Input Tolerance
|
## CLI Input Tolerance
|
||||||
|
|
||||||
The CLI auto-corrects common input mistakes and prints a `note:` describing the normalization:
|
The CLI auto-corrects common input mistakes and prints a `note:` describing the normalization:
|
||||||
@@ -147,6 +191,18 @@ The CLI auto-corrects common input mistakes and prints a `note:` describing the
|
|||||||
- `zip=33101` -> `--zip=33101`
|
- `zip=33101` -> `--zip=33101`
|
||||||
- `--ziip 33101` -> `--zip 33101`
|
- `--ziip 33101` -> `--zip 33101`
|
||||||
- `stores zip 33101` -> `stores --zip 33101`
|
- `stores zip 33101` -> `stores --zip 33101`
|
||||||
|
- `categoriess` -> `categories`
|
||||||
|
|
||||||
|
Flag aliases are recognized and rewritten:
|
||||||
|
|
||||||
|
| Alias | Resolves to |
|
||||||
|
|-------|------------|
|
||||||
|
| `zipcode`, `postal-code` | `--zip` |
|
||||||
|
| `store-number`, `storeno` | `--store` |
|
||||||
|
| `dept` | `--department` |
|
||||||
|
| `search` | `--query` |
|
||||||
|
| `sortby`, `orderby` | `--sort` |
|
||||||
|
| `max` | `--limit` |
|
||||||
|
|
||||||
Command argument tokens are preserved for command workflows like:
|
Command argument tokens are preserved for command workflows like:
|
||||||
|
|
||||||
@@ -192,6 +248,21 @@ Object map of category name to deal count:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Compare (`pubcli compare ... --json`)
|
||||||
|
|
||||||
|
Array of objects ranked by deal quality:
|
||||||
|
|
||||||
|
- `rank` (number)
|
||||||
|
- `number` (string) — store number
|
||||||
|
- `name` (string)
|
||||||
|
- `city` (string)
|
||||||
|
- `state` (string)
|
||||||
|
- `distance` (string)
|
||||||
|
- `matchedDeals` (number)
|
||||||
|
- `bogoDeals` (number)
|
||||||
|
- `score` (number)
|
||||||
|
- `topDeal` (string)
|
||||||
|
|
||||||
## Structured Errors
|
## Structured Errors
|
||||||
|
|
||||||
When command execution fails, errors include:
|
When command execution fails, errors include:
|
||||||
|
|||||||
Reference in New Issue
Block a user