@purveyors/cli 0.9.5 → 0.14.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.
Files changed (69) hide show
  1. package/README.md +199 -21
  2. package/dist/commands/auth.d.ts.map +1 -1
  3. package/dist/commands/auth.js +4 -3
  4. package/dist/commands/auth.js.map +1 -1
  5. package/dist/commands/catalog.d.ts.map +1 -1
  6. package/dist/commands/catalog.js +55 -31
  7. package/dist/commands/catalog.js.map +1 -1
  8. package/dist/commands/config.d.ts.map +1 -1
  9. package/dist/commands/config.js +61 -12
  10. package/dist/commands/config.js.map +1 -1
  11. package/dist/commands/context.d.ts.map +1 -1
  12. package/dist/commands/context.js +32 -231
  13. package/dist/commands/context.js.map +1 -1
  14. package/dist/commands/inventory.d.ts.map +1 -1
  15. package/dist/commands/inventory.js +5 -0
  16. package/dist/commands/inventory.js.map +1 -1
  17. package/dist/commands/manifest.d.ts +3 -0
  18. package/dist/commands/manifest.d.ts.map +1 -0
  19. package/dist/commands/manifest.js +28 -0
  20. package/dist/commands/manifest.js.map +1 -0
  21. package/dist/commands/roast.d.ts.map +1 -1
  22. package/dist/commands/roast.js +5 -0
  23. package/dist/commands/roast.js.map +1 -1
  24. package/dist/commands/sales.d.ts.map +1 -1
  25. package/dist/commands/sales.js +5 -0
  26. package/dist/commands/sales.js.map +1 -1
  27. package/dist/index.js +6 -105
  28. package/dist/index.js.map +1 -1
  29. package/dist/lib/catalog.d.ts.map +1 -1
  30. package/dist/lib/catalog.js +2 -6
  31. package/dist/lib/catalog.js.map +1 -1
  32. package/dist/lib/config.d.ts.map +1 -1
  33. package/dist/lib/config.js +8 -2
  34. package/dist/lib/config.js.map +1 -1
  35. package/dist/lib/errors.d.ts +13 -1
  36. package/dist/lib/errors.d.ts.map +1 -1
  37. package/dist/lib/errors.js +153 -10
  38. package/dist/lib/errors.js.map +1 -1
  39. package/dist/lib/index.d.ts +1 -0
  40. package/dist/lib/index.d.ts.map +1 -1
  41. package/dist/lib/index.js +1 -0
  42. package/dist/lib/index.js.map +1 -1
  43. package/dist/lib/inventory.d.ts +1 -0
  44. package/dist/lib/inventory.d.ts.map +1 -1
  45. package/dist/lib/inventory.js +3 -1
  46. package/dist/lib/inventory.js.map +1 -1
  47. package/dist/lib/manifest.d.ts +100 -0
  48. package/dist/lib/manifest.d.ts.map +1 -0
  49. package/dist/lib/manifest.js +919 -0
  50. package/dist/lib/manifest.js.map +1 -0
  51. package/dist/lib/output.d.ts +10 -0
  52. package/dist/lib/output.d.ts.map +1 -1
  53. package/dist/lib/output.js +33 -18
  54. package/dist/lib/output.js.map +1 -1
  55. package/dist/lib/roast.d.ts +1 -0
  56. package/dist/lib/roast.d.ts.map +1 -1
  57. package/dist/lib/roast.js +5 -1
  58. package/dist/lib/roast.js.map +1 -1
  59. package/dist/lib/sales.d.ts +1 -0
  60. package/dist/lib/sales.d.ts.map +1 -1
  61. package/dist/lib/sales.js +5 -1
  62. package/dist/lib/sales.js.map +1 -1
  63. package/dist/program.d.ts +4 -0
  64. package/dist/program.d.ts.map +1 -0
  65. package/dist/program.js +131 -0
  66. package/dist/program.js.map +1 -0
  67. package/dist/types/index.d.ts +4 -0
  68. package/dist/types/index.d.ts.map +1 -1
  69. package/package.json +2 -1
package/README.md CHANGED
@@ -4,7 +4,7 @@ Coffee intelligence from your terminal.
4
4
 
