@purveyors/cli 0.3.0 → 0.4.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.
Files changed (38) hide show
  1. package/dist/commands/config.d.ts +7 -0
  2. package/dist/commands/config.d.ts.map +1 -0
  3. package/dist/commands/config.js +82 -0
  4. package/dist/commands/config.js.map +1 -0
  5. package/dist/commands/inventory.d.ts.map +1 -1
  6. package/dist/commands/inventory.js +65 -2
  7. package/dist/commands/inventory.js.map +1 -1
  8. package/dist/commands/roast.d.ts.map +1 -1
  9. package/dist/commands/roast.js +315 -3
  10. package/dist/commands/roast.js.map +1 -1
  11. package/dist/commands/sales.d.ts.map +1 -1
  12. package/dist/commands/sales.js +73 -3
  13. package/dist/commands/sales.js.map +1 -1
  14. package/dist/commands/tasting.d.ts.map +1 -1
  15. package/dist/commands/tasting.js +81 -11
  16. package/dist/commands/tasting.js.map +1 -1
  17. package/dist/index.js +8 -0
  18. package/dist/index.js.map +1 -1
  19. package/dist/lib/ai.d.ts +36 -0
  20. package/dist/lib/ai.d.ts.map +1 -0
  21. package/dist/lib/ai.js +42 -0
  22. package/dist/lib/ai.js.map +1 -0
  23. package/dist/lib/config.d.ts +26 -0
  24. package/dist/lib/config.d.ts.map +1 -1
  25. package/dist/lib/config.js +59 -0
  26. package/dist/lib/config.js.map +1 -1
  27. package/dist/lib/interactive/forms.d.ts +33 -0
  28. package/dist/lib/interactive/forms.d.ts.map +1 -0
  29. package/dist/lib/interactive/forms.js +139 -0
  30. package/dist/lib/interactive/forms.js.map +1 -0
  31. package/dist/lib/interactive/watch.d.ts +66 -0
  32. package/dist/lib/interactive/watch.d.ts.map +1 -0
  33. package/dist/lib/interactive/watch.js +494 -0
  34. package/dist/lib/interactive/watch.js.map +1 -0
  35. package/dist/lib/supabase.d.ts.map +1 -1
  36. package/dist/lib/supabase.js +16 -1
  37. package/dist/lib/supabase.js.map +1 -1
  38. package/package.json +4 -2
