@purveyors/cli 0.8.3 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +276 -254
- package/dist/commands/auth.d.ts.map +1 -1
- package/dist/commands/auth.js +6 -4
- package/dist/commands/auth.js.map +1 -1
- package/dist/commands/catalog.d.ts +2 -2
- package/dist/commands/catalog.d.ts.map +1 -1
- package/dist/commands/catalog.js +30 -35
- package/dist/commands/catalog.js.map +1 -1
- package/dist/commands/context.d.ts +0 -5
- package/dist/commands/context.d.ts.map +1 -1
- package/dist/commands/context.js +197 -267
- package/dist/commands/context.js.map +1 -1
- package/dist/commands/roast.d.ts.map +1 -1
- package/dist/commands/roast.js +46 -0
- package/dist/commands/roast.js.map +1 -1
- package/dist/index.js +12 -9
- package/dist/index.js.map +1 -1
- package/dist/lib/catalog.d.ts +3 -0
- package/dist/lib/catalog.d.ts.map +1 -1
- package/dist/lib/catalog.js +19 -2
- package/dist/lib/catalog.js.map +1 -1
- package/dist/lib/output.d.ts +6 -0
- package/dist/lib/output.d.ts.map +1 -1
- package/dist/lib/output.js +8 -0
- package/dist/lib/output.js.map +1 -1
- package/dist/lib/roast.d.ts +6 -0
- package/dist/lib/roast.d.ts.map +1 -1
- package/dist/lib/roast.js +60 -0
- package/dist/lib/roast.js.map +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
# purvey
|
|
1
|
+
# purvey
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Coffee intelligence from your terminal.
|
|
4
4
|
|
|
5
|
-
`purvey` is the official
|
|
5
|
+
`purvey` is the official CLI for [purveyors.io](https://purveyors.io). It gives coffee professionals and AI agents direct access to the Purveyors platform from the terminal: catalog search, inventory tracking, roast logging, sales records, tasting notes, and Artisan `.alog` import.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
---
|
|
7
|
+
Run `purvey context` for the dense agent reference.
|
|
10
8
|
|
|
11
9
|
## Installation
|
|
12
10
|
|
|
@@ -14,284 +12,378 @@
|
|
|
14
12
|
npm install -g @purveyors/cli
|
|
15
13
|
```
|
|
16
14
|
|
|
17
|
-
|
|
15
|
+
Requirements:
|
|
16
|
+
|
|
17
|
+
- Node.js 20 or newer
|
|
18
18
|
|
|
19
|
-
Verify:
|
|
19
|
+
Verify the install:
|
|
20
20
|
|
|
21
21
|
```bash
|
|
22
22
|
purvey --version
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
-
---
|
|
26
|
-
|
|
27
25
|
## Quick Start
|
|
28
26
|
|
|
29
27
|
```bash
|
|
30
28
|
# 1. Authenticate
|
|
31
29
|
purvey auth login
|
|
32
30
|
|
|
33
|
-
# 2. Confirm
|
|
31
|
+
# 2. Confirm the session
|
|
34
32
|
purvey auth status
|
|
35
33
|
|
|
36
|
-
# 3. Search the catalog
|
|
34
|
+
# 3. Search the catalog
|
|
37
35
|
purvey catalog search --origin "Ethiopia" --stocked --pretty
|
|
38
36
|
|
|
39
|
-
# 4. Check
|
|
37
|
+
# 4. Check inventory
|
|
40
38
|
purvey inventory list --stocked --pretty
|
|
41
39
|
|
|
42
40
|
# 5. Import a roast from Artisan
|
|
43
41
|
purvey roast import ~/artisan/my-roast.alog --coffee-id 7 --pretty
|
|
44
42
|
```
|
|
45
43
|
|
|
46
|
-
---
|
|
47
|
-
|
|
48
44
|
## Authentication
|
|
49
45
|
|
|
50
|
-
`purvey`
|
|
46
|
+
`purvey` uses Google OAuth through purveyors.io.
|
|
51
47
|
|
|
52
|
-
|
|
48
|
+
Interactive login:
|
|
53
49
|
|
|
54
50
|
```bash
|
|
55
51
|
purvey auth login
|
|
56
52
|
```
|
|
57
53
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
### Headless Login (agents, CI, servers)
|
|
54
|
+
Headless login for agents, CI, and remote machines:
|
|
61
55
|
|
|
62
56
|
```bash
|
|
63
57
|
purvey auth login --headless
|
|
64
58
|
```
|
|
65
59
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
### Status
|
|
60
|
+
Status:
|
|
69
61
|
|
|
70
62
|
```bash
|
|
71
63
|
purvey auth status
|
|
64
|
+
purvey auth status --json
|
|
72
65
|
purvey auth status --pretty
|
|
73
66
|
```
|
|
74
67
|
|
|
75
|
-
|
|
76
|
-
✔ Logged in as you@example.com
|
|
77
|
-
ℹ Role: member
|
|
78
|
-
ℹ Token expires: 2026-04-01T08:00:00.000Z
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
### Token Refresh
|
|
82
|
-
|
|
83
|
-
Tokens refresh automatically. No need to re-login between sessions.
|
|
84
|
-
|
|
85
|
-
### Logout
|
|
68
|
+
Logout:
|
|
86
69
|
|
|
87
70
|
```bash
|
|
88
71
|
purvey auth logout
|
|
89
72
|
```
|
|
90
73
|
|
|
91
|
-
|
|
74
|
+
Credentials are stored at `~/.config/purvey/credentials.json`.
|
|
92
75
|
|
|
93
|
-
|
|
76
|
+
### Auth roles
|
|
94
77
|
|
|
95
|
-
|
|
78
|
+
`catalog` commands require an authenticated viewer session. Sign in before using:
|
|
96
79
|
|
|
97
|
-
|
|
80
|
+
- `purvey catalog search`
|
|
81
|
+
- `purvey catalog get <id>`
|
|
82
|
+
- `purvey catalog stats`
|
|
83
|
+
- `purvey catalog similar <id>`
|
|
98
84
|
|
|
99
|
-
|
|
85
|
+
`inventory`, `roast`, `sales`, and `tasting` commands require a member role.
|
|
100
86
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
87
|
+
## Output and Scripting
|
|
88
|
+
|
|
89
|
+
Most commands write compact JSON to stdout by default.
|
|
90
|
+
Use `--json` if you want to request that mode explicitly.
|
|
105
91
|
|
|
106
|
-
|
|
92
|
+
Pretty JSON:
|
|
107
93
|
|
|
108
94
|
```bash
|
|
109
|
-
purvey
|
|
110
|
-
# → indented, colorized JSON
|
|
95
|
+
purvey inventory list --pretty
|
|
111
96
|
```
|
|
112
97
|
|
|
113
|
-
|
|
98
|
+
CSV output for array results:
|
|
114
99
|
|
|
115
100
|
```bash
|
|
116
101
|
purvey inventory list --csv > inventory.csv
|
|
117
|
-
purvey
|
|
102
|
+
purvey sales list --csv > sales.csv
|
|
118
103
|
```
|
|
119
104
|
|
|
120
|
-
|
|
105
|
+
Pipe JSON into `jq`:
|
|
121
106
|
|
|
122
107
|
```bash
|
|
123
108
|
purvey inventory list | jq '.[].id'
|
|
124
|
-
purvey
|
|
125
|
-
purvey auth status | jq -r '.email'
|
|
109
|
+
purvey roast list --limit 5 | jq '.[].roast_id'
|
|
110
|
+
purvey auth status 2>/dev/null | jq -r '.email'
|
|
126
111
|
```
|
|
127
112
|
|
|
128
|
-
|
|
113
|
+
Operational messages go to stderr, so stdout stays script-friendly.
|
|
129
114
|
|
|
130
|
-
|
|
115
|
+
### Output caveats worth knowing
|
|
116
|
+
|
|
117
|
+
- `purvey auth status` prints human-readable output in an interactive terminal unless you pass `--json`, `--pretty`, or `--csv`. When piped or redirected, it emits JSON.
|
|
118
|
+
- `--json` is an explicit alias for the default compact JSON mode, and it forces JSON even in an interactive terminal.
|
|
131
119
|
|
|
132
120
|
## Command Reference
|
|
133
121
|
|
|
134
|
-
###
|
|
122
|
+
### auth
|
|
135
123
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
| `purvey auth status` | Show current authentication state and role |
|
|
141
|
-
| `purvey auth logout` | Clear stored credentials |
|
|
124
|
+
- `purvey auth login`
|
|
125
|
+
- `purvey auth login --headless`
|
|
126
|
+
- `purvey auth status`
|
|
127
|
+
- `purvey auth logout`
|
|
142
128
|
|
|
143
|
-
###
|
|
129
|
+
### catalog
|
|
144
130
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
| `purvey catalog stats` | Aggregate statistics for the full catalog |
|
|
131
|
+
- `purvey catalog search`
|
|
132
|
+
- `purvey catalog get <id>`
|
|
133
|
+
- `purvey catalog stats`
|
|
134
|
+
- `purvey catalog similar <id>`
|
|
150
135
|
|
|
151
|
-
|
|
136
|
+
`catalog search` filters:
|
|
152
137
|
|
|
138
|
+
- `--origin <text>` -- filter by origin (country, continent, or region)
|
|
139
|
+
- `--process <method>` -- filter by processing method (e.g. natural, washed)
|
|
140
|
+
- `--price-min <n>` -- minimum price per lb (USD)
|
|
141
|
+
- `--price-max <n>` -- maximum price per lb (USD)
|
|
142
|
+
- `--flavor <keywords>` -- flavor keywords, comma-separated
|
|
143
|
+
- `--name <text>` -- filter by coffee name (partial match, case-insensitive)
|
|
144
|
+
- `--supplier <name>` -- filter by supplier/source name (partial match, case-insensitive)
|
|
145
|
+
- `--ids <n,n,...>` -- fetch specific catalog IDs (comma-separated, ignores limit)
|
|
146
|
+
- `--stocked` -- only show currently stocked coffees
|
|
147
|
+
- `--sort <price|price-desc|name|origin|newest>` -- sort results
|
|
148
|
+
- `--offset <n>` -- skip N results for pagination
|
|
149
|
+
- `--limit <n>` -- maximum results to return (default: 10)
|
|
150
|
+
|
|
151
|
+
`catalog similar <id>` options:
|
|
152
|
+
|
|
153
|
+
- `--threshold <0-1>` -- minimum similarity score (default: 0.70)
|
|
154
|
+
- `--limit <n>` -- max results (default: 10)
|
|
155
|
+
- `--stocked-only` -- only show currently stocked beans
|
|
156
|
+
|
|
157
|
+
Examples:
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
purvey catalog search --origin "Ethiopia" --pretty
|
|
161
|
+
purvey catalog search --supplier "Royal Coffee" --stocked --pretty
|
|
162
|
+
purvey catalog search --ids "1182,1183,1200"
|
|
163
|
+
purvey catalog search --stocked --sort price --offset 10 --limit 10
|
|
164
|
+
purvey catalog similar 1182 --threshold 0.85 --stocked-only --pretty
|
|
165
|
+
purvey catalog similar 1182 --json | jq '.[0]'
|
|
153
166
|
```
|
|
154
|
-
--origin <text> country or region (e.g. "Ethiopia", "Colombia")
|
|
155
|
-
--process <method> natural, washed, honey
|
|
156
|
-
--price-min <n> min USD/lb
|
|
157
|
-
--price-max <n> max USD/lb
|
|
158
|
-
--flavor <keywords> comma-separated (e.g. "blueberry,citrus")
|
|
159
|
-
--stocked only currently stocked coffees
|
|
160
|
-
--limit <n> max results (default: 10)
|
|
161
|
-
```
|
|
162
167
|
|
|
163
|
-
###
|
|
168
|
+
### inventory
|
|
169
|
+
|
|
170
|
+
- `purvey inventory list`
|
|
171
|
+
- `purvey inventory get <id>`
|
|
172
|
+
- `purvey inventory add`
|
|
173
|
+
- `purvey inventory update <id>`
|
|
174
|
+
- `purvey inventory delete <id>`
|
|
164
175
|
|
|
165
|
-
|
|
166
|
-
| ------------------------------ | -------------------------------- |
|
|
167
|
-
| `purvey inventory list` | List your green coffee inventory |
|
|
168
|
-
| `purvey inventory get <id>` | Get a single inventory item |
|
|
169
|
-
| `purvey inventory add` | Add a bean to your inventory |
|
|
170
|
-
| `purvey inventory update <id>` | Update an inventory item |
|
|
171
|
-
| `purvey inventory delete <id>` | Delete an inventory item |
|
|
176
|
+
`inventory list` options:
|
|
172
177
|
|
|
173
|
-
|
|
178
|
+
- `--stocked` -- only show currently stocked beans
|
|
179
|
+
- `--limit <n>` -- maximum results (default: 20)
|
|
180
|
+
|
|
181
|
+
`inventory add` flags:
|
|
182
|
+
|
|
183
|
+
- `--catalog-id <id>` -- [REQUIRED] coffee_catalog.catalog_id
|
|
184
|
+
- `--qty <lbs>` -- [REQUIRED] quantity in pounds
|
|
185
|
+
- `--cost <dollars>` -- bean cost in dollars
|
|
186
|
+
- `--tax-ship <dollars>` -- tax and shipping cost in dollars
|
|
187
|
+
- `--notes <text>` -- notes for this inventory item
|
|
188
|
+
- `--purchase-date <YYYY-MM-DD>` -- purchase date (defaults to today)
|
|
189
|
+
- `--form` -- interactive form mode
|
|
190
|
+
|
|
191
|
+
`inventory update <id>` flags:
|
|
192
|
+
|
|
193
|
+
- `--qty <lbs>` -- updated quantity in pounds
|
|
194
|
+
- `--cost <dollars>` -- updated bean cost
|
|
195
|
+
- `--tax-ship <dollars>` -- updated tax/shipping cost
|
|
196
|
+
- `--notes <text>` -- updated notes
|
|
197
|
+
- `--stocked <true|false>` -- mark as stocked or not
|
|
198
|
+
|
|
199
|
+
Examples:
|
|
174
200
|
|
|
175
201
|
```bash
|
|
202
|
+
purvey inventory list --stocked --pretty
|
|
176
203
|
purvey inventory add --catalog-id 128 --qty 10 --cost 8.50
|
|
177
|
-
purvey inventory add --
|
|
204
|
+
purvey inventory add --catalog-id 42 --qty 5 --cost 6.25 --tax-ship 4.00
|
|
205
|
+
purvey inventory update 7 --stocked false
|
|
206
|
+
purvey inventory delete 7 --yes
|
|
178
207
|
```
|
|
179
208
|
|
|
180
|
-
###
|
|
209
|
+
### roast
|
|
210
|
+
|
|
211
|
+
- `purvey roast list`
|
|
212
|
+
- `purvey roast get <id>`
|
|
213
|
+
- `purvey roast create`
|
|
214
|
+
- `purvey roast update <id>`
|
|
215
|
+
- `purvey roast delete <id>`
|
|
216
|
+
- `purvey roast import [file]`
|
|
217
|
+
- `purvey roast watch [directory]`
|
|
218
|
+
|
|
219
|
+
`roast list` filters:
|
|
220
|
+
|
|
221
|
+
- `--coffee-id <id>` -- filter by inventory item ID (green_coffee_inv.id)
|
|
222
|
+
- `--roast-id <id>` -- filter by exact roast profile ID
|
|
223
|
+
- `--batch-name <text>` -- filter by batch name (partial match, case-insensitive)
|
|
224
|
+
- `--date-start <YYYY-MM-DD>` -- only show roasts on or after this date
|
|
225
|
+
- `--date-end <YYYY-MM-DD>` -- only show roasts on or before this date
|
|
226
|
+
- `--stocked` -- only show roasts for currently stocked beans
|
|
227
|
+
- `--catalog-id <id>` -- filter by coffee_catalog ID
|
|
228
|
+
- `--limit <n>` -- maximum results (default: 20)
|
|
229
|
+
|
|
230
|
+
`roast get <id>` options:
|
|
231
|
+
|
|
232
|
+
- `--include-temps` -- include temperature curve data
|
|
233
|
+
- `--include-events` -- include roast event markers
|
|
234
|
+
|
|
235
|
+
`roast create` flags:
|
|
181
236
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
| `purvey roast import [file]` | Import an Artisan .alog roast file |
|
|
190
|
-
| `purvey roast watch [dir]` | Watch a directory for new .alog files |
|
|
237
|
+
- `--coffee-id <id>` -- [REQUIRED] green_coffee_inv ID
|
|
238
|
+
- `--batch-name <name>` -- batch name (defaults to coffee name + today's date)
|
|
239
|
+
- `--oz-in <oz>` -- green weight in ounces
|
|
240
|
+
- `--oz-out <oz>` -- roasted weight in ounces
|
|
241
|
+
- `--roast-date <YYYY-MM-DD>` -- roast date (defaults to today)
|
|
242
|
+
- `--notes <text>` -- roast notes
|
|
243
|
+
- `--form` -- interactive form mode
|
|
191
244
|
|
|
192
|
-
|
|
245
|
+
`roast update <id>` fields:
|
|
246
|
+
|
|
247
|
+
- `--notes <text>` -- updated roast notes
|
|
248
|
+
- `--oz-out <oz>` -- updated roasted weight (triggers weight loss recalculation)
|
|
249
|
+
- `--batch-name <name>` -- updated batch name
|
|
250
|
+
- `--targets <text>` -- updated roast targets
|
|
251
|
+
|
|
252
|
+
`roast import [file]` flags:
|
|
253
|
+
|
|
254
|
+
- `--coffee-id <id>` -- [REQUIRED] green_coffee_inv ID
|
|
255
|
+
- `--batch-name <name>` -- batch name (auto-generated if omitted)
|
|
256
|
+
- `--oz-in <oz>` -- green weight (extracted from .alog if present, overridden here)
|
|
257
|
+
- `--roast-notes <text>` -- additional roast notes
|
|
258
|
+
- `--form` -- interactive form mode
|
|
259
|
+
|
|
260
|
+
`roast watch [directory]` options:
|
|
261
|
+
|
|
262
|
+
- `--coffee-id <id>` -- [REQUIRED unless --auto-match] inventory ID for all imports
|
|
263
|
+
- `--batch-prefix <name>` -- batch name prefix for auto-named batches
|
|
264
|
+
- `--prompt-each` -- prompt for bean selection on each new file
|
|
265
|
+
- `--auto-match` -- auto-match beans per file (mutually exclusive with --coffee-id)
|
|
266
|
+
- `--resume` -- resume a previous watch session
|
|
267
|
+
- `--form` -- interactive setup wizard
|
|
268
|
+
|
|
269
|
+
Examples:
|
|
193
270
|
|
|
194
271
|
```bash
|
|
272
|
+
purvey roast list --catalog-id 128 --pretty
|
|
273
|
+
purvey roast list --batch-name "Ethiopia Guji" --pretty
|
|
274
|
+
purvey roast list --date-start 2026-03-01 --date-end 2026-03-31
|
|
275
|
+
purvey roast create --coffee-id 7 --batch-name "Ethiopia Guji Light" --oz-in 16
|
|
276
|
+
purvey roast update 123 --targets "Aim for FC at 390F, 18% dev"
|
|
195
277
|
purvey roast import ~/artisan/ethiopia.alog --coffee-id 7
|
|
196
|
-
purvey roast
|
|
278
|
+
purvey roast watch ~/artisan/ --auto-match
|
|
197
279
|
```
|
|
198
280
|
|
|
199
|
-
|
|
281
|
+
### sales
|
|
200
282
|
|
|
201
|
-
|
|
202
|
-
purvey
|
|
203
|
-
|
|
204
|
-
purvey
|
|
205
|
-
|
|
283
|
+
- `purvey sales list`
|
|
284
|
+
- `purvey sales record`
|
|
285
|
+
- `purvey sales update <id>`
|
|
286
|
+
- `purvey sales delete <id>`
|
|
287
|
+
|
|
288
|
+
`sales record` flags:
|
|
206
289
|
|
|
207
|
-
|
|
290
|
+
- `--roast-id <id>` -- [REQUIRED] roast_data.roast_id
|
|
291
|
+
- `--oz <amount>` -- [REQUIRED] ounces sold
|
|
292
|
+
- `--price <dollars>` -- [REQUIRED] total sale price in dollars
|
|
293
|
+
- `--buyer <name>` -- buyer name or identifier
|
|
294
|
+
- `--sell-date <YYYY-MM-DD>` -- sale date (defaults to today)
|
|
295
|
+
- `--form` -- interactive form mode
|
|
208
296
|
|
|
209
|
-
|
|
210
|
-
| -------------------------- | ----------------------- |
|
|
211
|
-
| `purvey sales list` | List your sales records |
|
|
212
|
-
| `purvey sales record` | Record a new sale |
|
|
213
|
-
| `purvey sales update <id>` | Update a sale record |
|
|
214
|
-
| `purvey sales delete <id>` | Delete a sale record |
|
|
297
|
+
`sales update <id>` flags:
|
|
215
298
|
|
|
216
|
-
|
|
299
|
+
- `--oz <amount>` -- updated ounces sold
|
|
300
|
+
- `--price <dollars>` -- updated sale price
|
|
301
|
+
- `--buyer <name>` -- updated buyer name
|
|
302
|
+
- `--sell-date <YYYY-MM-DD>` -- updated sale date
|
|
303
|
+
|
|
304
|
+
Examples:
|
|
217
305
|
|
|
218
306
|
```bash
|
|
219
|
-
purvey sales record --roast-id 123 --oz 12 --price 22.00
|
|
220
|
-
purvey sales
|
|
307
|
+
purvey sales record --roast-id 123 --oz 12 --price 22.00 --buyer "Jane Smith"
|
|
308
|
+
purvey sales list --pretty
|
|
309
|
+
purvey sales update 5 --price 24.00
|
|
310
|
+
purvey sales delete 5 --yes
|
|
221
311
|
```
|
|
222
312
|
|
|
223
|
-
###
|
|
313
|
+
### tasting
|
|
224
314
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
| `purvey tasting get <catalog-id>` | Get tasting notes for a catalog coffee |
|
|
228
|
-
| `purvey tasting rate [inventory-id]` | Rate a coffee with cupping scores |
|
|
315
|
+
- `purvey tasting get <bean-id>`
|
|
316
|
+
- `purvey tasting rate [bean-id]`
|
|
229
317
|
|
|
230
|
-
|
|
318
|
+
`purvey tasting get <bean-id>` options:
|
|
319
|
+
|
|
320
|
+
- `--filter <user|supplier|both>` -- which notes to show (default: both)
|
|
321
|
+
|
|
322
|
+
`purvey tasting rate [bean-id]` options:
|
|
323
|
+
|
|
324
|
+
- `--aroma <1-5>` -- [REQUIRED in flag mode]
|
|
325
|
+
- `--body <1-5>` -- [REQUIRED in flag mode]
|
|
326
|
+
- `--acidity <1-5>` -- [REQUIRED in flag mode]
|
|
327
|
+
- `--sweetness <1-5>` -- [REQUIRED in flag mode]
|
|
328
|
+
- `--aftertaste <1-5>` -- [REQUIRED in flag mode]
|
|
329
|
+
- `--brew-method <method>` -- brew method used (e.g. pour_over, espresso)
|
|
330
|
+
- `--notes <text>` -- additional tasting notes
|
|
331
|
+
- `--form` -- interactive form mode
|
|
332
|
+
|
|
333
|
+
Examples:
|
|
231
334
|
|
|
232
335
|
```bash
|
|
336
|
+
purvey tasting get 128 --filter both --pretty
|
|
233
337
|
purvey tasting rate 7 --aroma 4 --body 3 --acidity 5 --sweetness 4 --aftertaste 4
|
|
234
|
-
purvey tasting rate --
|
|
338
|
+
purvey tasting rate 42 --aroma 3 --body 3 --acidity 3 --sweetness 3 --aftertaste 3 --notes "Underextracted"
|
|
235
339
|
```
|
|
236
340
|
|
|
237
|
-
###
|
|
341
|
+
### config
|
|
238
342
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
| `purvey config set <key> <value>` | Set a config value |
|
|
244
|
-
| `purvey config reset` | Reset all config to defaults |
|
|
343
|
+
- `purvey config list`
|
|
344
|
+
- `purvey config get <key>`
|
|
345
|
+
- `purvey config set <key> <value>`
|
|
346
|
+
- `purvey config reset`
|
|
245
347
|
|
|
246
|
-
|
|
348
|
+
Current config key:
|
|
247
349
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
350
|
+
- `form-mode`: when set to `true`, write commands enter interactive mode when required args are missing
|
|
351
|
+
|
|
352
|
+
Examples:
|
|
251
353
|
|
|
252
354
|
```bash
|
|
253
355
|
purvey config set form-mode true
|
|
254
356
|
purvey config get form-mode
|
|
255
|
-
purvey config list
|
|
256
357
|
```
|
|
257
358
|
|
|
258
|
-
|
|
359
|
+
### context
|
|
360
|
+
|
|
361
|
+
- `purvey context`
|
|
362
|
+
|
|
363
|
+
Use this when an agent needs a compact, source-aware CLI reference.
|
|
259
364
|
|
|
260
365
|
## Common Workflows
|
|
261
366
|
|
|
262
|
-
### Buy
|
|
367
|
+
### Buy coffee, roast it, rate it, and record a sale
|
|
263
368
|
|
|
264
369
|
```bash
|
|
265
|
-
# Find a coffee
|
|
266
370
|
purvey catalog search --origin "Ethiopia" --process "natural" --stocked --pretty
|
|
267
|
-
|
|
268
|
-
# Add to inventory (catalog-id from search results)
|
|
269
371
|
purvey inventory add --catalog-id 128 --qty 10 --cost 8.50
|
|
270
|
-
|
|
271
|
-
# Get your inventory id
|
|
272
372
|
purvey inventory list --stocked --pretty
|
|
273
|
-
|
|
274
|
-
# Import a roast from Artisan (inventory id = 7)
|
|
275
373
|
purvey roast import ~/artisan/guji-light.alog --coffee-id 7 --pretty
|
|
276
|
-
|
|
277
|
-
# Rate the coffee after brewing
|
|
278
374
|
purvey tasting rate 7 --aroma 5 --body 3 --acidity 5 --sweetness 4 --aftertaste 4
|
|
279
|
-
|
|
280
|
-
# Record a sale (roast_id from import output)
|
|
281
375
|
purvey sales record --roast-id 123 --oz 12 --price 22.00 --buyer "Jane Smith"
|
|
282
376
|
```
|
|
283
377
|
|
|
284
|
-
### Continuous watch mode
|
|
378
|
+
### Continuous Artisan watch mode
|
|
285
379
|
|
|
286
380
|
```bash
|
|
287
|
-
|
|
288
|
-
purvey roast watch ~/
|
|
289
|
-
|
|
290
|
-
# Resume a watch session after restart
|
|
381
|
+
purvey roast watch ~/artisan/ --coffee-id 7
|
|
382
|
+
purvey roast watch ~/artisan/ --auto-match
|
|
291
383
|
purvey roast watch --resume
|
|
292
384
|
```
|
|
293
385
|
|
|
294
|
-
### Export
|
|
386
|
+
### Export records for spreadsheets
|
|
295
387
|
|
|
296
388
|
```bash
|
|
297
389
|
purvey inventory list --csv > inventory.csv
|
|
@@ -299,66 +391,45 @@ purvey roast list --csv > roasts.csv
|
|
|
299
391
|
purvey sales list --csv > sales.csv
|
|
300
392
|
```
|
|
301
393
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
## Environment Variables
|
|
394
|
+
## ID Reference
|
|
305
395
|
|
|
306
|
-
|
|
307
|
-
| ----------------------------- | ----------------------------------------------- |
|
|
308
|
-
| `PURVEYORS_SUPABASE_URL` | Override the Supabase project URL (dev/staging) |
|
|
309
|
-
| `PURVEYORS_SUPABASE_ANON_KEY` | Override the Supabase anon key |
|
|
310
|
-
| `PURVEY_DEBUG` | Set to any value to enable verbose error output |
|
|
396
|
+
Use the right ID for the right command.
|
|
311
397
|
|
|
312
|
-
|
|
398
|
+
- `catalog_id`: coffee_catalog rows; used by `catalog get`, `inventory add --catalog-id`, `tasting get`, `roast list --catalog-id`
|
|
399
|
+
- `inventory id`: green_coffee_inv rows; used by `inventory get/update/delete`, `roast --coffee-id`, `tasting rate`, `roast list --coffee-id`
|
|
400
|
+
- `roast_id`: roast_data rows; used by `roast get/delete`, `sales --roast-id`, `roast list --roast-id`
|
|
401
|
+
- `sale id`: coffee_sales rows; used by `sales update/delete`
|
|
313
402
|
|
|
314
|
-
##
|
|
403
|
+
## Environment Variables
|
|
315
404
|
|
|
316
|
-
`
|
|
405
|
+
- `PURVEYORS_SUPABASE_URL`: override the Supabase project URL
|
|
406
|
+
- `PURVEYORS_SUPABASE_ANON_KEY`: override the Supabase anon key
|
|
407
|
+
- `PURVEYORS_BASE_URL`: override the Purveyors web base URL
|
|
408
|
+
- `PURVEY_DEBUG`: enable verbose error output
|
|
317
409
|
|
|
318
|
-
|
|
410
|
+
## For AI Agents
|
|
319
411
|
|
|
320
|
-
|
|
412
|
+
Start here:
|
|
321
413
|
|
|
322
414
|
```bash
|
|
323
415
|
purvey context
|
|
324
416
|
```
|
|
325
417
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
### Agent Auth Flow
|
|
418
|
+
Recommended flow:
|
|
329
419
|
|
|
330
420
|
```bash
|
|
331
421
|
purvey auth login --headless
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
# Token auto-refreshes; no further auth action needed.
|
|
335
|
-
```
|
|
336
|
-
|
|
337
|
-
### Agent Usage Pattern
|
|
338
|
-
|
|
339
|
-
```bash
|
|
340
|
-
# Check auth before any write operations
|
|
341
|
-
purvey auth status
|
|
342
|
-
|
|
343
|
-
# Always use JSON output (default) for scripting
|
|
344
|
-
purvey catalog search --origin "Ethiopia" | jq '.[0].catalog_id'
|
|
345
|
-
purvey inventory list | jq '.[] | select(.stocked == true) | .id'
|
|
346
|
-
|
|
347
|
-
# Use --yes to skip confirmation prompts in automated flows
|
|
348
|
-
purvey inventory delete 7 --yes
|
|
349
|
-
purvey sales delete 5 --yes
|
|
422
|
+
purvey auth status 2>/dev/null | jq .
|
|
423
|
+
purvey inventory list | jq '.[].id'
|
|
350
424
|
```
|
|
351
425
|
|
|
352
|
-
|
|
426
|
+
The CLI is designed to be agent-friendly:
|
|
353
427
|
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
| `sale_id` | `coffee_sales` | `sales update/delete` |
|
|
360
|
-
|
|
361
|
-
---
|
|
428
|
+
- stable command names
|
|
429
|
+
- structured output on stdout
|
|
430
|
+
- headless auth flow
|
|
431
|
+
- copy-pasteable examples
|
|
432
|
+
- a dedicated `context` command for onboarding
|
|
362
433
|
|
|
363
434
|
## Development
|
|
364
435
|
|
|
@@ -366,71 +437,22 @@ purvey sales delete 5 --yes
|
|
|
366
437
|
git clone https://github.com/reedwhetstone/purveyors-cli
|
|
367
438
|
cd purveyors-cli
|
|
368
439
|
pnpm install
|
|
440
|
+
npm run build
|
|
441
|
+
npm run check
|
|
442
|
+
npm run lint
|
|
443
|
+
npm test
|
|
369
444
|
```
|
|
370
445
|
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
```
|
|
374
|
-
PURVEYORS_SUPABASE_URL=https://your-project.supabase.co
|
|
375
|
-
PURVEYORS_SUPABASE_ANON_KEY=your-anon-key
|
|
376
|
-
```
|
|
377
|
-
|
|
378
|
-
Run locally:
|
|
379
|
-
|
|
380
|
-
```bash
|
|
381
|
-
pnpm dev -- auth status
|
|
382
|
-
pnpm dev -- catalog search --origin Ethiopia --pretty
|
|
383
|
-
pnpm dev -- --help
|
|
384
|
-
```
|
|
385
|
-
|
|
386
|
-
Build:
|
|
387
|
-
|
|
388
|
-
```bash
|
|
389
|
-
pnpm build
|
|
390
|
-
```
|
|
391
|
-
|
|
392
|
-
Lint + type check + test:
|
|
393
|
-
|
|
394
|
-
```bash
|
|
395
|
-
pnpm lint
|
|
396
|
-
pnpm check
|
|
397
|
-
pnpm test
|
|
398
|
-
```
|
|
399
|
-
|
|
400
|
-
### Architecture
|
|
401
|
-
|
|
402
|
-
```
|
|
403
|
-
src/
|
|
404
|
-
index.ts Entry point — registers all subcommands
|
|
405
|
-
commands/ One file per command group
|
|
406
|
-
auth.ts OAuth login/status/logout
|
|
407
|
-
catalog.ts Public coffee catalog search
|
|
408
|
-
config.ts CLI configuration
|
|
409
|
-
context.ts Agent onboarding reference
|
|
410
|
-
inventory.ts Green coffee inventory management
|
|
411
|
-
roast.ts Roast profiles + Artisan .alog import
|
|
412
|
-
sales.ts Sales recording
|
|
413
|
-
tasting.ts Cupping notes and scoring
|
|
414
|
-
lib/ Business logic (no Commander dependencies)
|
|
415
|
-
supabase.ts Auth client + session management
|
|
416
|
-
catalog.ts Catalog query functions
|
|
417
|
-
inventory.ts Inventory CRUD
|
|
418
|
-
roast.ts Roast profile CRUD + import pipeline
|
|
419
|
-
sales.ts Sales CRUD
|
|
420
|
-
tasting.ts Tasting notes + cupping score logic
|
|
421
|
-
artisan/ Artisan .alog parser
|
|
422
|
-
interactive/ Interactive form prompts + watch mode
|
|
423
|
-
output.ts JSON/CSV output formatting
|
|
424
|
-
errors.ts Error handling + withErrorHandling wrapper
|
|
425
|
-
config.ts Local config read/write
|
|
426
|
-
```
|
|
427
|
-
|
|
428
|
-
See [AGENTS.md](./AGENTS.md) for the full contributor guide including code conventions and PR requirements.
|
|
446
|
+
Key files:
|
|
429
447
|
|
|
430
|
-
|
|
448
|
+
- `src/index.ts`: top-level CLI registration and global options
|
|
449
|
+
- `src/commands/`: command definitions and help text
|
|
450
|
+
- `src/lib/`: business logic and Supabase integration
|
|
451
|
+
- `src/commands/context.ts`: dense agent reference
|
|
452
|
+
- `AGENTS.md`: contributor guide
|
|
431
453
|
|
|
432
454
|
## License
|
|
433
455
|
|
|
434
456
|
Sustainable Use License. See [LICENSE.md](./LICENSE.md).
|
|
435
457
|
|
|
436
|
-
Copyright
|
|
458
|
+
Copyright 2026 Reed Whetstone / purveyors.io
|