5
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
- Run `purvey context` for the dense agent reference.
7
+ Run `purvey manifest` for the machine-readable contract, `purvey context` for the dense human-readable reference, or import `@purveyors/cli/manifest` in-process.
8
8
 
9
9
  ## Installation
10
10
 
@@ -25,24 +25,37 @@ purvey --version
25
25
  ## Quick Start
26
26
 
27
27
  ```bash
28
- # 1. Authenticate
28
+ # 1. Authenticate before using catalog, inventory, roast, sales, or tasting commands
29
29
  purvey auth login
30
30
 
31
- # 2. Confirm the session
31
+ # For agents, CI, or remote machines, use headless flow:
32
+ # purvey auth login --headless
33
+
34
+ # 2. Confirm the session and role
32
35
  purvey auth status
33
36
 
34
- # 3. Search the catalog
37
+ # 3. Search the catalog (requires viewer role, granted on sign-in)
35
38
  purvey catalog search --origin "Ethiopia" --stocked --pretty
36
39
 
37
- # 4. Check inventory
40
+ # 4. Check inventory (requires member role)
38
41
  purvey inventory list --stocked --pretty
39
42
 
40
43
  # 5. Import a roast from Artisan
41
44
  purvey roast import ~/artisan/my-roast.alog --coffee-id 7 --pretty
45
+
46
+ # 6. (Agents/scripts) Get the machine-readable CLI contract in one command
47
+ purvey manifest
48
+
49
+ # 7. (Humans/agents) Get the dense readable CLI reference
50
+ purvey context
42
51
  ```
43
52
 
44
53
  ## Authentication
45
54
 
55
+ No pre-existing session is required for `auth`, `config`, `context`, or `manifest`.
56
+
57
+ **All remote data commands require a valid authenticated session.** `catalog`, `inventory`, `roast`, `sales`, and `tasting` all require auth.
58
+
46
59
  `purvey` uses Google OAuth through purveyors.io.
47
60
 
48
61
  Interactive login:
@@ -55,6 +68,9 @@ Headless login for agents, CI, and remote machines:
55
68
 
56
69
  ```bash
57
70
  purvey auth login --headless
71
+ # CLI prints a Google OAuth URL
72
+ # Open it in any browser and sign in
73
+ # Paste the full callback URL back into the terminal
58
74
  ```
59
75
 
60
76
  Status:
@@ -75,14 +91,18 @@ Credentials are stored at `~/.config/purvey/credentials.json`.
75
91
 
76
92
  ### Auth roles
77
93
 
78
- `catalog` commands require an authenticated viewer session. Sign in before using:
94
+ Two roles gate different command groups:
79
95
 
80
- - `purvey catalog search`
81
- - `purvey catalog get <id>`
82
- - `purvey catalog stats`
83
- - `purvey catalog similar <id>`
96
+ | Role | Commands |
97
+ | -------- | ------------------------------------------------------------------- |
98
+ | `viewer` | `catalog search`, `catalog get`, `catalog stats`, `catalog similar` |
99
+ | `member` | All viewer commands, plus `inventory`, `roast`, `sales`, `tasting` |
100
+
101
+ Both roles are granted when you sign in through purveyors.io. The `viewer` role is the minimum required for catalog access; the `member` role is required for any personal data or write operations.
102
+
103
+ `auth`, `config`, `context`, and `manifest` work without a pre-existing session. `config list/get/set/reset` are local-only commands, `context` is a local reference command, and `manifest` emits the machine-readable CLI contract.
84
104
 
85
- `inventory`, `roast`, `sales`, and `tasting` commands require a member role.
105
+ Commands that require a higher role will exit with code `3` (auth error) if you are not signed in or your role is insufficient. Run `purvey auth status` to confirm your current role before scripting.
86
106
 
87
107
  ## Output and Scripting
88
108
 
@@ -112,10 +132,49 @@ purvey auth status 2>/dev/null | jq -r '.email'
112
132
 
113
133
  Operational messages go to stderr, so stdout stays script-friendly.
114
134
 