@@ -0,0 +1,494 @@
1
+ /**
2
+ * Watch module for `purvey roast watch`.
3
+ * CLI-only — not exported via package.json subpaths.
4
+ *
5
+ * Monitors a directory for new .alog files, imports them automatically,
6
+ * and shows a verification table when the session ends (Ctrl+C).
7
+ */
8
+ import { watch } from 'fs';
9
+ import { readFile, access, writeFile, mkdir } from 'fs/promises';
10
+ import { join, extname } from 'path';
11
+ import { constants } from 'fs';
12
+ import { importRoastFromFile } from '../roast.js';
13
+ import { CONFIG_DIR } from '../config.js';
14
+ // ─── Session persistence ──────────────────────────────────────────────────────
15
+ const SESSION_FILE = join(CONFIG_DIR, 'watch-session.json');
16
+ /** Persist session state to disk after each import. */
17
+ export async function saveWatchSession(session) {
18
+ await mkdir(CONFIG_DIR, { recursive: true, mode: 0o700 });
19
+ await writeFile(SESSION_FILE, JSON.stringify(session, null, 2) + '\n', { mode: 0o600 });
20
+ }
21
+ /** Load a previously saved watch session. Returns null if none exists. */
22
+ export async function loadWatchSession() {
23
+ try {
24
+ await access(SESSION_FILE, constants.R_OK);
25
+ const raw = await readFile(SESSION_FILE, 'utf-8');
26
+ return JSON.parse(raw);
27
+ }
28
+ catch {
29
+ return null;
30
+ }
31
+ }
32
+ // ─── Batch name generation ────────────────────────────────────────────────────
33
+ /**
34
+ * Generate a sequential batch name: "{prefix} #{n}".
35
+ * sequence is 1-based (first import = 1).
36
+ */
37
+ export function generateBatchName(prefix, sequence) {
38
+ return `${prefix} #${sequence}`;
39
+ }
40
+ // ─── File extension filter ────────────────────────────────────────────────────
41
+ /** Returns true if filename has a .alog extension (case-insensitive). */
42
+ export function isAlogFile(filename) {
43
+ return extname(filename).toLowerCase() === '.alog';
44
+ }
45
+ // ─── Verification table ───────────────────────────────────────────────────────
46
+ /** Render a padded verification table and print to stderr. */
47
+ export function printVerificationTable(session, autoMatch) {
48
+ const imports = session.imports;
49
+ const showAiColumns = autoMatch === true || imports.some((r) => r.aiMatch !== undefined);
50
+ if (showAiColumns) {
51
+ printVerificationTableAutoMatch(imports);
52
+ }
53
+ else {
54
+ printVerificationTableStandard(imports);
55
+ }
56
+ }
57
+ function printVerificationTableStandard(imports) {
58
+ // Column widths
59
+ const COL_FILE = 31;
60
+ const COL_ID = 10;
61
+ const COL_BATCH = 26;
62
+ const COL_STATUS = 9;
63
+ function row(file, id, batch, status) {
64
+ return ('│ ' +
65
+ file.padEnd(COL_FILE) +
66
+ '│ ' +
67
+ id.padEnd(COL_ID) +
68
+ '│ ' +
69
+ batch.padEnd(COL_BATCH) +
70
+ '│ ' +
71
+ status.padEnd(COL_STATUS) +
72
+ '│');
73
+ }
74
+ function hline(left, mid, right, fill) {
75
+ return (left +
76
+ fill.repeat(COL_FILE + 2) +
77
+ mid +
78
+ fill.repeat(COL_ID + 2) +
79
+ mid +
80
+ fill.repeat(COL_BATCH + 2) +
81
+ mid +
82
+ fill.repeat(COL_STATUS + 2) +
83
+ right);
84
+ }
85
+ const lines = [];
86
+ lines.push('');
87
+ lines.push(hline('┌', '┬', '┐', '─'));
88
+ lines.push(row('File', 'Roast ID', 'Batch', 'Status'));
89
+ lines.push(hline('├', '┼', '┤', '─'));
90
+ if (imports.length === 0) {
91
+ lines.push(row('(no files imported)', '', '', ''));
92
+ }
93
+ else {
94
+ for (const rec of imports) {
95
+ const file = rec.fileName.length > COL_FILE ? rec.fileName.slice(0, COL_FILE - 1) + '…' : rec.fileName;
96
+ const id = rec.status === 'success' ? `#${rec.roastId}` : '—';
97
+ const batch = rec.batchName.length > COL_BATCH
98
+ ? rec.batchName.slice(0, COL_BATCH - 1) + '…'
99
+ : rec.batchName;
100
+ const status = rec.status === 'success' ? '✓' : `✗ ${rec.error?.slice(0, 5) ?? 'Error'}`;
101
+ lines.push(row(file, id, batch, status));
102
+ }
103
+ }
104
+ lines.push(hline('└', '┴', '┘', '─'));
105
+ const succeeded = imports.filter((r) => r.status === 'success').length;
106
+ const failed = imports.filter((r) => r.status === 'failed').length;
107
+ lines.push('');
108
+ lines.push(`Session: ${imports.length} file${imports.length !== 1 ? 's' : ''} processed, ${succeeded} succeeded, ${failed} failed`);
109
+ lines.push('');
110
+ process.stderr.write(lines.join('\n') + '\n');
111
+ }
112
+ function printVerificationTableAutoMatch(imports) {
113
+ // Column widths for auto-match table
114
+ const COL_FILE = 29;
115
+ const COL_ID = 9;
116
+ const COL_BEAN = 22;
117
+ const COL_CONF = 10;
118
+ const COL_STATUS = 7;
119
+ function row(file, id, bean, conf, status) {
120
+ return ('│ ' +
121
+ file.padEnd(COL_FILE) +
122
+ '│ ' +
123
+ id.padEnd(COL_ID) +
124
+ '│ ' +
125
+ bean.padEnd(COL_BEAN) +
126
+ '│ ' +
127
+ conf.padEnd(COL_CONF) +
128
+ '│ ' +
129
+ status.padEnd(COL_STATUS) +
130
+ '│');
131
+ }
132
+ function hline(left, mid, right, fill) {
133
+ return (left +
134
+ fill.repeat(COL_FILE + 2) +
135
+ mid +
136
+ fill.repeat(COL_ID + 2) +
137
+ mid +
138
+ fill.repeat(COL_BEAN + 2) +
139
+ mid +
140
+ fill.repeat(COL_CONF + 2) +
141
+ mid +
142
+ fill.repeat(COL_STATUS + 2) +
143
+ right);
144
+ }
145
+ const lines = [];
146
+ lines.push('');
147
+ lines.push(hline('┌', '┬', '┐', '─'));
148
+ lines.push(row('File', 'Roast ID', 'Matched Bean', 'Confidence', 'Status'));
149
+ lines.push(hline('├', '┼', '┤', '─'));
150
+ if (imports.length === 0) {
151
+ lines.push(row('(no files imported)', '', '', '', ''));
152
+ }
153
+ else {
154
+ for (const rec of imports) {
155
+ const file = rec.fileName.length > COL_FILE ? rec.fileName.slice(0, COL_FILE - 1) + '…' : rec.fileName;
156
+ const id = rec.status === 'success' && rec.roastId !== null ? `#${rec.roastId}` : '—';
157
+ const beanName = rec.aiMatch?.coffeeName ?? (rec.status === 'needs-review' ? '(needs review)' : '—');
158
+ const bean = beanName.length > COL_BEAN ? beanName.slice(0, COL_BEAN - 1) + '…' : beanName;
159
+ const confVal = rec.aiMatch !== undefined ? `${rec.aiMatch.confidence}%` : '';
160
+ const conf = confVal.padEnd(COL_CONF);
161
+ const status = rec.status === 'success'
162
+ ? '✓'
163
+ : rec.status === 'needs-review'
164
+ ? '⚠'
165
+ : `✗ ${rec.error?.slice(0, 4) ?? 'Err'}`;
166
+ lines.push(row(file, id, bean, conf, status));
167
+ }
168
+ }
169
+ lines.push(hline('└', '┴', '┘', '─'));
170
+ const succeeded = imports.filter((r) => r.status === 'success').length;
171
+ const failed = imports.filter((r) => r.status === 'failed').length;
172
+ const needsReview = imports.filter((r) => r.status === 'needs-review').length;
173
+ lines.push('');
174
+ let summary = `Session: ${imports.length} file${imports.length !== 1 ? 's' : ''} processed, ${succeeded} succeeded, ${failed} failed`;
175
+ if (needsReview > 0) {
176
+ summary += `, ${needsReview} need${needsReview !== 1 ? '' : 's'} review`;
177
+ }
178
+ lines.push(summary);
179
+ lines.push('');
180
+ process.stderr.write(lines.join('\n') + '\n');
181
+ }
182
+ // ─── Main watch function ──────────────────────────────────────────────────────
183
+ /**
184
+ * Start watching a directory for new .alog files.
185
+ * Blocks until SIGINT (Ctrl+C), then prints a summary table and resolves.
186
+ *
187
+ * @param supabase Authenticated Supabase client
188
+ * @param userId Authenticated user ID
189
+ * @param directory Absolute or relative path to watch
190
+ * @param opts Watch options
191
+ * @returns The final WatchSession (all imports recorded)
192
+ */
193
+ export async function startWatch(supabase, userId, directory, opts) {
194
+ // 1. Validate directory exists
195
+ try {
196
+ await access(directory, constants.R_OK);
197
+ }
198
+ catch {
199
+ throw new Error(`Directory not found or not readable: "${directory}"`);
200
+ }
201
+ // 2. Snapshot existing .alog files so we only react to NEW ones
202
+ const { readdir } = await import('fs/promises');
203
+ const existingFiles = new Set();
204
+ try {
205
+ const entries = await readdir(directory);
206
+ for (const entry of entries) {
207
+ if (isAlogFile(entry)) {
208
+ existingFiles.add(entry);
209
+ }
210
+ }
211
+ }
212
+ catch {
213
+ // Non-fatal — if readdir fails we just won't filter pre-existing files
214
+ }
215
+ // 3. Create session state
216
+ const session = {
217
+ directory,
218
+ coffeeId: opts.coffeeId,
219
+ coffeeName: opts.coffeeName,
220
+ batchPrefix: opts.batchPrefix,
221
+ startedAt: new Date().toISOString(),
222
+ imports: [],
223
+ };
224
+ const startSequence = opts.startSequence ?? 0;
225
+ // 4. Debounce map: filename → timeout handle
226
+ const debounceTimers = new Map();
227
+ // Track in-progress files to avoid double-processing
228
+ const processing = new Set();
229
+ // processFile: read, import, record result
230
+ async function processFile(filename) {
231
+ if (processing.has(filename))
232
+ return;
233
+ processing.add(filename);
234
+ const filePath = join(directory, filename);
235
+ const sequence = startSequence + session.imports.length + 1;
236
+ const batchName = generateBatchName(opts.batchPrefix, sequence);
237
+ // If promptEach: let user override the bean selection
238
+ let effectiveCoffeeId = opts.coffeeId;
239
+ let effectiveCoffeeName = opts.coffeeName;
240
+ if (opts.promptEach) {
241
+ const { pickBean, guardCancel } = await import('./forms.js');
242
+ process.stderr.write(`\nNew file detected: ${filename}\n`);
243
+ const bean = await pickBean(supabase, userId);
244
+ guardCancel(bean);
245
+ effectiveCoffeeId = bean.id;
246
+ effectiveCoffeeName = bean.name;
247
+ }
248
+ let fileContent;
249
+ try {
250
+ await access(filePath, constants.R_OK);
251
+ fileContent = await readFile(filePath, 'utf-8');
252
+ }
253
+ catch (err) {
254
+ const record = {
255
+ fileName: filename,
256
+ roastId: null,
257
+ batchName,
258
+ status: 'failed',
259
+ error: err instanceof Error ? err.message : 'Unreadable',
260
+ importedAt: new Date().toISOString(),
261
+ };
262
+ session.imports.push(record);
263
+ await saveWatchSession(session);
264
+ process.stderr.write(`✗ Failed to read ${filename}: ${record.error}\n`);
265
+ processing.delete(filename);
266
+ return;
267
+ }
268
+ // Auto-match mode: use AI to classify the bean
269
+ let aiResult;
270
+ if (opts.autoMatch && !opts.promptEach) {
271
+ aiResult = await runAutoMatch(supabase, userId, filename, fileContent);
272
+ if (aiResult.skip) {
273
+ // AI returned low confidence or failed — mark as needs-review
274
+ const record = {
275
+ fileName: filename,
276
+ roastId: null,
277
+ batchName,
278
+ status: 'needs-review',
279
+ error: aiResult.reason,
280
+ importedAt: new Date().toISOString(),
281
+ ...(aiResult.aiMatch !== undefined ? { aiMatch: aiResult.aiMatch } : {}),
282
+ };
283
+ session.imports.push(record);
284
+ await saveWatchSession(session);
285
+ const confStr = aiResult.aiMatch !== undefined ? ` (confidence: ${aiResult.aiMatch.confidence}%)` : '';
286
+ process.stderr.write(`⚠ Needs review: ${filename}${confStr} — ${aiResult.reason}\n`);
287
+ processing.delete(filename);
288
+ return;
289
+ }
290
+ effectiveCoffeeId = aiResult.coffeeId;
291
+ effectiveCoffeeName = aiResult.coffeeName;
292
+ process.stderr.write(`🤖 AI matched: ${filename} → ${effectiveCoffeeName} (${aiResult.aiMatch.confidence}% confidence)\n` +
293
+ ` Reasoning: ${aiResult.aiMatch.reasoning}\n`);
294
+ }
295
+ try {
296
+ const result = await importRoastFromFile(supabase, userId, {
297
+ fileContent,
298
+ fileName: filename,
299
+ coffeeId: effectiveCoffeeId,
300
+ batchName,
301
+ });
302
+ const milestoneCount = Object.values(result.milestones).filter((v) => v !== undefined && v > 0).length;
303
+ // Carry aiMatch from the local aiResult (threaded as a local variable, not module state)
304
+ const aiMatchField = opts.autoMatch && !opts.promptEach && aiResult?.aiMatch ? aiResult.aiMatch : undefined;
305
+ const record = {
306
+ fileName: filename,
307
+ roastId: result.roast_id,
308
+ batchName,
309
+ status: 'success',
310
+ milestones: result.milestones,
311
+ phases: result.phases,
312
+ importedAt: new Date().toISOString(),
313
+ ...(aiMatchField !== undefined ? { aiMatch: aiMatchField } : {}),
314
+ };
315
+ session.imports.push(record);
316
+ await saveWatchSession(session);
317
+ const tempCount = result.message.match(/(\d+) data points/)?.[1] ?? '?';
318
+ process.stderr.write(`✓ Imported: ${filename} → Roast #${result.roast_id} (${tempCount} temps, ${milestoneCount} milestones)` +
319
+ (effectiveCoffeeName !== opts.coffeeName ? ` [${effectiveCoffeeName}]` : '') +
320
+ '\n');
321
+ }
322
+ catch (err) {
323
+ const errMsg = err instanceof Error ? err.message : String(err);
324
+ const record = {
325
+ fileName: filename,
326
+ roastId: null,
327
+ batchName,
328
+ status: 'failed',
329
+ error: errMsg,
330
+ importedAt: new Date().toISOString(),
331
+ };
332
+ session.imports.push(record);
333
+ await saveWatchSession(session);
334
+ process.stderr.write(`✗ Failed to import ${filename}: ${errMsg}\n`);
335
+ }
336
+ finally {
337
+ processing.delete(filename);
338
+ }
339
+ }
340
+ // debounced handler
341
+ function onFileEvent(filename) {
342
+ if (!isAlogFile(filename))
343
+ return;
344
+ // Skip files that were present when we started
345
+ if (existingFiles.has(filename))
346
+ return;
347
+ if (debounceTimers.has(filename)) {
348
+ clearTimeout(debounceTimers.get(filename));
349
+ }
350
+ debounceTimers.set(filename, setTimeout(() => {
351
+ debounceTimers.delete(filename);
352
+ processFile(filename).catch((err) => {
353
+ process.stderr.write(`✗ Unexpected error processing ${filename}: ${err instanceof Error ? err.message : String(err)}\n`);
354
+ });
355
+ }, 2000));
356
+ }
357
+ // 5. Start fs.watch
358
+ let watcher;
359
+ try {
360
+ watcher = watch(directory, { persistent: true }, (_eventType, filename) => {
361
+ if (filename)
362
+ onFileEvent(filename);
363
+ });
364
+ }
365
+ catch (err) {
366
+ throw new Error(`Failed to watch directory "${directory}": ${err instanceof Error ? err.message : String(err)}`);
367
+ }
368
+ const modeLabel = opts.autoMatch
369
+ ? 'auto-match mode'
370
+ : opts.promptEach
371
+ ? 'prompt-each mode'
372
+ : `coffee: ${opts.coffeeName}`;
373
+ process.stderr.write(`👁 Watching ${directory} for new .alog files (${modeLabel}, prefix: "${opts.batchPrefix}")...\n`);
374
+ process.stderr.write(` Press Ctrl+C to stop and view summary.\n\n`);
375
+ // 6. Block until SIGINT, then cleanup and return
376
+ await new Promise((resolve) => {
377
+ process.once('SIGINT', () => {
378
+ // Cancel all pending debounce timers
379
+ for (const timer of debounceTimers.values()) {
380
+ clearTimeout(timer);
381
+ }
382
+ debounceTimers.clear();
383
+ watcher.close();
384
+ process.stderr.write('\n');
385
+ printVerificationTable(session, opts.autoMatch);
386
+ // Prompt about unmatched files if in auto-match mode
387
+ const needsReview = session.imports.filter((r) => r.status === 'needs-review');
388
+ if (opts.autoMatch && needsReview.length > 0) {
389
+ process.stderr.write(`⚠ ${needsReview.length} file${needsReview.length !== 1 ? 's need' : ' needs'} manual bean assignment:\n`);
390
+ for (const rec of needsReview) {
391
+ process.stderr.write(` - ${rec.fileName}\n`);
392
+ }
393
+ process.stderr.write(` Use \`purvey roast import <file> --coffee-id <id>\` to import them manually.\n\n`);
394
+ }
395
+ resolve();
396
+ });
397
+ });
398
+ return session;
399
+ }
400
+ /**
401
+ * Run AI classification for a newly detected .alog file.
402
+ * Returns skip=true if confidence < 50 or if the AI call fails.
403
+ */
404
+ async function runAutoMatch(supabase, userId, filename, fileContent) {
405
+ // Parse alog metadata without full import
406
+ let alogMetadata;
407
+ try {
408
+ const { processAlogFile } = await import('../artisan/parser.js');
409
+ const parsed = processAlogFile(fileContent);
410
+ alogMetadata = {
411
+ title: typeof parsed.title === 'string' ? parsed.title : filename,
412
+ roastertype: typeof parsed.roastertype === 'string' ? parsed.roastertype : undefined,
413
+ beans: typeof parsed.beans === 'string' ? parsed.beans : undefined,
414
+ roastingnotes: typeof parsed.roastingnotes === 'string' ? parsed.roastingnotes : undefined,
415
+ weight: Array.isArray(parsed.weight)
416
+ ? parsed.weight
417
+ : undefined,
418
+ };
419
+ }
420
+ catch {
421
+ // If we can't parse the file, fall back to filename as title
422
+ alogMetadata = { title: filename };
423
+ }
424
+ // Fetch the user's stocked inventory
425
+ let inventory = [];
426
+ try {
427
+ const { data, error } = await supabase
428
+ .from('green_coffee_inv')
429
+ .select('id, coffee_catalog!catalog_id (name, country, processing)')
430
+ .eq('user', userId)
431
+ .eq('stocked', true)
432
+ .limit(100);
433
+ if (error)
434
+ throw error;
435
+ const rows = (data ?? []);
436
+ inventory = rows.map((row) => {
437
+ const catalog = Array.isArray(row.coffee_catalog)
438
+ ? (row.coffee_catalog[0] ?? null)
439
+ : row.coffee_catalog;
440
+ return {
441
+ id: row.id,
442
+ coffee_name: catalog?.name ?? `Bean #${row.id}`,
443
+ origin: catalog?.country ?? undefined,
444
+ processing: catalog?.processing ?? undefined,
445
+ };
446
+ });
447
+ }
448
+ catch (err) {
449
+ const reason = `Failed to fetch inventory: ${err instanceof Error ? err.message : String(err)}`;
450
+ process.stderr.write(`⚠ Auto-match skipped for ${filename}: ${reason}\n`);
451
+ return { skip: true, reason };
452
+ }
453
+ if (inventory.length === 0) {
454
+ return { skip: true, reason: 'No stocked inventory items found' };
455
+ }
456
+ // Call the AI classifier
457
+ try {
458
+ const { classifyRoast } = await import('../ai.js');
459
+ const result = await classifyRoast(supabase, { alogMetadata, inventory });
460
+ if (!result.match) {
461
+ return { skip: true, reason: 'AI returned no match' };
462
+ }
463
+ const { inventoryId, coffeeName, confidence, reasoning } = result.match;
464
+ const aiMatch = { coffeeName, confidence, reasoning };
465
+ if (confidence < 50) {
466
+ return {
467
+ skip: true,
468
+ reason: `Low AI confidence (${confidence}%)`,
469
+ aiMatch,
470
+ };
471
+ }
472
+ // Verify the matched inventoryId is actually in our fetched inventory
473
+ const matchedItem = inventory.find((item) => item.id === inventoryId);
474
+ if (!matchedItem) {
475
+ return {
476
+ skip: true,
477
+ reason: `AI matched unknown inventory ID ${inventoryId}`,
478
+ aiMatch,
479
+ };
480
+ }
481
+ return {
482
+ skip: false,
483
+ coffeeId: inventoryId,
484
+ coffeeName,
485
+ aiMatch,
486
+ };
487
+ }
488
+ catch (err) {
489
+ const reason = `AI classification error: ${err instanceof Error ? err.message : String(err)}`;
490
+ process.stderr.write(`⚠ Auto-match failed for ${filename}: ${reason}\n`);
491
+ return { skip: true, reason };
492
+ }
493
+ }
494
+ //# sourceMappingURL=watch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watch.js","sourceRoot":"","sources":["../../../src/lib/interactive/watch.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"supabase.d.ts","sourceRoot":"","sources":["../../src/lib/supabase.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAe1E;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,cAAc,CAOjD;AAED;;;GAGG;AACH,wBAAsB,yBAAyB,IAAI,OAAO,CAAC,cAAc,CAAC,CAoCzE;AAED;;;GAGG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC;IAC/C,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,IAAI,CAAC,CA2BR"}
1
+ {"version":3,"file":"supabase.d.ts","sourceRoot":"","sources":["../../src/lib/supabase.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAe1E;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,cAAc,CAOjD;AAED;;;GAGG;AACH,wBAAsB,yBAAyB,IAAI,OAAO,CAAC,cAAc,CAAC,CAoCzE;AAED;;;GAGG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC;IAC/C,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,IAAI,CAAC,CA0CR"}
@@ -73,10 +73,25 @@ export async function validateSession() {
73
73
  const { data: { user }, error, } = await client.auth.getUser();
74
74
  if (error || !user)
75
75
  return null;
76
+ // Fetch app-level role from user_roles table
77
+ let appRoles = [];
78
+ try {
79
+ const { data: roleData } = await client
80
+ .from('user_roles')
81
+ .select('user_role')
82
+ .eq('id', user.id)
83
+ .single();
84
+ if (roleData?.user_role && Array.isArray(roleData.user_role)) {
85
+ appRoles = roleData.user_role;
86
+ }
87
+ }
88
+ catch {
89
+ // user_roles query failed — fall back to auth role
90
+ }
76
91
  return {
77
92
  id: user.id,
78
93
  email: user.email,
79
- role: user.role,
94
+ role: appRoles.length > 0 ? appRoles.join(', ') : (user.role ?? 'authenticated'),
80
95
  expiresAt: creds.expiresAt,
81
96
  };
82
97
  }
@@ -1 +1 @@
1
- {"version":3,"file":"supabase.js","sourceRoot":"","sources":["../../src/lib/supabase.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"supabase.js","sourceRoot":"","sources":["../../src/lib/supabase.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@purveyors/cli",
3
- "version": "0.3.0",
3
+ "version": "0.4.1",
4
4
  "description": "The official CLI for purveyors.io — coffee intelligence from your terminal",
5
5
  "type": "module",
6
6
  "bin": {
@@ -14,7 +14,8 @@
14
14
  "./sales": "./dist/lib/sales.js",
15
15
  "./tasting": "./dist/lib/tasting.js",
16
16
  "./lib": "./dist/lib/index.js",
17
- "./artisan": "./dist/lib/artisan/index.js"
17
+ "./artisan": "./dist/lib/artisan/index.js",
18
+ "./ai": "./dist/lib/ai.js"
18
19
  },
19
20
  "files": [
20
21
  "dist",
@@ -49,6 +50,7 @@
49
50
  "node": ">=20"
50
51
  },
51
52
  "dependencies": {
53
+ "@clack/prompts": "^1.1.0",
52
54
  "@supabase/supabase-js": "^2.49.1",
53
55
  "chalk": "^5.4.1",
54
56
  "commander": "^13.1.0",