@purveyors/cli 0.32.0 → 0.32.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.
@@ -1 +1 @@
1
- {"version":3,"file":"ai.d.ts","sourceRoot":"","sources":["../../src/lib/ai.ts"],"names":[],"mappings":"AAAA,mEAAmE;AAEnE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAK1D,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE;QACZ,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;KACnC,CAAC;IACF,SAAS,EAAE,KAAK,CAAC;QACf,EAAE,EAAE,MAAM,CAAC;QACX,WAAW,EAAE,MAAM,CAAC;QACpB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE;QACL,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,EAAE,MAAM,CAAC;KACnB,GAAG,IAAI,CAAC;CACV;AAED,qFAAqF;AACrF,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE;QACJ,UAAU,IAAI,OAAO,CAAC;YACpB,IAAI,EAAE;gBAAE,OAAO,EAAE;oBAAE,YAAY,EAAE,MAAM,CAAA;iBAAE,GAAG,IAAI,CAAA;aAAE,CAAC;SACpD,CAAC,CAAC;KACJ,CAAC;CACH;AAoBD;;;;;GAKG;AACH,wBAAsB,aAAa,CACjC,iBAAiB,EAAE,iBAAiB,GAAG,wBAAwB,EAC/D,KAAK,EAAE,kBAAkB,GACxB,OAAO,CAAC,mBAAmB,CAAC,CAc9B"}
1
+ {"version":3,"file":"ai.d.ts","sourceRoot":"","sources":["../../src/lib/ai.ts"],"names":[],"mappings":"AAAA,mEAAmE;AAEnE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAK1D,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE;QACZ,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;KACnC,CAAC;IACF,SAAS,EAAE,KAAK,CAAC;QACf,EAAE,EAAE,MAAM,CAAC;QACX,WAAW,EAAE,MAAM,CAAC;QACpB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE;QACL,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,EAAE,MAAM,CAAC;KACnB,GAAG,IAAI,CAAC;CACV;AAED,qFAAqF;AACrF,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE;QACJ,UAAU,IAAI,OAAO,CAAC;YACpB,IAAI,EAAE;gBAAE,OAAO,EAAE;oBAAE,YAAY,EAAE,MAAM,CAAA;iBAAE,GAAG,IAAI,CAAA;aAAE,CAAC;SACpD,CAAC,CAAC;KACJ,CAAC;CACH;AAoGD;;;;;GAKG;AACH,wBAAsB,aAAa,CACjC,iBAAiB,EAAE,iBAAiB,GAAG,wBAAwB,EAC/D,KAAK,EAAE,kBAAkB,GACxB,OAAO,CAAC,mBAAmB,CAAC,CAiB9B"}
package/dist/lib/ai.js CHANGED
@@ -1,5 +1,61 @@
1
1
  /** AI roast classification through the canonical Parchment API. */
2
2
  import { createParchmentClient, unwrapParchment } from './parchment.js';