135
+ Fatal errors also stay on stderr, but the payload format depends on mode:
136
+
137
+ - interactive terminal with no explicit output flag: human-readable text
138
+ - `--json`, `--pretty`, or `--csv`: JSON error envelope on stderr
139
+ - piped or redirected with no explicit flag: compact JSON error envelope on stderr
140
+
141
+ That same contract applies to parser-level mistakes too, including unknown options, unknown commands, and missing required arguments.
142
+
143
+ The JSON error envelope includes:
144
+
145
+ ```json
146
+ { "error": true, "code": "INVALID_ARGUMENT", "exitCode": 2, "message": "..." }
147
+ ```
148
+
115
149
  ### Output caveats worth knowing
116
150
 
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.
151
+ - `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 on stdout even when unauthenticated.
152
+ - `purvey config list/get/set/reset` stay human-readable in an interactive terminal, but emit JSON on stdout when you pass `--json` or `--pretty`, or when stdout is non-interactive. `--csv` is not supported for config commands.
118
153
  - `--json` is an explicit alias for the default compact JSON mode, and it forces JSON even in an interactive terminal.
154
+ - `--csv` affects successful stdout output only; fatal errors still use JSON on stderr.
155
+
156
+ ## Exit Codes
157
+
158
+ All `purvey` commands exit with a numeric code your scripts can check with `$?`.
159
+
160
+ | Code | Meaning |
161
+ | ---- | ----------------------------------------------------------------------------------------- |
162
+ | `0` | Success |
163
+ | `1` | Unexpected or unclassified error |
164
+ | `2` | Invalid argument or bad input |
165
+ | `3` | Auth error: not logged in, expired session, or insufficient role |
166
+ | `4` | Not found |
167
+ | `5` | Dependency conflict (for example, `inventory delete` without `--force` when roasts exist) |
168
+ | `6` | Local config error |
169
+
170
+ Scripting pattern:
171
+
172
+ ```bash
173
+ purvey catalog search --origin "Ethiopia" --stocked --json
174
+ if [ $? -eq 3 ]; then
175
+ purvey auth login --headless
176
+ fi
177
+ ```
119
178
 
120
179
  ## Command Reference
121
180
 
@@ -144,6 +203,9 @@ Operational messages go to stderr, so stdout stays script-friendly.
144
203
  - `--supplier <name>` -- filter by supplier/source name (partial match, case-insensitive)
145
204
  - `--ids <n,n,...>` -- fetch specific catalog IDs (comma-separated, ignores limit)
146
205
  - `--stocked` -- only show currently stocked coffees
206
+ - `--variety <text>` -- filter by coffee variety/cultivar (partial match)
207
+ - `--drying-method <text>` -- filter by drying method (partial match)
208
+ - `--stocked-days <n>` -- only show coffees stocked within N days
147
209
  - `--sort <price|price-desc|name|origin|newest>` -- sort results
148
210
  - `--offset <n>` -- skip N results for pagination
149
211
  - `--limit <n>` -- maximum results to return (default: 10)
@@ -171,12 +233,17 @@ purvey catalog similar 1182 --json | jq '.[0]'
171
233
  - `purvey inventory get <id>`
172
234
  - `purvey inventory add`
173
235
  - `purvey inventory update <id>`
174
- - `purvey inventory delete <id>`
236
+ - `purvey inventory delete <id>` (use `--force` to cascade delete dependent roasts and sales)
175
237
 
176
238
  `inventory list` options:
177
239
 
178
240
  - `--stocked` -- only show currently stocked beans
241
+ - `--catalog-id <id>` -- filter by catalog ID
242
+ - `--purchase-date-start <YYYY-MM-DD>` -- only show purchases on or after this date
243
+ - `--purchase-date-end <YYYY-MM-DD>` -- only show purchases on or before this date
244
+ - `--origin <country>` -- filter by country of origin (partial match)
179
245
  - `--limit <n>` -- maximum results (default: 20)
246
+ - `--offset <n>` -- skip N results for pagination (default: 0)
180
247
 
181
248
  `inventory add` flags:
182
249
 
@@ -200,6 +267,8 @@ Examples:
200
267
 
201
268
  ```bash
202
269
  purvey inventory list --stocked --pretty
270
+ purvey inventory list --limit 20 --offset 20 # page 2
271
+ purvey inventory list --csv > inventory.csv
203
272
  purvey inventory add --catalog-id 128 --qty 10 --cost 8.50
204
273
  purvey inventory add --catalog-id 42 --qty 5 --cost 6.25 --tax-ship 4.00
205
274
  purvey inventory update 7 --stocked false
