@purveyors/cli 0.5.2 → 0.6.1
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 +292 -32
- package/dist/commands/auth.d.ts.map +1 -1
- package/dist/commands/auth.js +35 -4
- package/dist/commands/auth.js.map +1 -1
- package/dist/commands/catalog.d.ts +1 -1
- package/dist/commands/catalog.d.ts.map +1 -1
- package/dist/commands/catalog.js +41 -5
- package/dist/commands/catalog.js.map +1 -1
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +26 -0
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/context.d.ts +8 -0
- package/dist/commands/context.d.ts.map +1 -0
- package/dist/commands/context.js +282 -0
- package/dist/commands/context.js.map +1 -0
- package/dist/commands/inventory.d.ts +1 -1
- package/dist/commands/inventory.d.ts.map +1 -1
- package/dist/commands/inventory.js +78 -41
- package/dist/commands/inventory.js.map +1 -1
- package/dist/commands/roast.d.ts +1 -1
- package/dist/commands/roast.d.ts.map +1 -1
- package/dist/commands/roast.js +112 -63
- package/dist/commands/roast.js.map +1 -1
- package/dist/commands/sales.d.ts +1 -1
- package/dist/commands/sales.d.ts.map +1 -1
- package/dist/commands/sales.js +59 -34
- package/dist/commands/sales.js.map +1 -1
- package/dist/commands/tasting.d.ts +1 -1
- package/dist/commands/tasting.d.ts.map +1 -1
- package/dist/commands/tasting.js +46 -25
- package/dist/commands/tasting.js.map +1 -1
- package/dist/index.js +57 -28
- package/dist/index.js.map +1 -1
- package/dist/lib/ai.d.ts +1 -0
- package/dist/lib/ai.d.ts.map +1 -1
- package/dist/lib/ai.js.map +1 -1
- package/dist/lib/auth-guard.d.ts +14 -0
- package/dist/lib/auth-guard.d.ts.map +1 -0
- package/dist/lib/auth-guard.js +44 -0
- package/dist/lib/auth-guard.js.map +1 -0
- package/dist/lib/interactive/watch.js +7 -1
- package/dist/lib/interactive/watch.js.map +1 -1
- package/package.json +1 -1
package/dist/commands/config.js
CHANGED
|
@@ -13,6 +13,14 @@ export function buildConfigCommand() {
|
|
|
13
13
|
config
|
|
14
14
|
.command('list')
|
|
15
15
|
.description('Show all configuration values')
|
|
16
|
+
.addHelpText('after', `
|
|
17
|
+
Examples:
|
|
18
|
+
purvey config list
|
|
19
|
+
|
|
20
|
+
Notes:
|
|
21
|
+
Config is stored at ~/.config/purvey/config.json.
|
|
22
|
+
Shows all key = value pairs currently set.
|
|
23
|
+
`)
|
|
16
24
|
.action(withErrorHandling(async () => {
|
|
17
25
|
const cfg = await readConfig();
|
|
18
26
|
const keys = Object.keys(cfg);
|
|
@@ -30,6 +38,17 @@ export function buildConfigCommand() {
|
|
|
30
38
|
config
|
|
31
39
|
.command('get <key>')
|
|
32
40
|
.description('Get a single configuration value')
|
|
41
|
+
.addHelpText('after', `
|
|
42
|
+
Examples:
|
|
43
|
+
purvey config get form-mode
|
|
44
|
+
|
|
45
|
+
Supported keys:
|
|
46
|
+
form-mode true/false — auto-enter interactive wizard when required args are missing
|
|
47
|
+
|
|
48
|
+
Notes:
|
|
49
|
+
Prints the raw value to stdout (no decorators), suitable for scripting.
|
|
50
|
+
Prints "form-mode is not set." if the key has no value.
|
|
51
|
+
`)
|
|
33
52
|
.action(withErrorHandling(async (key) => {
|
|
34
53
|
if (!isValidConfigKey(key)) {
|
|
35
54
|
throw new PrvrsError('INVALID_ARGUMENT', `Unknown config key: "${key}". Valid keys: form-mode.`);
|
|
@@ -73,6 +92,13 @@ Examples:
|
|
|
73
92
|
config
|
|
74
93
|
.command('reset')
|
|
75
94
|
.description('Reset all configuration to defaults')
|
|
95
|
+
.addHelpText('after', `
|
|
96
|
+
Examples:
|
|
97
|
+
purvey config reset
|
|
98
|
+
|
|
99
|
+
Notes:
|
|
100
|
+
Clears all config values. Equivalent to deleting ~/.config/purvey/config.json.
|
|
101
|
+
`)
|
|
76
102
|
.action(withErrorHandling(async () => {
|
|
77
103
|
await writeConfig({});
|
|
78
104
|
success('Config reset to defaults.');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
/**
|
|
3
|
+
* `purvey context`
|
|
4
|
+
* Outputs a comprehensive CLI reference for AI agent onboarding.
|
|
5
|
+
* Optimized for token efficiency — dense, structured, no fluff.
|
|
6
|
+
*/
|
|
7
|
+
export declare function buildContextCommand(): Command;
|
|
8
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/commands/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA2QpC;;;;GAIG;AACH,wBAAgB,mBAAmB,IAAI,OAAO,CAe7C"}
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
// ─── Agent Context Reference ──────────────────────────────────────────────────
|
|
3
|
+
//
|
|
4
|
+
// This text is optimized for token efficiency: dense, structured, no fluff.
|
|
5
|
+
// An agent reading this once should be able to use every CLI command correctly.
|
|
6
|
+
const CONTEXT_TEXT = `
|
|
7
|
+
PURVEY CLI — Agent Reference v0.5
|
|
8
|
+
==================================
|
|
9
|
+
CLI for purveyors.io coffee marketplace. Node >=20 required.
|
|
10
|
+
Credentials: ~/.config/purvey/credentials.json (auto-refreshed, do not edit)
|
|
11
|
+
|
|
12
|
+
ROLES
|
|
13
|
+
-----
|
|
14
|
+
viewer — catalog commands only (no login required for catalog search/get/stats)
|
|
15
|
+
member — all commands; required for inventory, roast, sales, tasting
|
|
16
|
+
|
|
17
|
+
AUTHENTICATION
|
|
18
|
+
--------------
|
|
19
|
+
Browser login (interactive):
|
|
20
|
+
purvey auth login
|
|
21
|
+
|
|
22
|
+
Headless login (agents/CI — no browser):
|
|
23
|
+
purvey auth login --headless
|
|
24
|
+
→ prints Google OAuth URL
|
|
25
|
+
→ user opens URL, signs in, copies callback URL
|
|
26
|
+
→ paste callback URL back at prompt
|
|
27
|
+
Token auto-refreshes; no action needed between sessions.
|
|
28
|
+
|
|
29
|
+
Check status:
|
|
30
|
+
purvey auth status --pretty
|
|
31
|
+
purvey auth status # compact JSON: {"authenticated":true,"email":"...","role":"..."}
|
|
32
|
+
|
|
33
|
+
Logout:
|
|
34
|
+
purvey auth logout
|
|
35
|
+
|
|
36
|
+
OUTPUT FORMATS
|
|
37
|
+
--------------
|
|
38
|
+
Default: compact single-line JSON (machine-readable, pipeable to jq)
|
|
39
|
+
--pretty: indented + colorized JSON (human-readable)
|
|
40
|
+
--csv: CSV rows (pipeable to spreadsheets)
|
|
41
|
+
User feedback (spinners, success/error) → stderr only; stdout is always clean data.
|
|
42
|
+
|
|
43
|
+
DATA MODEL
|
|
44
|
+
----------
|
|
45
|
+
coffee_catalog (catalog_id)
|
|
46
|
+
└─ green_coffee_inv (id, user, catalog_id) ← your inventory
|
|
47
|
+
├─ roast_data (roast_id, coffee_id) ← your roast profiles
|
|
48
|
+
│ ├─ roast_temperatures ← temperature curve
|
|
49
|
+
│ └─ roast_events ← FC, drop, etc.
|
|
50
|
+
├─ coffee_sales (id, roast_id) ← your sales
|
|
51
|
+
└─ cupping notes stored on green_coffee_inv (aroma/body/acidity/sweetness/aftertaste)
|
|
52
|
+
|
|
53
|
+
CATALOG COMMANDS (no auth required)
|
|
54
|
+
-------------------------------------
|
|
55
|
+
Search the public catalog:
|
|
56
|
+
purvey catalog search [options]
|
|
57
|
+
Options (all optional):
|
|
58
|
+
--origin <text> country/region (e.g. "Ethiopia", "Colombia")
|
|
59
|
+
--process <method> natural|washed|honey
|
|
60
|
+
--price-min <n> min USD/lb
|
|
61
|
+
--price-max <n> max USD/lb
|
|
62
|
+
--flavor <keywords> comma-separated (e.g. "blueberry,citrus")
|
|
63
|
+
--stocked only currently stocked
|
|
64
|
+
--limit <n> max results (default: 10)
|
|
65
|
+
Returns: array of catalog items with id, name, origin, process, flavor_notes, cost_lb, stocked
|
|
66
|
+
|
|
67
|
+
Get one catalog item by ID:
|
|
68
|
+
purvey catalog get <catalog_id>
|
|
69
|
+
Returns: single catalog item object
|
|
70
|
+
|
|
71
|
+
Catalog statistics:
|
|
72
|
+
purvey catalog stats
|
|
73
|
+
Returns: aggregate stats (count, avg_price, origins, processes, etc.)
|
|
74
|
+
|
|
75
|
+
INVENTORY COMMANDS (member role required)
|
|
76
|
+
------------------------------------------
|
|
77
|
+
List your green coffee inventory:
|
|
78
|
+
purvey inventory list [options]
|
|
79
|
+
Options:
|
|
80
|
+
--stocked only stocked beans
|
|
81
|
+
--limit <n> max results (default: 20)
|
|
82
|
+
Returns: array with id, catalog_id, qty, cost, stocked, purchase_date, plus joined catalog fields
|
|
83
|
+
|
|
84
|
+
Get one inventory item:
|
|
85
|
+
purvey inventory get <id>
|
|
86
|
+
Returns: single inventory item
|
|
87
|
+
|
|
88
|
+
Add bean to inventory (REQUIRED: --catalog-id, --qty):
|
|
89
|
+
purvey inventory add --catalog-id <id> --qty <lbs> [options]
|
|
90
|
+
Options:
|
|
91
|
+
--catalog-id <id> [REQUIRED] coffee_catalog id
|
|
92
|
+
--qty <lbs> [REQUIRED] pounds purchased
|
|
93
|
+
--cost <dollars> cost per lb
|
|
94
|
+
--tax-ship <dollars> tax + shipping cost
|
|
95
|
+
--notes <text> notes
|
|
96
|
+
--purchase-date <YYYY-MM-DD> defaults to today
|
|
97
|
+
--form interactive wizard
|
|
98
|
+
Returns: created inventory item
|
|
99
|
+
|
|
100
|
+
Update inventory item:
|
|
101
|
+
purvey inventory update <id> [options]
|
|
102
|
+
Options (at least one required):
|
|
103
|
+
--qty <lbs> updated quantity
|
|
104
|
+
--cost <dollars> updated cost
|
|
105
|
+
--tax-ship <dollars> updated tax/shipping
|
|
106
|
+
--notes <text> updated notes
|
|
107
|
+
--stocked <true|false> mark as stocked/unstocked
|
|
108
|
+
Returns: updated inventory item
|
|
109
|
+
|
|
110
|
+
Delete inventory item:
|
|
111
|
+
purvey inventory delete <id> [-y]
|
|
112
|
+
-y skips confirmation prompt
|
|
113
|
+
|
|
114
|
+
ROAST COMMANDS (member role required)
|
|
115
|
+
---------------------------------------
|
|
116
|
+
List roast profiles:
|
|
117
|
+
purvey roast list [options]
|
|
118
|
+
Options:
|
|
119
|
+
--coffee-id <id> filter by inventory item id
|
|
120
|
+
--limit <n> max results (default: 20)
|
|
121
|
+
Returns: array of roast profiles with roast_id, batch_name, roast_date, oz_in, oz_out
|
|
122
|
+
|
|
123
|
+
Get roast profile:
|
|
124
|
+
purvey roast get <roast_id> [options]
|
|
125
|
+
Options:
|
|
126
|
+
--include-temps include temperature curve data
|
|
127
|
+
--include-events include roast events (FC, drop, etc.)
|
|
128
|
+
Returns: roast profile object
|
|
129
|
+
|
|
130
|
+
Create roast profile (REQUIRED: --coffee-id):
|
|
131
|
+
purvey roast create --coffee-id <id> [options]
|
|
132
|
+
Options:
|
|
133
|
+
--coffee-id <id> [REQUIRED] green_coffee_inv id
|
|
134
|
+
--batch-name <name> defaults to "CoffeeName YYYY-MM-DD"
|
|
135
|
+
--oz-in <oz> green weight in ounces
|
|
136
|
+
--oz-out <oz> roasted weight in ounces
|
|
137
|
+
--roast-date <YYYY-MM-DD> defaults to today
|
|
138
|
+
--notes <text> roast notes
|
|
139
|
+
--form interactive wizard
|
|
140
|
+
Returns: created roast profile
|
|
141
|
+
|
|
142
|
+
Delete roast profile:
|
|
143
|
+
purvey roast delete <roast_id> [-y]
|
|
144
|
+
|
|
145
|
+
Import Artisan .alog file (REQUIRED: <file>, --coffee-id):
|
|
146
|
+
purvey roast import <file.alog> --coffee-id <id> [options]
|
|
147
|
+
Options:
|
|
148
|
+
--coffee-id <id> [REQUIRED] green_coffee_inv id
|
|
149
|
+
--batch-name <name> auto-generated if omitted
|
|
150
|
+
--oz-in <oz> extracted from .alog if omitted
|
|
151
|
+
--roast-notes <text> additional notes
|
|
152
|
+
--form interactive wizard
|
|
153
|
+
Returns: roast profile + milestone_events + control_events counts
|
|
154
|
+
|
|
155
|
+
Watch directory for new .alog files (REQUIRED: <directory>):
|
|
156
|
+
purvey roast watch <directory> [options]
|
|
157
|
+
Options:
|
|
158
|
+
--coffee-id <id> [REQUIRED unless --auto-match] green_coffee_inv id
|
|
159
|
+
--batch-prefix <name> prefix for batch names
|
|
160
|
+
--auto-match AI matches bean per file (requires member role; mutually exclusive with --coffee-id)
|
|
161
|
+
--prompt-each prompt for bean on each new file
|
|
162
|
+
--resume resume previous watch session
|
|
163
|
+
--form interactive wizard
|
|
164
|
+
Runs continuously (Ctrl+C to stop). Persists session for --resume.
|
|
165
|
+
|
|
166
|
+
SALES COMMANDS (member role required)
|
|
167
|
+
---------------------------------------
|
|
168
|
+
List sales:
|
|
169
|
+
purvey sales list [--limit <n>]
|
|
170
|
+
Returns: array with id, roast_id, oz, price, buyer, sell_date
|
|
171
|
+
|
|
172
|
+
Record sale (REQUIRED: --roast-id, --oz, --price):
|
|
173
|
+
purvey sales record --roast-id <id> --oz <amount> --price <dollars> [options]
|
|
174
|
+
Options:
|
|
175
|
+
--roast-id <id> [REQUIRED] roast_data id
|
|
176
|
+
--oz <amount> [REQUIRED] ounces sold
|
|
177
|
+
--price <dollars> [REQUIRED] sale price
|
|
178
|
+
--buyer <name> buyer name/identifier
|
|
179
|
+
--sell-date <YYYY-MM-DD> defaults to today
|
|
180
|
+
--form interactive wizard
|
|
181
|
+
Returns: created sale record
|
|
182
|
+
|
|
183
|
+
Update sale:
|
|
184
|
+
purvey sales update <id> [--oz <n>] [--price <n>] [--buyer <name>] [--sell-date <date>]
|
|
185
|
+
|
|
186
|
+
Delete sale:
|
|
187
|
+
purvey sales delete <id> [-y]
|
|
188
|
+
|
|
189
|
+
TASTING COMMANDS (member role required)
|
|
190
|
+
-----------------------------------------
|
|
191
|
+
Get tasting notes for a catalog item:
|
|
192
|
+
purvey tasting get <catalog_id> [--filter user|supplier|both]
|
|
193
|
+
--filter both (default): returns {supplier: {...}, user: {...}}
|
|
194
|
+
--filter user: only your cupping notes from green_coffee_inv
|
|
195
|
+
--filter supplier: only the supplier's flavor notes from coffee_catalog
|
|
196
|
+
|
|
197
|
+
Rate a bean (REQUIRED: <inventory_id>, all score flags):
|
|
198
|
+
purvey tasting rate <inventory_id> --aroma <1-5> --body <1-5> --acidity <1-5> --sweetness <1-5> --aftertaste <1-5> [options]
|
|
199
|
+
Options:
|
|
200
|
+
--aroma <1-5> [REQUIRED in flag mode] integer 1-5
|
|
201
|
+
--body <1-5> [REQUIRED in flag mode] integer 1-5
|
|
202
|
+
--acidity <1-5> [REQUIRED in flag mode] integer 1-5
|
|
203
|
+
--sweetness <1-5> [REQUIRED in flag mode] integer 1-5
|
|
204
|
+
--aftertaste <1-5> [REQUIRED in flag mode] integer 1-5
|
|
205
|
+
--brew-method pour_over|french_press|espresso|etc
|
|
206
|
+
--notes <text> tasting notes
|
|
207
|
+
--form interactive wizard
|
|
208
|
+
Note: <inventory_id> is green_coffee_inv.id, NOT catalog_id.
|
|
209
|
+
Scores are stored on the green_coffee_inv row.
|
|
210
|
+
|
|
211
|
+
CONFIG COMMANDS
|
|
212
|
+
---------------
|
|
213
|
+
purvey config list show all config
|
|
214
|
+
purvey config get form-mode get a value
|
|
215
|
+
purvey config set form-mode true|false set a value
|
|
216
|
+
purvey config reset clear all config
|
|
217
|
+
|
|
218
|
+
Config keys:
|
|
219
|
+
form-mode true|false — when true, write commands auto-enter interactive
|
|
220
|
+
wizard if required args are missing (default: false)
|
|
221
|
+
|
|
222
|
+
COMMON WORKFLOWS
|
|
223
|
+
----------------
|
|
224
|
+
1. Import a roast and rate it:
|
|
225
|
+
purvey inventory list --stocked --pretty # find your bean id
|
|
226
|
+
purvey roast import roast.alog --coffee-id 42 # import
|
|
227
|
+
purvey tasting rate 42 --aroma 4 --body 3 --acidity 5 --sweetness 4 --aftertaste 4
|
|
228
|
+
|
|
229
|
+
2. Full workflow: buy → roast → sell:
|
|
230
|
+
purvey catalog search --origin "Ethiopia" --stocked --pretty
|
|
231
|
+
purvey inventory add --catalog-id 128 --qty 10 --cost 8.50
|
|
232
|
+
purvey roast create --coffee-id 7 --oz-in 16 --batch-name "Ethiopia Guji Light"
|
|
233
|
+
purvey sales record --roast-id 123 --oz 12 --price 22.00 --buyer "Jane"
|
|
234
|
+
|
|
235
|
+
3. Watch directory and auto-import roasts:
|
|
236
|
+
purvey roast watch ~/artisan/ --coffee-id 7
|
|
237
|
+
# or with AI bean matching:
|
|
238
|
+
purvey roast watch ~/artisan/ --auto-match
|
|
239
|
+
|
|
240
|
+
4. Find a coffee and check tasting notes:
|
|
241
|
+
purvey catalog search --flavor "blueberry,floral" --pretty
|
|
242
|
+
purvey tasting get 128 --filter both --pretty
|
|
243
|
+
|
|
244
|
+
ERROR HANDLING
|
|
245
|
+
--------------
|
|
246
|
+
Exit 0: success
|
|
247
|
+
Exit 1: error (auth failure, not found, validation error, API error)
|
|
248
|
+
Errors go to stderr as: Error: <message>
|
|
249
|
+
|
|
250
|
+
Common errors:
|
|
251
|
+
"Not logged in" → run: purvey auth login [--headless]
|
|
252
|
+
"Not found" → check the ID; must be yours (RLS enforced)
|
|
253
|
+
"INVALID_ARGUMENT" → check flags; use --form for interactive mode
|
|
254
|
+
"--auto-match and --coffee-id are mutually exclusive" → use one or the other
|
|
255
|
+
|
|
256
|
+
ID TYPES (avoid confusion)
|
|
257
|
+
---------------------------
|
|
258
|
+
catalog_id → coffee_catalog table; used with: catalog get, inventory add --catalog-id, tasting get
|
|
259
|
+
inventory_id → green_coffee_inv table (your beans); used with: inventory get/update/delete, roast --coffee-id, tasting rate
|
|
260
|
+
roast_id → roast_data table; used with: roast get/delete, sales --roast-id
|
|
261
|
+
sale_id → coffee_sales table; used with: sales update/delete
|
|
262
|
+
`.trim();
|
|
263
|
+
// ─── Command builder ──────────────────────────────────────────────────────────
|
|
264
|
+
/**
|
|
265
|
+
* `purvey context`
|
|
266
|
+
* Outputs a comprehensive CLI reference for AI agent onboarding.
|
|
267
|
+
* Optimized for token efficiency — dense, structured, no fluff.
|
|
268
|
+
*/
|
|
269
|
+
export function buildContextCommand() {
|
|
270
|
+
return new Command('context')
|
|
271
|
+
.description('Output full CLI reference for AI agent onboarding')
|
|
272
|
+
.addHelpText('after', `
|
|
273
|
+
Examples:
|
|
274
|
+
purvey context # print full reference to stdout
|
|
275
|
+
purvey context | head -50 # preview first section
|
|
276
|
+
purvey context > cli-ref.txt # save to file
|
|
277
|
+
`)
|
|
278
|
+
.action(() => {
|
|
279
|
+
console.log(CONTEXT_TEXT);
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/commands/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,iFAAiF;AACjF,EAAE;AACF,4EAA4E;AAC5E,gFAAgF;AAEhF,MAAM,YAAY,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgQpB,CAAC,IAAI,EAAE,CAAC;AAET,iFAAiF;AAEjF;;;;GAIG;AACH,MAAM,UAAU,mBAAmB;IACjC,OAAO,IAAI,OAAO,CAAC,SAAS,CAAC;SAC1B,WAAW,CAAC,mDAAmD,CAAC;SAChE,WAAW,CACV,OAAO,EACP;;;;;CAKL,CACI;SACA,MAAM,CAAC,GAAG,EAAE;QACX,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IAC5B,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -3,7 +3,7 @@ import type { InventoryItem } from '../lib/inventory.js';
|
|
|
3
3
|
export type { InventoryItem };
|
|
4
4
|
/**
|
|
5
5
|
* `purvey inventory` — Manage your green coffee inventory.
|
|
6
|
-
* Requires authentication.
|
|
6
|
+
* Requires member+ authentication.
|
|
7
7
|
*/
|
|
8
8
|
export declare function buildInventoryCommand(): Command;
|
|
9
9
|
//# sourceMappingURL=inventory.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inventory.d.ts","sourceRoot":"","sources":["../../src/commands/inventory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAcpC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAKzD,YAAY,EAAE,aAAa,EAAE,CAAC;AAI9B;;;GAGG;AACH,wBAAgB,qBAAqB,IAAI,OAAO,
|
|
1
|
+
{"version":3,"file":"inventory.d.ts","sourceRoot":"","sources":["../../src/commands/inventory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAcpC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAKzD,YAAY,EAAE,aAAa,EAAE,CAAC;AAI9B;;;GAGG;AACH,wBAAgB,qBAAqB,IAAI,OAAO,CA4V/C"}
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import * as p from '@clack/prompts';
|
|
3
|
-
import { createAuthenticatedClient } from '../lib/supabase.js';
|
|
4
3
|
import { getConfigValue } from '../lib/config.js';
|
|
5
4
|
import { outputData, info, success } from '../lib/output.js';
|
|
6
|
-
import { withErrorHandling,
|
|
5
|
+
import { withErrorHandling, PrvrsError } from '../lib/errors.js';
|
|
6
|
+
import { requireAuth } from '../lib/auth-guard.js';
|
|
7
7
|
import { confirm, todayIso } from '../lib/prompts.js';
|
|
8
8
|
import { listInventory, getInventory, addInventory, updateInventory, deleteInventory, } from '../lib/inventory.js';
|
|
9
9
|
import { pickCatalogItem, guardCancel } from '../lib/interactive/forms.js';
|
|
10
10
|
// ─── Command builder ──────────────────────────────────────────────────────────
|
|
11
11
|
/**
|
|
12
12
|
* `purvey inventory` — Manage your green coffee inventory.
|
|
13
|
-
* Requires authentication.
|
|
13
|
+
* Requires member+ authentication.
|
|
14
14
|
*/
|
|
15
15
|
export function buildInventoryCommand() {
|
|
16
16
|
const inventory = new Command('inventory').description('Manage your green coffee inventory');
|
|
@@ -20,14 +20,23 @@ export function buildInventoryCommand() {
|
|
|
20
20
|
.description('List your green coffee inventory with catalog details')
|
|
21
21
|
.option('--stocked', 'Only show currently stocked beans')
|
|
22
22
|
.option('--limit <n>', 'Maximum results to return', '20')
|
|
23
|
+
.addHelpText('after', `
|
|
24
|
+
Examples:
|
|
25
|
+
purvey inventory list --pretty
|
|
26
|
+
purvey inventory list --stocked --pretty
|
|
27
|
+
purvey inventory list --limit 50 | jq '.[].id'
|
|
28
|
+
purvey inventory list --csv > inventory.csv
|
|
29
|
+
|
|
30
|
+
Notes:
|
|
31
|
+
Returns your green_coffee_inv rows joined with catalog details.
|
|
32
|
+
The "id" field in each row is your inventory ID (used for roast --coffee-id,
|
|
33
|
+
tasting rate, etc.) — distinct from catalog_id.
|
|
34
|
+
Requires authentication (member role).
|
|
35
|
+
`)
|
|
23
36
|
.action(withErrorHandling(async (opts, cmd) => {
|
|
24
37
|
const globalOpts = cmd.optsWithGlobals();
|
|
25
|
-
const supabase = await
|
|
26
|
-
const
|
|
27
|
-
if (!user) {
|
|
28
|
-
throw new AuthError('Not logged in. Run `purvey auth login` first.');
|
|
29
|
-
}
|
|
30
|
-
const data = await listInventory(supabase, user.id, {
|
|
38
|
+
const { supabase, userId } = await requireAuth('member');
|
|
39
|
+
const data = await listInventory(supabase, userId, {
|
|
31
40
|
stocked: opts.stocked ? true : undefined,
|
|
32
41
|
limit: Math.max(1, parseInt(opts.limit, 10)),
|
|
33
42
|
});
|
|
@@ -41,34 +50,48 @@ export function buildInventoryCommand() {
|
|
|
41
50
|
inventory
|
|
42
51
|
.command('get <id>')
|
|
43
52
|
.description('Fetch a single inventory item by ID (must be yours)')
|
|
53
|
+
.addHelpText('after', `
|
|
54
|
+
Examples:
|
|
55
|
+
purvey inventory get 7 --pretty
|
|
56
|
+
purvey inventory get 42 | jq '{id, qty, cost, stocked}'
|
|
57
|
+
|
|
58
|
+
Notes:
|
|
59
|
+
<id> is green_coffee_inv.id (integer).
|
|
60
|
+
Row-level security: only returns items belonging to the logged-in user.
|
|
61
|
+
Requires authentication (member role).
|
|
62
|
+
`)
|
|
44
63
|
.action(withErrorHandling(async (id, _opts, cmd) => {
|
|
45
64
|
const globalOpts = cmd.optsWithGlobals();
|
|
46
|
-
const supabase = await
|
|
47
|
-
const
|
|
48
|
-
if (!user) {
|
|
49
|
-
throw new AuthError('Not logged in. Run `purvey auth login` first.');
|
|
50
|
-
}
|
|
51
|
-
const data = await getInventory(supabase, user.id, parseInt(id, 10));
|
|
65
|
+
const { supabase, userId } = await requireAuth('member');
|
|
66
|
+
const data = await getInventory(supabase, userId, parseInt(id, 10));
|
|
52
67
|
outputData(data, globalOpts);
|
|
53
68
|
}));
|
|
54
69
|
// ── inventory add ─────────────────────────────────────────────────────────
|
|
55
70
|
inventory
|
|
56
71
|
.command('add')
|
|
57
72
|
.description('Add a new green coffee inventory item')
|
|
58
|
-
.option('--catalog-id <id>', 'Coffee catalog entry ID')
|
|
59
|
-
.option('--qty <lbs>', 'Quantity purchased in pounds')
|
|
60
|
-
.option('--cost <dollars>', 'Bean cost in dollars')
|
|
61
|
-
.option('--tax-ship <dollars>', 'Tax and shipping cost in dollars')
|
|
62
|
-
.option('--notes <text>', 'Notes for this inventory item')
|
|
73
|
+
.option('--catalog-id <id>', '[REQUIRED] Coffee catalog entry ID (coffee_catalog.catalog_id)')
|
|
74
|
+
.option('--qty <lbs>', '[REQUIRED] Quantity purchased in pounds')
|
|
75
|
+
.option('--cost <dollars>', 'Bean cost in dollars (optional)')
|
|
76
|
+
.option('--tax-ship <dollars>', 'Tax and shipping cost in dollars (optional)')
|
|
77
|
+
.option('--notes <text>', 'Notes for this inventory item (optional)')
|
|
63
78
|
.option('--purchase-date <YYYY-MM-DD>', 'Purchase date (defaults to today)')
|
|
64
|
-
.option('--form', 'Interactive form mode')
|
|
79
|
+
.option('--form', 'Interactive form mode (prompts for all fields)')
|
|
80
|
+
.addHelpText('after', `
|
|
81
|
+
Examples:
|
|
82
|
+
purvey inventory add --catalog-id 128 --qty 10 --cost 8.50 --pretty
|
|
83
|
+
purvey inventory add --catalog-id 42 --qty 5 --cost 6.25 --tax-ship 4.00
|
|
84
|
+
purvey inventory add --catalog-id 77 --qty 25 --purchase-date 2026-03-01
|
|
85
|
+
purvey inventory add --form # interactive wizard
|
|
86
|
+
|
|
87
|
+
Required flags: --catalog-id, --qty
|
|
88
|
+
Use 'purvey catalog search' to find a --catalog-id.
|
|
89
|
+
Use --form if you prefer to browse and select interactively.
|
|
90
|
+
Requires authentication (member role).
|
|
91
|
+
`)
|
|
65
92
|
.action(withErrorHandling(async (opts, cmd) => {
|
|
66
93
|
const globalOpts = cmd.optsWithGlobals();
|
|
67
|
-
const supabase = await
|
|
68
|
-
const { data: { user }, } = await supabase.auth.getUser();
|
|
69
|
-
if (!user) {
|
|
70
|
-
throw new AuthError('Not logged in. Run `purvey auth login` first.');
|
|
71
|
-
}
|
|
94
|
+
const { supabase, userId } = await requireAuth('member');
|
|
72
95
|
// ── Interactive form mode ──────────────────────────────────────────
|
|
73
96
|
// Auto-enter form mode if config form-mode is true and required args are missing
|
|
74
97
|
const formMode = opts.form ||
|
|
@@ -109,7 +132,7 @@ export function buildInventoryCommand() {
|
|
|
109
132
|
const qtyStr = String(qtyRaw);
|
|
110
133
|
const spin = p.spinner();
|
|
111
134
|
spin.start('Adding bean to inventory...');
|
|
112
|
-
const data = await addInventory(supabase,
|
|
135
|
+
const data = await addInventory(supabase, userId, {
|
|
113
136
|
catalogId: catalogItem.id,
|
|
114
137
|
qty: parseFloat(qtyStr),
|
|
115
138
|
cost,
|
|
@@ -144,7 +167,7 @@ export function buildInventoryCommand() {
|
|
|
144
167
|
if (taxShip !== undefined && isNaN(taxShip)) {
|
|
145
168
|
throw new PrvrsError('INVALID_ARGUMENT', `Invalid --tax-ship: "${opts.taxShip}".`);
|
|
146
169
|
}
|
|
147
|
-
const data = await addInventory(supabase,
|
|
170
|
+
const data = await addInventory(supabase, userId, {
|
|
148
171
|
catalogId,
|
|
149
172
|
qty,
|
|
150
173
|
cost,
|
|
@@ -163,14 +186,22 @@ export function buildInventoryCommand() {
|
|
|
163
186
|
.option('--cost <dollars>', 'Updated bean cost')
|
|
164
187
|
.option('--tax-ship <dollars>', 'Updated tax/shipping cost')
|
|
165
188
|
.option('--notes <text>', 'Updated notes')
|
|
166
|
-
.option('--stocked <bool>', 'Mark as stocked
|
|
189
|
+
.option('--stocked <bool>', 'Mark as stocked: true or false')
|
|
190
|
+
.addHelpText('after', `
|
|
191
|
+
Examples:
|
|
192
|
+
purvey inventory update 7 --qty 8.5
|
|
193
|
+
purvey inventory update 7 --stocked false
|
|
194
|
+
purvey inventory update 7 --cost 9.00 --notes "bulk discount applied"
|
|
195
|
+
purvey inventory update 42 --stocked true --qty 15
|
|
196
|
+
|
|
197
|
+
Notes:
|
|
198
|
+
At least one flag required. Pass only the fields you want to change.
|
|
199
|
+
--stocked accepts "true" or "false" (string, not flag).
|
|
200
|
+
Requires authentication (member role).
|
|
201
|
+
`)
|
|
167
202
|
.action(withErrorHandling(async (id, opts, cmd) => {
|
|
168
203
|
const globalOpts = cmd.optsWithGlobals();
|
|
169
|
-
const supabase = await
|
|
170
|
-
const { data: { user }, } = await supabase.auth.getUser();
|
|
171
|
-
if (!user) {
|
|
172
|
-
throw new AuthError('Not logged in. Run `purvey auth login` first.');
|
|
173
|
-
}
|
|
204
|
+
const { supabase, userId } = await requireAuth('member');
|
|
174
205
|
const itemId = parseInt(id, 10);
|
|
175
206
|
if (isNaN(itemId)) {
|
|
176
207
|
throw new PrvrsError('INVALID_ARGUMENT', `Invalid inventory ID: "${id}".`);
|
|
@@ -209,7 +240,7 @@ export function buildInventoryCommand() {
|
|
|
209
240
|
stocked === undefined) {
|
|
210
241
|
throw new PrvrsError('INVALID_ARGUMENT', 'No update fields provided. Pass at least one of: --qty, --cost, --tax-ship, --notes, --stocked.');
|
|
211
242
|
}
|
|
212
|
-
const data = await updateInventory(supabase,
|
|
243
|
+
const data = await updateInventory(supabase, userId, itemId, {
|
|
213
244
|
qty,
|
|
214
245
|
cost,
|
|
215
246
|
taxShip,
|
|
@@ -224,13 +255,19 @@ export function buildInventoryCommand() {
|
|
|
224
255
|
.command('delete <id>')
|
|
225
256
|
.description('Delete an inventory item (must be yours)')
|
|
226
257
|
.option('-y, --yes', 'Skip confirmation prompt')
|
|
258
|
+
.addHelpText('after', `
|
|
259
|
+
Examples:
|
|
260
|
+
purvey inventory delete 7 # prompts for confirmation
|
|
261
|
+
purvey inventory delete 7 --yes # skip confirmation (use in scripts)
|
|
262
|
+
|
|
263
|
+
Notes:
|
|
264
|
+
Permanently deletes the inventory row. Cannot be undone.
|
|
265
|
+
Row-level security: only items belonging to you can be deleted.
|
|
266
|
+
Requires authentication (member role).
|
|
267
|
+
`)
|
|
227
268
|
.action(withErrorHandling(async (id, opts, cmd) => {
|
|
228
269
|
void cmd;
|
|
229
|
-
const supabase = await
|
|
230
|
-
const { data: { user }, } = await supabase.auth.getUser();
|
|
231
|
-
if (!user) {
|
|
232
|
-
throw new AuthError('Not logged in. Run `purvey auth login` first.');
|
|
233
|
-
}
|
|
270
|
+
const { supabase, userId } = await requireAuth('member');
|
|
234
271
|
const itemId = parseInt(id, 10);
|
|
235
272
|
if (isNaN(itemId)) {
|
|
236
273
|
throw new PrvrsError('INVALID_ARGUMENT', `Invalid inventory ID: "${id}".`);
|
|
@@ -242,7 +279,7 @@ export function buildInventoryCommand() {
|
|
|
242
279
|
return;
|
|
243
280
|
}
|
|
244
281
|
}
|
|
245
|
-
await deleteInventory(supabase,
|
|
282
|
+
await deleteInventory(supabase, userId, itemId);
|
|
246
283
|
success(`Inventory item ${itemId} deleted.`);
|
|
247
284
|
}));
|
|
248
285
|
return inventory;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inventory.js","sourceRoot":"","sources":["../../src/commands/inventory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AACpC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"inventory.js","sourceRoot":"","sources":["../../src/commands/inventory.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/roast.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { RoastProfile, TemperatureEntry, RoastEventEntry } from '../lib/roa
|
|
|
3
3
|
export type { RoastProfile, TemperatureEntry, RoastEventEntry };
|
|
4
4
|
/**
|
|
5
5
|
* `purvey roast` — Browse and manage your roast profiles.
|
|
6
|
-
* Requires authentication.
|
|
6
|
+
* Requires member+ authentication.
|
|
7
7
|
*/
|
|
8
8
|
export declare function buildRoastCommand(): Command;
|
|
9
9
|
//# sourceMappingURL=roast.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"roast.d.ts","sourceRoot":"","sources":["../../src/commands/roast.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAepC,OAAO,KAAK,EACV,YAAY,EACZ,gBAAgB,EAChB,eAAe,EAEhB,MAAM,iBAAiB,CAAC;AAOzB,YAAY,EAAE,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,CAAC;AAIhE;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,
|
|
1
|
+
{"version":3,"file":"roast.d.ts","sourceRoot":"","sources":["../../src/commands/roast.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAepC,OAAO,KAAK,EACV,YAAY,EACZ,gBAAgB,EAChB,eAAe,EAEhB,MAAM,iBAAiB,CAAC;AAOzB,YAAY,EAAE,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,CAAC;AAIhE;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAgqB3C"}
|