@purveyors/cli 0.3.0 → 0.4.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.
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Interactive form helpers for `purvey` write commands.
3
+ * CLI-only — not exported via package.json subpaths.
4
+ * All functions use @clack/prompts for step-by-step TUI wizards.
5
+ */
6
+ import type { SupabaseClient } from '@supabase/supabase-js';
7
+ /** Call after any clack result to abort cleanly on Ctrl+C / Escape. */
8
+ export declare function guardCancel(result: unknown): void;
9
+ /**
10
+ * Interactive bean picker — shows user's inventory beans and lets them select one.
11
+ * Returns the selected bean's ID and name.
12
+ */
13
+ export declare function pickBean(supabase: SupabaseClient, userId: string): Promise<{
14
+ id: number;
15
+ name: string;
16
+ }>;
17
+ /**
18
+ * Interactive roast picker — shows user's roast profiles, lets them select one.
19
+ * Returns the selected roast's ID and batch name.
20
+ */
21
+ export declare function pickRoast(supabase: SupabaseClient, userId: string): Promise<{
22
+ id: number;
23
+ batchName: string;
24
+ }>;
25
+ /**
26
+ * Interactive catalog search — user types search term, sees matching coffees.
27
+ * Returns selected catalog item ID and name.
28
+ */
29
+ export declare function pickCatalogItem(supabase: SupabaseClient): Promise<{
30
+ id: number;
31
+ name: string;
32
+ }>;
33
+ //# sourceMappingURL=forms.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"forms.d.ts","sourceRoot":"","sources":["../../../src/lib/interactive/forms.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAI5D,uEAAuE;AACvE,wBAAgB,WAAW,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAKjD;AAID;;;GAGG;AACH,wBAAsB,QAAQ,CAC5B,QAAQ,EAAE,cAAc,EACxB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CA4CvC;AAED;;;GAGG;AACH,wBAAsB,SAAS,CAC7B,QAAQ,EAAE,cAAc,EACxB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,CAuC5C;AAED;;;GAGG;AACH,wBAAsB,eAAe,CACnC,QAAQ,EAAE,cAAc,GACvB,OAAO,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAiEvC"}
@@ -0,0 +1,139 @@
1
+ /**
2
+ * Interactive form helpers for `purvey` write commands.
3
+ * CLI-only — not exported via package.json subpaths.
4
+ * All functions use @clack/prompts for step-by-step TUI wizards.
5
+ */
6
+ import * as p from '@clack/prompts';
7
+ // ─── Cancel guard ─────────────────────────────────────────────────────────────
8
+ /** Call after any clack result to abort cleanly on Ctrl+C / Escape. */
9
+ export function guardCancel(result) {
10
+ if (p.isCancel(result)) {
11
+ p.cancel('Cancelled.');
12
+ process.exit(0);
13
+ }
14
+ }
15
+ // ─── Pickers ──────────────────────────────────────────────────────────────────
16
+ /**
17
+ * Interactive bean picker — shows user's inventory beans and lets them select one.
18
+ * Returns the selected bean's ID and name.
19
+ */
20
+ export async function pickBean(supabase, userId) {
21
+ const { data, error } = await supabase
22
+ .from('green_coffee_inv')
23
+ .select('id, coffee_catalog!catalog_id (name)')
24
+ .eq('user', userId)
25
+ .eq('stocked', true)
26
+ .order('id', { ascending: false })
27
+ .limit(50);
28
+ if (error)
29
+ throw error;
30
+ const rows = (data ?? []);
31
+ if (rows.length === 0) {
32
+ p.cancel('No stocked beans found in your inventory. Add some first.');
33
+ process.exit(0);
34
+ }
35
+ const options = rows.map((row) => {
36
+ const catalog = Array.isArray(row.coffee_catalog)
37
+ ? (row.coffee_catalog[0] ?? null)
38
+ : row.coffee_catalog;
39
+ const name = catalog?.name ?? `Bean #${row.id}`;
40
+ return { value: String(row.id), label: `${name} (#${row.id})`, hint: name };
41
+ });
42
+ const selected = await p.select({
43
+ message: 'Select a bean from your inventory',
44
+ options,
45
+ });
46
+ guardCancel(selected);
47
+ const selectedId = parseInt(selected, 10);
48
+ const matchedRow = rows.find((r) => r.id === selectedId);
49
+ const catalog = Array.isArray(matchedRow?.coffee_catalog)
50
+ ? (matchedRow?.coffee_catalog[0] ?? null)
51
+ : (matchedRow?.coffee_catalog ?? null);
52
+ const name = catalog?.name ?? `Bean #${selectedId}`;
53
+ return { id: selectedId, name };
54
+ }
55
+ /**
56
+ * Interactive roast picker — shows user's roast profiles, lets them select one.
57
+ * Returns the selected roast's ID and batch name.
58
+ */
59
+ export async function pickRoast(supabase, userId) {
60
+ const { data, error } = await supabase
61
+ .from('roast_profiles')
62
+ .select('roast_id, batch_name, roast_date')
63
+ .eq('user', userId)
64
+ .order('roast_date', { ascending: false })
65
+ .limit(50);
66
+ if (error)
67
+ throw error;
68
+ const rows = (data ?? []);
69
+ if (rows.length === 0) {
70
+ p.cancel('No roast profiles found. Create one first.');
71
+ process.exit(0);
72
+ }
73
+ const options = rows.map((row) => {
74
+ const label = row.batch_name ?? `Roast #${row.roast_id}`;
75
+ const hint = row.roast_date ?? undefined;
76
+ return { value: String(row.roast_id), label, hint };
77
+ });
78
+ const selected = await p.select({
79
+ message: 'Select a roast profile',
80
+ options,
81
+ });
82
+ guardCancel(selected);
83
+ const selectedId = parseInt(selected, 10);
84
+ const matchedRow = rows.find((r) => r.roast_id === selectedId);
85
+ const batchName = matchedRow?.batch_name ?? `Roast #${selectedId}`;
86
+ return { id: selectedId, batchName };
87
+ }
88
+ /**
89
+ * Interactive catalog search — user types search term, sees matching coffees.
90
+ * Returns selected catalog item ID and name.
91
+ */
92
+ export async function pickCatalogItem(supabase) {
93
+ const searchTerm = await p.text({
94
+ message: 'Search coffee catalog (origin, name, or flavor)',
95
+ placeholder: 'e.g. Ethiopia, natural, berry',
96
+ validate: (v) => {
97
+ if (!v || v.trim().length === 0)
98
+ return 'Please enter a search term.';
99
+ },
100
+ });
101
+ guardCancel(searchTerm);
102
+ const term = searchTerm.trim();
103
+ const safe = term.replace(/[(),.*%]/g, '');
104
+ const { data, error } = await supabase
105
+ .from('coffee_catalog')
106
+ .select('id, name, country, processing, cost_lb')
107
+ .or([
108
+ `name.ilike.%${safe}%`,
109
+ `country.ilike.%${safe}%`,
110
+ `continent.ilike.%${safe}%`,
111
+ `region.ilike.%${safe}%`,
112
+ `cupping_notes.ilike.%${safe}%`,
113
+ `description_short.ilike.%${safe}%`,
114
+ ].join(','))
115
+ .limit(20);
116
+ if (error)
117
+ throw error;
118
+ const rows = (data ?? []);
119
+ if (rows.length === 0) {
120
+ p.cancel(`No coffees found matching "${term}". Try a different search.`);
121
+ process.exit(0);
122
+ }
123
+ const options = rows.map((row) => {
124
+ const label = row.name ?? `Catalog #${row.id}`;
125
+ const parts = [row.country, row.processing, row.cost_lb ? `$${row.cost_lb}/lb` : null].filter(Boolean);
126
+ const hint = parts.join(' · ') || undefined;
127
+ return { value: String(row.id), label, hint };
128
+ });
129
+ const selected = await p.select({
130
+ message: 'Select a coffee',
131
+ options,
132
+ });
133
+ guardCancel(selected);
134
+ const selectedId = parseInt(selected, 10);
135
+ const matchedRow = rows.find((r) => r.id === selectedId);
136
+ const name = matchedRow?.name ?? `Catalog #${selectedId}`;
137
+ return { id: selectedId, name };
138
+ }
139
+ //# sourceMappingURL=forms.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"forms.js","sourceRoot":"","sources":["../../../src/lib/interactive/forms.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,66 @@
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 type { SupabaseClient } from '@supabase/supabase-js';
9
+ import type { MilestoneData, ProcessedRoastData } from '../artisan/types.js';
10
+ export interface WatchSession {
11
+ directory: string;
12
+ coffeeId: number;
13
+ coffeeName: string;
14
+ batchPrefix: string;
15
+ startedAt: string;
16
+ imports: ImportRecord[];
17
+ }
18
+ export interface ImportRecord {
19
+ fileName: string;
20
+ roastId: number | null;
21
+ batchName: string;
22
+ status: 'success' | 'failed' | 'needs-review';
23
+ error?: string;
24
+ milestones?: MilestoneData;
25
+ phases?: ProcessedRoastData['phases'];
26
+ importedAt: string;
27
+ aiMatch?: {
28
+ coffeeName: string;
29
+ confidence: number;
30
+ reasoning: string;
31
+ };
32
+ }
33
+ interface StartWatchOpts {
34
+ coffeeId: number;
35
+ coffeeName: string;
36
+ batchPrefix: string;
37
+ promptEach?: boolean;
38
+ startSequence?: number;
39
+ autoMatch?: boolean;
40
+ }
41
+ /** Persist session state to disk after each import. */
42
+ export declare function saveWatchSession(session: WatchSession): Promise<void>;
43
+ /** Load a previously saved watch session. Returns null if none exists. */
44
+ export declare function loadWatchSession(): Promise<WatchSession | null>;
45
+ /**
46
+ * Generate a sequential batch name: "{prefix} #{n}".
47
+ * sequence is 1-based (first import = 1).
48
+ */
49
+ export declare function generateBatchName(prefix: string, sequence: number): string;
50
+ /** Returns true if filename has a .alog extension (case-insensitive). */
51
+ export declare function isAlogFile(filename: string): boolean;
52
+ /** Render a padded verification table and print to stderr. */
53
+ export declare function printVerificationTable(session: WatchSession, autoMatch?: boolean): void;
54
+ /**
55
+ * Start watching a directory for new .alog files.
56
+ * Blocks until SIGINT (Ctrl+C), then prints a summary table and resolves.
57
+ *
58
+ * @param supabase Authenticated Supabase client
59
+ * @param userId Authenticated user ID
60
+ * @param directory Absolute or relative path to watch
61
+ * @param opts Watch options
62
+ * @returns The final WatchSession (all imports recorded)
63
+ */
64
+ export declare function startWatch(supabase: SupabaseClient, userId: string, directory: string, opts: StartWatchOpts): Promise<WatchSession>;
65
+ export {};
66
+ //# sourceMappingURL=watch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../../../src/lib/interactive/watch.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,OAAO,KAAK,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAK7E,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,YAAY,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,SAAS,GAAG,QAAQ,GAAG,cAAc,CAAC;IAC9C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,aAAa,CAAC;IAC3B,MAAM,CAAC,EAAE,kBAAkB,CAAC,QAAQ,CAAC,CAAC;IACtC,UAAU,EAAE,MAAM,CAAC;IAEnB,OAAO,CAAC,EAAE;QACR,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED,UAAU,cAAc;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAMD,uDAAuD;AACvD,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAG3E;AAED,0EAA0E;AAC1E,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAQrE;AAID;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE1E;AAID,yEAAyE;AACzE,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEpD;AAID,8DAA8D;AAC9D,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,YAAY,EAAE,SAAS,CAAC,EAAE,OAAO,GAAG,IAAI,CASvF;AA8JD;;;;;;;;;GASG;AACH,wBAAsB,UAAU,CAC9B,QAAQ,EAAE,cAAc,EACxB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,YAAY,CAAC,CAiPvB"}