@@ -221,11 +290,13 @@ purvey inventory delete 7 --yes
221
290
  - `--coffee-id <id>` -- filter by inventory item ID (green_coffee_inv.id)
222
291
  - `--roast-id <id>` -- filter by exact roast profile ID
223
292
  - `--batch-name <text>` -- filter by batch name (partial match, case-insensitive)
293
+ - `--coffee-name <text>` -- filter by bean name (partial match, case-insensitive)
224
294
  - `--date-start <YYYY-MM-DD>` -- only show roasts on or after this date
225
295
  - `--date-end <YYYY-MM-DD>` -- only show roasts on or before this date
226
296
  - `--stocked` -- only show roasts for currently stocked beans
227
297
  - `--catalog-id <id>` -- filter by coffee_catalog ID
228
298
  - `--limit <n>` -- maximum results (default: 20)
299
+ - `--offset <n>` -- skip N results for pagination (default: 0)
229
300
 
230
301
  `roast get <id>` options:
231
302
 
@@ -272,6 +343,7 @@ Examples:
272
343
  purvey roast list --catalog-id 128 --pretty
273
344
  purvey roast list --batch-name "Ethiopia Guji" --pretty
274
345
  purvey roast list --date-start 2026-03-01 --date-end 2026-03-31
346
+ purvey roast list --limit 20 --offset 20 # page 2
275
347
  purvey roast create --coffee-id 7 --batch-name "Ethiopia Guji Light" --oz-in 16
276
348
  purvey roast update 123 --targets "Aim for FC at 390F, 18% dev"
277
349
  purvey roast import ~/artisan/ethiopia.alog --coffee-id 7
@@ -285,6 +357,15 @@ purvey roast watch ~/artisan/ --auto-match
285
357
  - `purvey sales update <id>`
286
358
  - `purvey sales delete <id>`
287
359
 
360
+ `sales list` filters:
361
+
362
+ - `--roast-id <id>` -- filter by roast profile ID
363
+ - `--date-start <YYYY-MM-DD>` -- only show sales on or after this date
364
+ - `--date-end <YYYY-MM-DD>` -- only show sales on or before this date
365
+ - `--buyer <name>` -- filter by buyer name (partial match, case-insensitive)
366
+ - `--limit <n>` -- maximum results (default: 20)
367
+ - `--offset <n>` -- skip N results for pagination (default: 0)
368
+
288
369
  `sales record` flags:
289
370
 
290
371
  - `--roast-id <id>` -- [REQUIRED] roast_data.roast_id
@@ -306,20 +387,23 @@ Examples:
306
387
  ```bash
307
388
  purvey sales record --roast-id 123 --oz 12 --price 22.00 --buyer "Jane Smith"
308
389
  purvey sales list --pretty
390
+ purvey sales list --limit 20 --offset 20 # page 2
309
391
  purvey sales update 5 --price 24.00
310
392
  purvey sales delete 5 --yes
311
393
  ```
312
394
 
313
395
  ### tasting
314
396
 
315
- - `purvey tasting get <bean-id>`
316
- - `purvey tasting rate [bean-id]`
397
+ - `purvey tasting get <catalog-id>` -- retrieve tasting notes (uses `coffee_catalog.catalog_id`)
398
+ - `purvey tasting rate [inventory-id]` -- record cupping scores (uses `green_coffee_inv.id`)
399
+
400
+ **ID distinction:** `tasting get` takes a `catalog_id`; `tasting rate` takes an `inventory id`. These are different numbers. Use `purvey catalog search` to find a `catalog_id` and `purvey inventory list` to find your `inventory id`.
317
401
 
318
- `purvey tasting get <bean-id>` options:
402
+ `purvey tasting get <catalog-id>` options:
319
403
 
320
404
  - `--filter <user|supplier|both>` -- which notes to show (default: both)
321
405
 
322
- `purvey tasting rate [bean-id]` options:
406
+ `purvey tasting rate [inventory-id]` options:
323
407
 
324
408
  - `--aroma <1-5>` -- [REQUIRED in flag mode]
325
409
  - `--body <1-5>` -- [REQUIRED in flag mode]
@@ -333,7 +417,9 @@ purvey sales delete 5 --yes
333
417
  Examples:
334
418
 