3
+ const CLASSIFICATION_STRING_LIMIT = 500;
4
+ const CLASSIFICATION_NOTES_LIMIT = 2_000;
5
+ const CLASSIFICATION_WEIGHT_UNIT_LIMIT = 16;
6
+ const CLASSIFICATION_INVENTORY_LIMIT = 100;
7
+ function normalizeOptionalString(value, maxLength) {
8
+ if (typeof value !== 'string')
9
+ return undefined;
10
+ const normalized = value.trim();
11
+ return normalized ? normalized.slice(0, maxLength) : undefined;
12
+ }
13
+ function normalizeWeight(value) {
14
+ if (!Array.isArray(value) || value.length !== 3)
15
+ return undefined;
16
+ const [input, output, rawUnit] = value;
17
+ const unit = normalizeOptionalString(typeof rawUnit === 'string' ? rawUnit : undefined, CLASSIFICATION_WEIGHT_UNIT_LIMIT);
18
+ if (typeof input !== 'number' ||
19
+ !Number.isFinite(input) ||
20
+ input < 0 ||
21
+ typeof output !== 'number' ||
22
+ !Number.isFinite(output) ||
23
+ output < 0 ||
24
+ !unit) {
25
+ return undefined;
26
+ }
27
+ return [input, output, unit];
28
+ }
29
+ function normalizeClassificationInput(input) {
30
+ const filename = normalizeOptionalString(input.alogMetadata.filename, CLASSIFICATION_STRING_LIMIT);
31
+ const title = normalizeOptionalString(input.alogMetadata.title, CLASSIFICATION_STRING_LIMIT) ?? filename;
32
+ if (!title) {
33
+ throw new Error('Invalid roast classification input: alogMetadata.title and filename cannot both be blank.');
34
+ }
35
+ const inventory = input.inventory.slice(0, CLASSIFICATION_INVENTORY_LIMIT).map((item, index) => {
36
+ if (!Number.isInteger(item.id) || item.id <= 0) {
37
+ throw new Error(`Invalid roast classification input: inventory[${index}].id must be a positive integer.`);
38
+ }
39
+ const coffeeName = normalizeOptionalString(item.coffee_name, CLASSIFICATION_STRING_LIMIT) ?? `Bean #${item.id}`;
40
+ return {
41
+ id: item.id,
42
+ coffee_name: coffeeName,
43
+ origin: normalizeOptionalString(item.origin, CLASSIFICATION_STRING_LIMIT),
44
+ processing: normalizeOptionalString(item.processing, CLASSIFICATION_STRING_LIMIT),
45
+ };
46
+ });
47
+ return {
48
+ alogMetadata: {
49
+ title,
50
+ filename,
51
+ roastertype: normalizeOptionalString(input.alogMetadata.roastertype, CLASSIFICATION_STRING_LIMIT),
52
+ beans: normalizeOptionalString(input.alogMetadata.beans, CLASSIFICATION_STRING_LIMIT),
53
+ roastingnotes: normalizeOptionalString(input.alogMetadata.roastingnotes, CLASSIFICATION_NOTES_LIMIT),
54
+ weight: normalizeWeight(input.alogMetadata.weight),
55
+ },
56
+ inventory,
57
+ };
58
+ }
3
59
  async function resolveClassificationApiKey(source) {
4
60
  if ('getSession' in source) {
5
61
  const { data: { session }, } = await source.getSession();
@@ -22,7 +78,7 @@ export async function classifyRoast(credentialContext, input) {
22
78
  throw new Error('Not authenticated. Run `purvey auth login` first.');
23
79
  }
24
80
  const client = await createParchmentClient('member', apiKey);
25
- const data = unwrapParchment(await client.roasts.classify(input), 'AI roast classification');
81
+ const data = unwrapParchment(await client.roasts.classify(normalizeClassificationInput(input)), 'AI roast classification');
26
82
  // Keep the historical library contract tolerant of an omitted match.
27
83
  return {
28
84
  match: data.match ?? null,
@@ -1 +1 @@
1
- {"version":3,"file":"ai.js","sourceRoot":"","sources":["../../src/lib/ai.ts"],"names":[],"mappings":"AAAA,mEAAmE;AAGnE,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAuCxE,KAAK,UAAU,2BAA2B,CACxC,MAAoD;IAEpD,IAAI,YAAY,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,EACJ,IAAI,EAAE,EAAE,OAAO,EAAE,GAClB,GAAG,MAAM,MAAM,CAAC,UAAU,EAAE,CAAC;QAC9B,OAAO,OAAO,EAAE,MAAM,CAAC;IACzB,CAAC;IAED,MAAM,EACJ,IAAI,EAAE,EAAE,OAAO,EAAE,GAClB,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;IACnC,OAAO,OAAO,EAAE,YAAY,CAAC;AAC/B,CAAC;AAED,iFAAiF;AAEjF;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,iBAA+D,EAC/D,KAAyB;IAEzB,8DAA8D;IAC9D,MAAM,MAAM,GAAG,MAAM,2BAA2B,CAAC,iBAAiB,CAAC,CAAC;IACpE,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;IACvE,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,qBAAqB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC7D,MAAM,IAAI,GAAG,eAAe,CAAC,MAAM,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,yBAAyB,CAAC,CAAC;IAE7F,qEAAqE;IACrE,OAAO;QACL,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,IAAI;KAC1B,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"ai.js","sourceRoot":"","sources":["../../src/lib/ai.ts"],"names":[],"mappings":"AAAA,mEAAmE;AAGnE,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAuCxE,MAAM,2BAA2B,GAAG,GAAG,CAAC;AACxC,MAAM,0BAA0B,GAAG,KAAK,CAAC;AACzC,MAAM,gCAAgC,GAAG,EAAE,CAAC;AAC5C,MAAM,8BAA8B,GAAG,GAAG,CAAC;AAE3C,SAAS,uBAAuB,CAAC,KAAyB,EAAE,SAAiB;IAC3E,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IAChD,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAChC,OAAO,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACjE,CAAC;AAED,SAAS,eAAe,CAAC,KAAc;IACrC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAClE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,GAAG,KAAK,CAAC;IACvC,MAAM,IAAI,GAAG,uBAAuB,CAClC,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,EACjD,gCAAgC,CACjC,CAAC;IACF,IACE,OAAO,KAAK,KAAK,QAAQ;QACzB,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QACvB,KAAK,GAAG,CAAC;QACT,OAAO,MAAM,KAAK,QAAQ;QAC1B,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;QACxB,MAAM,GAAG,CAAC;QACV,CAAC,IAAI,EACL,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;AAC/B,CAAC;AAED,SAAS,4BAA4B,CAAC,KAAyB;IAC7D,MAAM,QAAQ,GAAG,uBAAuB,CACtC,KAAK,CAAC,YAAY,CAAC,QAAQ,EAC3B,2BAA2B,CAC5B,CAAC;IACF,MAAM,KAAK,GACT,uBAAuB,CAAC,KAAK,CAAC,YAAY,CAAC,KAAK,EAAE,2BAA2B,CAAC,IAAI,QAAQ,CAAC;IAC7F,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CACb,2FAA2F,CAC5F,CAAC;IACJ,CAAC;IAED,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,8BAA8B,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;QAC7F,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC;YAC/C,MAAM,IAAI,KAAK,CACb,iDAAiD,KAAK,kCAAkC,CACzF,CAAC;QACJ,CAAC;QACD,MAAM,UAAU,GACd,uBAAuB,CAAC,IAAI,CAAC,WAAW,EAAE,2BAA2B,CAAC,IAAI,SAAS,IAAI,CAAC,EAAE,EAAE,CAAC;QAC/F,OAAO;YACL,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,WAAW,EAAE,UAAU;YACvB,MAAM,EAAE,uBAAuB,CAAC,IAAI,CAAC,MAAM,EAAE,2BAA2B,CAAC;YACzE,UAAU,EAAE,uBAAuB,CAAC,IAAI,CAAC,UAAU,EAAE,2BAA2B,CAAC;SAClF,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,YAAY,EAAE;YACZ,KAAK;YACL,QAAQ;YACR,WAAW,EAAE,uBAAuB,CAClC,KAAK,CAAC,YAAY,CAAC,WAAW,EAC9B,2BAA2B,CAC5B;YACD,KAAK,EAAE,uBAAuB,CAAC,KAAK,CAAC,YAAY,CAAC,KAAK,EAAE,2BAA2B,CAAC;YACrF,aAAa,EAAE,uBAAuB,CACpC,KAAK,CAAC,YAAY,CAAC,aAAa,EAChC,0BAA0B,CAC3B;YACD,MAAM,EAAE,eAAe,CAAC,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC;SACnD;QACD,SAAS;KACV,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,2BAA2B,CACxC,MAAoD;IAEpD,IAAI,YAAY,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,EACJ,IAAI,EAAE,EAAE,OAAO,EAAE,GAClB,GAAG,MAAM,MAAM,CAAC,UAAU,EAAE,CAAC;QAC9B,OAAO,OAAO,EAAE,MAAM,CAAC;IACzB,CAAC;IAED,MAAM,EACJ,IAAI,EAAE,EAAE,OAAO,EAAE,GAClB,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;IACnC,OAAO,OAAO,EAAE,YAAY,CAAC;AAC/B,CAAC;AAED,iFAAiF;AAEjF;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,iBAA+D,EAC/D,KAAyB;IAEzB,8DAA8D;IAC9D,MAAM,MAAM,GAAG,MAAM,2BAA2B,CAAC,iBAAiB,CAAC,CAAC;IACpE,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;IACvE,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,qBAAqB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC7D,MAAM,IAAI,GAAG,eAAe,CAC1B,MAAM,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,4BAA4B,CAAC,KAAK,CAAC,CAAC,EACjE,yBAAyB,CAC1B,CAAC;IAEF,qEAAqE;IACrE,OAAO;QACL,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,IAAI;KAC1B,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@purveyors/cli",
3
- "version": "0.32.0",
3
+ "version": "0.32.1",
4
4
  "description": "The official CLI for purveyors.io — coffee intelligence from your terminal",
5
5
  "type": "module",
6
6
  "bin": {