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>
pubcli
pubcli is a Go CLI for fetching current Publix weekly ad deals by store number or ZIP code.
Features
- Fetch weekly ad deals for a specific store
- Resolve nearest Publix store from a ZIP code
- Filter deals by category, department, keyword, and BOGO status
- Sort deals by estimated savings or ending date
- List weekly categories with deal counts
- Compare nearby stores for best filtered deal coverage
- Browse deals interactively in terminal (
tui) - Output data as formatted terminal text or JSON
- Generate shell completions (
bash,zsh,fish,powershell) - Tolerate minor CLI syntax mistakes when intent is clear
- Robot-mode behavior for AI agents (compact help, auto JSON when piped, structured errors, meaningful exit codes)
Requirements
- Go
1.24.4or newer to build from source - Network access to:
https://services.publix.com/api/v4/savingshttps://services.publix.com/api/v1/storelocation
Installation
Build locally
git clone https://github.com/tayloree/publix-deals.git
cd publix-deals
go build -o pubcli ./cmd/pubcli
Install with go install
go install github.com/tayloree/publix-deals/cmd/pubcli@latest
Quick Start
Find nearby stores:
pubcli stores --zip 33101
Fetch deals using a store number:
pubcli --store 1425
Fetch deals by ZIP (uses the nearest store):
pubcli --zip 33101
Fetch JSON output:
pubcli --zip 33101 --json
Commands
pubcli
Fetch weekly ad deals.
pubcli [flags]
pubcli stores
List up to 5 nearby stores for a ZIP code.
pubcli stores --zip 33101
pubcli stores -z 32801 --json
pubcli categories
List available categories for the current week.
pubcli categories --store 1425
pubcli categories -z 33101 --json
pubcli compare
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.
pubcli compare --zip 33101
pubcli compare --zip 33101 --category produce --sort savings
pubcli compare --zip 33101 --bogo --count 3 --json
pubcli tui
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 panes— cycle sort mode (relevance->savings->ending)g— toggle BOGO-only inline filterc— cycle category inline filtera— cycle department inline filterl— cycle result limit inline filterr— reset inline sort/filter options back to CLI-start defaultsj/kor arrows — navigate list and scroll detailu/d— half-page detail scrollb/forpgup/pgdown— full-page detail scroll[/]— jump to previous/next section1..9— jump directly to a numbered section?— toggle inline helpq— quit
pubcli tui --zip 33101
pubcli tui --store 1425 --category meat --sort ending
Flags
Global flags (available on all commands):
-s, --store stringPublix store number (example:1425)-z, --zip stringZIP code for store lookup--jsonOutput JSON instead of styled terminal output
Deal filtering flags (available on pubcli, compare, and tui):
--bogoShow only BOGO deals-c, --category stringFilter by category (example:bogo,meat,produce)-d, --department stringFilter by department (substring match, case-insensitive)-q, --query stringSearch title/description (case-insensitive)--sort stringSort byrelevance(default),savings, orending-n, --limit intLimit results (0means no limit)
Compare-specific flags:
--count intNumber of nearby stores to compare, 1-10 (default5)
Sort accepts aliases: end, expiry, and expiration are equivalent to ending.
Behavior Notes
- Either
--storeor--zipis required for deal and category lookups.comparerequires--zip. - If only
--zipis provided, the nearest store is selected automatically. - When using text output and ZIP-based store resolution, the selected store is shown.
- Filtering is applied in this order:
bogo+category,department,query,sort,limit. - Category matching is case-insensitive and supports synonym groups (see below).
- Department and query filters use case-insensitive substring matching.
- Running
pubcliwith 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.
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
The CLI auto-corrects common input mistakes and prints a note: describing the normalization:
-zip 33101->--zip 33101zip=33101->--zip=33101--ziip 33101->--zip 33101stores zip 33101->stores --zip 33101categoriess->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:
pubcli completion zshpubcli help stores
JSON Output
Deals (pubcli ... --json)
Array of objects with fields:
title(string)savings(string)description(string)department(string)categories(string[])additionalDealInfo(string)brand(string)validFrom(string)validTo(string)isBogo(boolean)imageUrl(string)
Stores (pubcli stores ... --json)
Array of objects with fields:
number(string)name(string)address(string)distance(string)
Categories (pubcli categories ... --json)
Object map of category name to deal count:
{
"bogo": 175,
"meat": 88,
"produce": 81
}
Compare (pubcli compare ... --json)
Array of objects ranked by deal quality:
rank(number)number(string) — store numbername(string)city(string)state(string)distance(string)matchedDeals(number)bogoDeals(number)score(number)topDeal(string)
Structured Errors
When command execution fails, errors include:
code(example:INVALID_ARGS,NOT_FOUND,UPSTREAM_ERROR)messagesuggestions(when available)exitCode
JSON-mode errors are emitted as:
{"error":{"code":"INVALID_ARGS","message":"unknown flag: --ziip","suggestions":["Try `--zip`.","pubcli --zip 33101"],"exitCode":2}}
Exit Codes
0success1not found2invalid arguments3upstream/network failure4internal failure
Shell Completion
Generate completions:
pubcli completion bash
pubcli completion zsh
pubcli completion fish
pubcli completion powershell
Development
Run tests:
go test ./...
Run without building:
go run ./cmd/pubcli --zip 33101 --limit 10