335
419
  ```bash
420
+ # catalog_id 128 = the bean in the catalog
336
421
  purvey tasting get 128 --filter both --pretty
422
+ # inventory id 7 = your physical purchase from inventory
337
423
  purvey tasting rate 7 --aroma 4 --body 3 --acidity 5 --sweetness 4 --aftertaste 4
338
424
  purvey tasting rate 42 --aroma 3 --body 3 --acidity 3 --sweetness 3 --aftertaste 3 --notes "Underextracted"
339
425
  ```
@@ -349,18 +435,53 @@ Current config key:
349
435
 
350
436
  - `form-mode`: when set to `true`, write commands enter interactive mode when required args are missing
351
437
 
438
+ Output behavior:
439
+
440
+ - Interactive terminals keep config commands human-readable by default
441
+ - `--json` or `--pretty`, or any non-interactive stdout, emits JSON on stdout
442
+ - `--csv` is not supported for config commands
443
+
352
444
  Examples:
353
445
 
354
446
  ```bash
355
447
  purvey config set form-mode true
356
448
  purvey config get form-mode
449
+ purvey config get form-mode --json
450
+ purvey config reset --json
357
451
  ```
358
452
 
359
453
  ### context
360
454
 
361
455
  - `purvey context`
456
+ - `purvey context --json`
457
+ - `purvey context --pretty`
458
+
459
+ `purvey context` defaults to dense, human-readable, source-aware CLI reference text.
460
+
461
+ Use `--json` or `--pretty` when you want the same machine-readable manifest that `purvey manifest` emits.
462
+
463
+ ### manifest
464
+
465
+ - `purvey manifest`
466
+ - `purvey manifest --pretty`
362
467
 
363
- Use this when an agent needs a compact, source-aware CLI reference.
468
+ Use this when an agent or script needs the machine-readable contract directly. `purvey manifest` emits compact JSON by default.
469
+
470
+ `purvey manifest` and `purvey context --json` emit the same JSON manifest.
471
+
472
+ If you want indented JSON, add `--pretty` to either command.
473
+
474
+ ### in-process manifest
475
+
476
+ - `@purveyors/cli/manifest`
477
+
478
+ Use this when you need the same contract from Node.js without shelling out to the CLI. This package subpath is exported via `./manifest` in `package.json`.
479
+
480
+ ```ts
481
+ import { getCliManifest } from '@purveyors/cli/manifest';
482
+
483
+ const manifest = getCliManifest();
484
+ ```
364
485
 
365
486
  ## Common Workflows
366
487
 
@@ -412,6 +533,7 @@ Use the right ID for the right command.
412
533
  Start here:
413
534
 
414
535
  ```bash
536
+ purvey manifest
415
537
  purvey context
416
538
  ```
417
539
 
@@ -429,7 +551,56 @@ The CLI is designed to be agent-friendly:
429
551
  - structured output on stdout
430
552
  - headless auth flow
431
553
  - copy-pasteable examples
432
- - a dedicated `context` command for onboarding
554
+ - a dedicated `manifest` command for machine-readable onboarding
555
+ - a dedicated `context` command for dense human-readable onboarding
556
+ - `purvey context --json` parity with `purvey manifest`
557
+ - an `@purveyors/cli/manifest` export for in-process access
558
+ - documented exit codes for programmatic error handling
559
+ - `--offset` + `--limit` pagination on all list commands
560
+
561
+ The scripting contract: stdout is always structured success data (JSON or CSV). stderr carries status/spinner output plus fatal errors. In structured or non-interactive modes, fatal errors are JSON envelopes on stderr; in interactive no-flag mode, they stay human-readable. Exit codes are stable and documented above. Never expect success data on stderr.
562
+
563
+ ## Troubleshooting
564
+
565
+ **`Error: not logged in` or exit code 3**
566
+
567
+ ```bash
568
+ purvey auth login
569
+ # or for headless environments:
570
+ purvey auth login --headless
571
+ ```
572
+
573
+ **Catalog commands fail with auth error after logging in**
574
+
575
+ Run `purvey auth status` to confirm you have a `viewer` or `member` role. Both are granted automatically on sign-in. If auth status shows a stale session, run `purvey auth logout` then log in again.
576
+
577
+ **Wrong ID type passed to a command**
578
+
579
+ The most common mistake is mixing up ID types. Check the [ID Reference](#id-reference) section above. Use `purvey catalog search` to find `catalog_id` values; use `purvey inventory list` to find `inventory id` values.
580
+
581
+ **Pagination: only seeing the first 20 results**
582
+
583
+ All list commands default to 20 results. Use `--limit` and `--offset` to page through larger sets:
584
+
585
+ ```bash
586
+ purvey inventory list --limit 20 --offset 0 # page 1
587
+ purvey inventory list --limit 20 --offset 20 # page 2
588
+ purvey inventory list --limit 20 --offset 40 # page 3
589
+ ```
590
+
591
+ **`inventory delete` fails with dependency conflict (exit code 5)**
592
+
593
+ The item has dependent roast profiles or sales records. Use `--force` to cascade delete:
594
+
595
+ ```bash
596
+ purvey inventory delete 7 --force --yes
597
+ ```
598
+
599
+ **Enable verbose error output**
600
+
601
+ ```bash
602
+ PURVEY_DEBUG=1 purvey <command>
603
+ ```
433
604
 
434
605
  ## Development
435
606
 
@@ -445,12 +616,19 @@ npm test
445
616
 
446
617
  Key files:
447
618
 
448
- - `src/index.ts`: top-level CLI registration and global options
619
+ - `src/index.ts`: executable entrypoint
620
+ - `src/program.ts`: top-level CLI registration and global options
449
621
  - `src/commands/`: command definitions and help text
450
622
  - `src/lib/`: business logic and Supabase integration
451
- - `src/commands/context.ts`: dense agent reference
623
+ - `src/commands/context.ts`: dense human-readable agent reference
624
+ - `src/commands/manifest.ts`: machine-readable CLI manifest command
625
+ - `src/lib/manifest.ts`: shared manifest contract and renderer
626
+ - `package.json`: package metadata and export surface, including `./manifest`
452
627
  - `AGENTS.md`: contributor guide
453
628
 
629
+ Live documentation: [purveyors.io/docs](https://purveyors.io/docs)
630
+ Package: [npmjs.com/package/@purveyors/cli](https://www.npmjs.com/package/@purveyors/cli)
631
+
454
632
  ## License
455
633
 
456
634
  Sustainable Use License. See [LICENSE.md](./LICENSE.md).
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAoUpC;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CAkF1C"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAuUpC;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CAkF1C"}
@@ -3,7 +3,7 @@ import { createServer } from 'http';
3
3
  import { createAnonClient, validateSession } from '../lib/supabase.js';
4
4
  import { writeCredentials, deleteCredentials } from '../lib/config.js';
5
5
  import { outputData, shouldUseInteractiveOutput, success, info, warn } from '../lib/output.js';
6
- import { withErrorHandling, AuthError } from '../lib/errors.js';
6
+ import { withErrorHandling, AuthError, exitCodeForError } from '../lib/errors.js';
7
7
  import chalk from 'chalk';
8
8
  import ora from 'ora';
9
9
  const DEFAULT_CALLBACK_HOST = 'localhost';
@@ -159,12 +159,13 @@ const statusAction = withErrorHandling(async (_, cmd) => {
159
159
  authenticated: false,
160
160
  message: 'Not logged in. Run `purvey auth login` to authenticate.',
161
161
  };
162
+ const error = new AuthError(result.message);
162
163
  if (isInteractive) {
163
164
  warn(result.message);
164
- process.exit(1);
165
+ process.exit(exitCodeForError(error));
165
166
  }
166
167
  outputData(result, opts);
167
- process.exit(1);
168
+ process.exit(exitCodeForError(error));
168
169
  }
169
170
  const result = {
170
171
  authenticated: true,
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../../src/commands/catalog.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,OAAO,EAKL,mBAAmB,EACnB,mBAAmB,EAEpB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAiC,MAAM,mBAAmB,CAAC;AAIlG,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC;AAC1C,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,CAAC;AAIpD;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,OAAO,CAoQ7C"}
1
+ {"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../../src/commands/catalog.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,OAAO,EAKL,mBAAmB,EACnB,mBAAmB,EAEpB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAiC,MAAM,mBAAmB,CAAC;AAIlG,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC;AAC1C,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,CAAC;AAoCpD;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,OAAO,CAwS7C"}
@@ -1,9 +1,34 @@
1
1
  import { Command } from 'commander';
2
- import { outputData, info, warn } from '../lib/output.js';
3
- import { withErrorHandling } from '../lib/errors.js';
2
+ import { outputData, info } from '../lib/output.js';
3
+ import { withErrorHandling, PrvrsError } from '../lib/errors.js';
4
4
  import { requireAuth } from '../lib/auth-guard.js';
5
5
  import { searchCatalog, getCatalog, getCatalogStats, findSimilarBeans, computeCatalogStats, sanitizeFilterValue, catalogSortFields, } from '../lib/catalog.js';
6
6
  export { sanitizeFilterValue, computeCatalogStats };
7
+ function parseFiniteNumberArg(rawValue, message) {
8
+ const trimmed = rawValue.trim();
9
+ if (trimmed.length === 0) {
10
+ throw new PrvrsError('INVALID_ARGUMENT', message);
11
+ }
12
+ const parsed = Number(trimmed);
13
+ if (!Number.isFinite(parsed)) {
14
+ throw new PrvrsError('INVALID_ARGUMENT', message);
15
+ }
16
+ return parsed;
17
+ }
18
+ function parsePositiveIntegerArg(rawValue, message) {
19
+ const parsed = parseFiniteNumberArg(rawValue, message);
20
+ if (!Number.isInteger(parsed) || parsed <= 0) {
21
+ throw new PrvrsError('INVALID_ARGUMENT', message);
22
+ }
23
+ return parsed;
24
+ }
25
+ function parseNonNegativeIntegerArg(rawValue, message) {
26
+ const parsed = parseFiniteNumberArg(rawValue, message);
27
+ if (!Number.isInteger(parsed) || parsed < 0) {
28
+ throw new PrvrsError('INVALID_ARGUMENT', message);
29
+ }
30
+ return parsed;
31
+ }
7
32
  // ─── Command builder ──────────────────────────────────────────────────────────
8
33
  /**
9
34
  * `purvey catalog` — Browse the coffee catalog.
@@ -68,12 +93,10 @@ Notes:
68
93
  `)
69
94
  .action(withErrorHandling(async (opts, cmd) => {
70
95
  const globalOpts = cmd.optsWithGlobals();
71
- const { supabase } = await requireAuth('viewer');
72
96
  // Validate --sort if provided
73
97
  const sortValue = opts.sort;
74
98
  if (sortValue && !catalogSortFields.includes(sortValue)) {
75
- warn(`Invalid --sort value: "${sortValue}". Must be one of: ${catalogSortFields.join(', ')}`);
76
- process.exit(1);
99
+ throw new PrvrsError('INVALID_ARGUMENT', `Invalid --sort value: "${sortValue}". Must be one of: ${catalogSortFields.join(', ')}`);
77
100
  }
78
101
  // Parse --ids: comma-separated integers
79
102
  let parsedIds;
@@ -84,35 +107,40 @@ Notes:
84
107
  .filter(Boolean);
85
108
  const nums = [];
86
109
  for (const token of raw) {
87
- const n = parseInt(token, 10);
88
- if (isNaN(n) || n <= 0) {
89
- warn(`Invalid --ids value: "${token}". Each ID must be a positive integer.`);
90
- process.exit(1);
91
- }
92
- nums.push(n);
110
+ nums.push(parsePositiveIntegerArg(token, `Invalid --ids value: "${token}". Each ID must be a positive integer.`));
93
111
  }
94
112
  parsedIds = nums;
95
113
  }
114
+ const priceMin = opts.priceMin !== undefined
115
+ ? parseFiniteNumberArg(opts.priceMin, `Invalid --price-min: "${opts.priceMin}". Must be a number.`)
116
+ : undefined;
117
+ const priceMax = opts.priceMax !== undefined
118
+ ? parseFiniteNumberArg(opts.priceMax, `Invalid --price-max: "${opts.priceMax}". Must be a number.`)
119
+ : undefined;
120
+ const stockedDays = opts.stockedDays !== undefined
121
+ ? parsePositiveIntegerArg(opts.stockedDays, `Invalid --stocked-days: "${opts.stockedDays}". Must be a positive integer.`)
122
+ : undefined;
123
+ const offset = opts.offset !== undefined
124
+ ? parseNonNegativeIntegerArg(opts.offset, `Invalid --offset: "${opts.offset}". Must be a non-negative integer.`)
125
+ : undefined;
126
+ const limit = parsePositiveIntegerArg(opts.limit, `Invalid --limit: "${opts.limit}". Must be a positive integer.`);
127
+ const { supabase } = await requireAuth('viewer');
96
128
  const data = await searchCatalog(supabase, {
97
129
  origin: opts.origin,
98
130
  process: opts.process,
99
- priceMin: opts.priceMin !== undefined ? parseFloat(opts.priceMin) : undefined,
100
- priceMax: opts.priceMax !== undefined ? parseFloat(opts.priceMax) : undefined,
131
+ priceMin,
132
+ priceMax,
101
133
  flavor: opts.flavor,
102
134
  name: opts.name,
103
135
  supplier: opts.supplier,
104
136
  ids: parsedIds,
105
137
  variety: opts.variety,
106
138
  dryingMethod: opts.dryingMethod,
107
- stockedDays: opts.stockedDays !== undefined
108
- ? Math.max(1, parseInt(opts.stockedDays, 10))
109
- : undefined,
139
+ stockedDays,
110
140
  stocked: opts.stocked ? true : undefined,
111
141
  sort: sortValue,
112
- offset: opts.offset !== undefined
113
- ? Math.max(0, parseInt(opts.offset, 10))
114
- : undefined,
115
- limit: Math.max(1, parseInt(opts.limit, 10)),
142
+ offset,
143
+ limit,
116
144
  });
117
145
  if (data.length === 0) {
118
146
  info('No coffees found matching your criteria.');
@@ -137,8 +165,9 @@ Notes:
137
165
  `)
138
166
  .action(withErrorHandling(async (id, _opts, cmd) => {
139
167
  const globalOpts = cmd.optsWithGlobals();
168
+ const catalogId = parsePositiveIntegerArg(id, `Invalid ID: "${id}". Please provide a numeric coffee_catalog ID.`);
140
169
  const { supabase } = await requireAuth('viewer');
141
- const data = await getCatalog(supabase, parseInt(id, 10));
170
+ const data = await getCatalog(supabase, catalogId);
142
171
  outputData(data, globalOpts);
143
172
  }));
144
173
  // ── catalog stats ─────────────────────────────────────────────────────────
@@ -184,15 +213,11 @@ Notes:
184
213
  `)
185
214
  .action(withErrorHandling(async (id, opts, cmd) => {
186
215
  const globalOpts = cmd.optsWithGlobals();
187
- const { supabase } = await requireAuth('viewer');
188
- const coffeeId = parseInt(id, 10);
189
- if (isNaN(coffeeId)) {
190
- warn(`Invalid ID: "${id}". Please provide a numeric coffee_catalog ID.`);
191
- process.exit(1);
192
- }
193
- const threshold = parseFloat(opts.threshold);
194
- const limit = Math.max(1, parseInt(opts.limit, 10));
216
+ const coffeeId = parsePositiveIntegerArg(id, `Invalid ID: "${id}". Please provide a numeric coffee_catalog ID.`);
217
+ const threshold = parseFiniteNumberArg(opts.threshold, `Invalid --threshold: "${opts.threshold}". Must be a number between 0 and 1.`);
218
+ const limit = parsePositiveIntegerArg(opts.limit, `Invalid --limit: "${opts.limit}". Must be a positive integer.`);
195
219
  const stockedOnly = Boolean(opts.stockedOnly);
220
+ const { supabase } = await requireAuth('viewer');
196
221
  // Confirm the target bean exists before running similarity lookup.
197
222
  const { data: targetBean, error: targetError } = await supabase
198
223
  .from('coffee_catalog')
@@ -200,8 +225,7 @@ Notes:
200
225
  .eq('catalog_id', coffeeId)
201
226
  .single();
202
227
  if (targetError || !targetBean) {
203
- warn(`Coffee ID ${coffeeId} not found in catalog.`);
204
- process.exit(1);
228
+ throw new PrvrsError('NOT_FOUND', `Coffee ID ${coffeeId} not found in catalog.`);
205
229
  }
206
230
  // Call the lib function
207
231
  const results = await findSimilarBeans(supabase, {