@purveyors/sdk 0.52.0 → 0.54.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.
package/dist/index.d.ts CHANGED
@@ -1159,7 +1159,10 @@ interface paths {
1159
1159
  };
1160
1160
  get?: never;
1161
1161
  put?: never;
1162
- /** Snapshot an executed roast as a reference profile */
1162
+ /**
1163
+ * Save an executed roast as a reference profile
1164
+ * @description Save one of the caller's executed roasts as a reference profile. The default `chart_snapshot` basis stores the roast's chart for comparison only. The `artisan_source` basis copies the Artisan file the roast was imported from, so the reference can be the base for a planned profile and its export; it requires a roast with an Artisan file on record, returns 400 `roast_artisan_source_unavailable` with a `reason` otherwise, and returns the reference already saved from that roast's file instead of creating a duplicate. The roast is never modified. Requires Mallard Studio, and for API keys the exact roast:read and roast:write scopes.
1165
+ */
1163
1166
  post: {
1164
1167
  parameters: {
1165
1168
  query?: never;
@@ -1175,7 +1178,22 @@ interface paths {
1175
1178
  };
1176
1179
  };
1177
1180
  responses: {
1178
- /** @description Created immutable roast snapshot */
1181
+ /** @description The reference already saved from this roast's Artisan file */
1182
+ 200: {
1183
+ headers: {
1184
+ "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
1185
+ "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
1186
+ "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
1187
+ "X-RateLimit-Burst-Limit": components["headers"]["X-RateLimit-Burst-Limit"];
1188
+ "X-RateLimit-Burst-Remaining": components["headers"]["X-RateLimit-Burst-Remaining"];
1189
+ "X-RateLimit-Burst-Reset": components["headers"]["X-RateLimit-Burst-Reset"];
1190
+ [name: string]: unknown;
1191
+ };
1192
+ content: {
1193
+ "application/json": components["schemas"]["ReferenceProfileResponse"];
1194
+ };
1195
+ };
1196
+ /** @description Created reference profile */
1179
1197
  201: {
1180
1198
  headers: {
1181
1199
  "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
@@ -1190,8 +1208,144 @@ interface paths {
1190
1208
  "application/json": components["schemas"]["ReferenceProfileResponse"];
1191
1209
  };
1192
1210
  };
1193
- /** @description Invalid request */
1211
+ /** @description Invalid request, or the roast has no usable Artisan file on record */
1194
1212
  400: {
1213
+ headers: {
1214
+ "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
1215
+ "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
1216
+ "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
1217
+ "X-RateLimit-Burst-Limit": components["headers"]["X-RateLimit-Burst-Limit"];
1218
+ "X-RateLimit-Burst-Remaining": components["headers"]["X-RateLimit-Burst-Remaining"];
1219
+ "X-RateLimit-Burst-Reset": components["headers"]["X-RateLimit-Burst-Reset"];
1220
+ [name: string]: unknown;
1221
+ };
1222
+ content: {
1223
+ "application/json": components["schemas"]["RoastSourceErrorResponse"];
1224
+ };
1225
+ };
1226
+ /** @description Authentication required */
1227
+ 401: {
1228
+ headers: {
1229
+ "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
1230
+ "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
1231
+ "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
1232
+ "X-RateLimit-Burst-Limit": components["headers"]["X-RateLimit-Burst-Limit"];
1233
+ "X-RateLimit-Burst-Remaining": components["headers"]["X-RateLimit-Burst-Remaining"];
1234
+ "X-RateLimit-Burst-Reset": components["headers"]["X-RateLimit-Burst-Reset"];
1235
+ [name: string]: unknown;
1236
+ };
1237
+ content: {
1238
+ "application/json": components["schemas"]["ErrorResponse"];
1239
+ };
1240
+ };
1241
+ /** @description Insufficient entitlement (plan or role) */
1242
+ 403: {
1243
+ headers: {
1244
+ "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
1245
+ "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
1246
+ "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
1247
+ "X-RateLimit-Burst-Limit": components["headers"]["X-RateLimit-Burst-Limit"];
1248
+ "X-RateLimit-Burst-Remaining": components["headers"]["X-RateLimit-Burst-Remaining"];
1249
+ "X-RateLimit-Burst-Reset": components["headers"]["X-RateLimit-Burst-Reset"];
1250
+ [name: string]: unknown;
1251
+ };
1252
+ content: {
1253
+ "application/json": components["schemas"]["ErrorResponse"];
1254
+ };
1255
+ };
1256
+ /** @description Reference profile or source roast not found */
1257
+ 404: {
1258
+ headers: {
1259
+ "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
1260
+ "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
1261
+ "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
1262
+ "X-RateLimit-Burst-Limit": components["headers"]["X-RateLimit-Burst-Limit"];
1263
+ "X-RateLimit-Burst-Remaining": components["headers"]["X-RateLimit-Burst-Remaining"];
1264
+ "X-RateLimit-Burst-Reset": components["headers"]["X-RateLimit-Burst-Reset"];
1265
+ [name: string]: unknown;
1266
+ };
1267
+ content: {
1268
+ "application/json": components["schemas"]["ErrorResponse"];
1269
+ };
1270
+ };
1271
+ /** @description Revision, idempotency, or concurrency conflict */
1272
+ 409: {
1273
+ headers: {
1274
+ "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
1275
+ "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
1276
+ "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
1277
+ "X-RateLimit-Burst-Limit": components["headers"]["X-RateLimit-Burst-Limit"];
1278
+ "X-RateLimit-Burst-Remaining": components["headers"]["X-RateLimit-Burst-Remaining"];
1279
+ "X-RateLimit-Burst-Reset": components["headers"]["X-RateLimit-Burst-Reset"];
1280
+ [name: string]: unknown;
1281
+ };
1282
+ content: {
1283
+ "application/json": components["schemas"]["ErrorResponse"];
1284
+ };
1285
+ };
1286
+ 429: components["responses"]["ApiRateLimitExceeded"];
1287
+ };
1288
+ };
1289
+ delete?: never;
1290
+ options?: never;
1291
+ head?: never;
1292
+ patch?: never;
1293
+ trace?: never;
1294
+ };
1295
+ "/v1/reference-profiles/from-roast/candidates": {
1296
+ parameters: {
1297
+ query?: never;
1298
+ header?: never;
1299
+ path?: never;
1300
+ cookie?: never;
1301
+ };
1302
+ /**
1303
+ * List executed roasts that can be the base for a planned profile
1304
+ * @description List the caller's executed roasts whose Artisan file is on record, newest first, each with its current revision token and the reference it is or would be saved under. `ineligibleRoastCount` counts the caller's other roasts, which have no usable Artisan file on record (entered manually, logged live, imported before files were kept, or holding a file larger than a reference profile allows). Requires Mallard Studio, and for API keys the exact roast:read scope.
1305
+ */
1306
+ get: {
1307
+ parameters: {
1308
+ query?: {
1309
+ limit?: number;
1310
+ };
1311
+ header?: never;
1312
+ path?: never;
1313
+ cookie?: never;
1314
+ };
1315
+ requestBody?: never;
1316
+ responses: {
1317
+ /** @description Roasts with an Artisan file on record */
1318
+ 200: {
1319
+ headers: {
1320
+ "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
1321
+ "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
1322
+ "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
1323
+ "X-RateLimit-Burst-Limit": components["headers"]["X-RateLimit-Burst-Limit"];
1324
+ "X-RateLimit-Burst-Remaining": components["headers"]["X-RateLimit-Burst-Remaining"];
1325
+ "X-RateLimit-Burst-Reset": components["headers"]["X-RateLimit-Burst-Reset"];
1326
+ [name: string]: unknown;
1327
+ };
1328
+ content: {
1329
+ "application/json": components["schemas"]["ReferenceProfileRoastCandidatesResponse"];
1330
+ };
1331
+ };
1332
+ /** @description Authentication required */
1333
+ 401: {
1334
+ headers: {
1335
+ "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
1336
+ "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
1337
+ "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
1338
+ "X-RateLimit-Burst-Limit": components["headers"]["X-RateLimit-Burst-Limit"];
1339
+ "X-RateLimit-Burst-Remaining": components["headers"]["X-RateLimit-Burst-Remaining"];
1340
+ "X-RateLimit-Burst-Reset": components["headers"]["X-RateLimit-Burst-Reset"];
1341
+ [name: string]: unknown;
1342
+ };
1343
+ content: {
1344
+ "application/json": components["schemas"]["ErrorResponse"];
1345
+ };
1346
+ };
1347
+ /** @description Insufficient entitlement (plan or role) */
1348
+ 403: {
1195
1349
  headers: {
1196
1350
  "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
1197
1351
  "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
@@ -1205,6 +1359,73 @@ interface paths {
1205
1359
  "application/json": components["schemas"]["ErrorResponse"];
1206
1360
  };
1207
1361
  };
1362
+ 429: components["responses"]["ApiRateLimitExceeded"];
1363
+ };
1364
+ };
1365
+ put?: never;
1366
+ post?: never;
1367
+ delete?: never;
1368
+ options?: never;
1369
+ head?: never;
1370
+ patch?: never;
1371
+ trace?: never;
1372
+ };
1373
+ "/v1/reference-profiles/from-roast/preview": {
1374
+ parameters: {
1375
+ query?: never;
1376
+ header?: never;
1377
+ path?: never;
1378
+ cookie?: never;
1379
+ };
1380
+ get?: never;
1381
+ put?: never;
1382
+ /**
1383
+ * Preview a planned profile based on an executed roast
1384
+ * @description Preview a constrained planned profile built on the Artisan file one of the caller's executed roasts was imported from. Read-only: nothing is saved and the roast is not modified. Returns the same measured preview as a saved reference, plus the reference identity a later save would use. Roasts without a usable Artisan file on record return 400 `roast_artisan_source_unavailable` with a `reason`. Requires Mallard Studio, and for API keys the exact roast:read scope.
1385
+ */
1386
+ post: {
1387
+ parameters: {
1388
+ query?: never;
1389
+ header?: never;
1390
+ path?: never;
1391
+ cookie?: never;
1392
+ };
1393
+ requestBody: {
1394
+ content: {
1395
+ "application/json": components["schemas"]["ReferenceProfileRoastGenerationRequest"];
1396
+ };
1397
+ };
1398
+ responses: {
1399
+ /** @description Deterministic preview without persistence */
1400
+ 200: {
1401
+ headers: {
1402
+ "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
1403
+ "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
1404
+ "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
1405
+ "X-RateLimit-Burst-Limit": components["headers"]["X-RateLimit-Burst-Limit"];
1406
+ "X-RateLimit-Burst-Remaining": components["headers"]["X-RateLimit-Burst-Remaining"];
1407
+ "X-RateLimit-Burst-Reset": components["headers"]["X-RateLimit-Burst-Reset"];
1408
+ [name: string]: unknown;
1409
+ };
1410
+ content: {
1411
+ "application/json": components["schemas"]["ReferenceProfileRoastGenerationPreviewResponse"];
1412
+ };
1413
+ };
1414
+ /** @description Invalid request, or the roast has no usable Artisan file on record */
1415
+ 400: {
1416
+ headers: {
1417
+ "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
1418
+ "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
1419
+ "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
1420
+ "X-RateLimit-Burst-Limit": components["headers"]["X-RateLimit-Burst-Limit"];
1421
+ "X-RateLimit-Burst-Remaining": components["headers"]["X-RateLimit-Burst-Remaining"];
1422
+ "X-RateLimit-Burst-Reset": components["headers"]["X-RateLimit-Burst-Reset"];
1423
+ [name: string]: unknown;
1424
+ };
1425
+ content: {
1426
+ "application/json": components["schemas"]["RoastSourceErrorResponse"];
1427
+ };
1428
+ };
1208
1429
  /** @description Authentication required */
1209
1430
  401: {
1210
1431
  headers: {
@@ -4128,6 +4349,7 @@ interface paths {
4128
4349
  screenMax?: number | null;
4129
4350
  includeUnknownScreen?: "true" | "false";
4130
4351
  gradeCode?: string | string[];
4352
+ gradeDimension?: "size" | "altitude" | "defects" | "cup" | "preparation";
4131
4353
  peaberry?: "true" | "false";
4132
4354
  labAnalyzed?: "true" | "false";
4133
4355
  moistureMax?: number | null;
@@ -4251,6 +4473,7 @@ interface paths {
4251
4473
  screenMax?: number | null;
4252
4474
  includeUnknownScreen?: "true" | "false";
4253
4475
  gradeCode?: string | string[];
4476
+ gradeDimension?: "size" | "altitude" | "defects" | "cup" | "preparation";
4254
4477
  peaberry?: "true" | "false";
4255
4478
  labAnalyzed?: "true" | "false";
4256
4479
  moistureMax?: number | null;
@@ -4377,6 +4600,7 @@ interface paths {
4377
4600
  get: {
4378
4601
  parameters: {
4379
4602
  query?: {
4603
+ include?: "grading";
4380
4604
  stocked?: "true" | "false" | "all";
4381
4605
  showWholesale?: "true" | "false";
4382
4606
  wholesaleOnly?: "true" | "false";
@@ -4409,6 +4633,7 @@ interface paths {
4409
4633
  screenMax?: number | null;
4410
4634
  includeUnknownScreen?: "true" | "false";
4411
4635
  gradeCode?: string | string[];
4636
+ gradeDimension?: "size" | "altitude" | "defects" | "cup" | "preparation";
4412
4637
  peaberry?: "true" | "false";
4413
4638
  labAnalyzed?: "true" | "false";
4414
4639
  moistureMax?: number | null;
@@ -6003,7 +6228,7 @@ interface paths {
6003
6228
  };
6004
6229
  /**
6005
6230
  * Find catalog coffees similar to a target coffee
6006
- * @description Vector-similarity matches between public supplier catalog coffees, with deterministic identity gating, supplier-diversity re-ranking, and a canonical/similar split. User-owned coffees are excluded. Available to member sessions and customer API keys; API keys also require catalog:read. Green responses return at most 25 matches.
6231
+ * @description Vector-similarity matches between public supplier catalog coffees, with deterministic identity gating, supplier-diversity re-ranking, and a canonical/similar split. User-owned coffees are excluded. Available to member sessions, or any customer API key with catalog:read (all API plans, within plan quota). Responses return at most 25 matches.
6007
6232
  */
6008
6233
  get: {
6009
6234
  parameters: {
@@ -7130,7 +7355,7 @@ interface paths {
7130
7355
  put?: never;
7131
7356
  /**
7132
7357
  * Execute a user-confirmed product action
7133
- * @description Execute one of the closed product actions for the authenticated session owner. The stable executionId provides payload-bound replay, and owner plus entitlement checks run again inside the same database transaction as the mutation. Generated reference saves require explicit user confirmation and remain planned profiles. API keys are not accepted.
7358
+ * @description Execute one of the closed product actions for the authenticated session owner. The stable executionId provides payload-bound replay, and owner plus entitlement checks run again inside the same database transaction as the mutation. Generated reference saves require explicit user confirmation and remain planned profiles; one based on an executed roast also saves that roast's stored Artisan file as its parent reference and never modifies the roast. API keys are not accepted.
7134
7359
  */
7135
7360
  post: {
7136
7361
  parameters: {
@@ -7160,7 +7385,7 @@ interface paths {
7160
7385
  "application/json": components["schemas"]["ConfirmedActionExecuteResponse"];
7161
7386
  };
7162
7387
  };
7163
- /** @description Invalid or unsupported confirmed-action payload */
7388
+ /** @description Invalid or unsupported confirmed-action payload, or a roast-based plan whose roast has no usable Artisan file on record */
7164
7389
  400: {
7165
7390
  headers: {
7166
7391
  "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
@@ -7172,7 +7397,7 @@ interface paths {
7172
7397
  [name: string]: unknown;
7173
7398
  };
7174
7399
  content: {
7175
- "application/json": components["schemas"]["ErrorResponse"];
7400
+ "application/json": components["schemas"]["RoastSourceErrorResponse"];
7176
7401
  };
7177
7402
  };
7178
7403
  /** @description Authentication required */
@@ -10242,7 +10467,7 @@ interface paths {
10242
10467
  patch?: never;
10243
10468
  trace?: never;
10244
10469
  };
10245
- "/v1/roasts/{id}/artisan-import": {
10470
+ "/v1/roasts/imports/from-reference": {
10246
10471
  parameters: {
10247
10472
  query?: never;
10248
10473
  header?: never;
@@ -10250,29 +10475,28 @@ interface paths {
10250
10475
  cookie?: never;
10251
10476
  };
10252
10477
  get?: never;
10478
+ put?: never;
10253
10479
  /**
10254
- * Replace a roast's Artisan import
10255
- * @description Re-derive one of the caller's existing roasts from an Artisan `.alog` file: replace its temperature curve, event markers, milestones, chart bounds, and computed metrics, and write an artisan_import_log entry atomically. The roast's identity (coffee, batch name, roast date, weights, and user notes) is preserved. Optional `If-Match: <last_updated>` enables optimistic concurrency (409 on mismatch). Requires an authenticated session, or an owner-bound API key carrying the exact roast:write scope.
10480
+ * Create a roast from a saved Artisan reference
10481
+ * @description Create a roast profile owned by the caller from the Artisan file stored with one of their uploaded reference profiles, against one of their green-coffee lots. The curve, events, and import log are written atomically, exactly as a direct Artisan import. Only uploaded Artisan references qualify: a planned (generated) profile is never recorded as a roast, and a reference saved from an existing roast is refused because that roast is already in history. Requires Mallard Studio, and for API keys the exact roast:read and roast:write scopes.
10256
10482
  */
10257
- put: {
10483
+ post: {
10258
10484
  parameters: {
10259
10485
  query?: never;
10260
10486
  header?: {
10261
- "if-match"?: string;
10262
- };
10263
- path: {
10264
- id: number;
10487
+ "idempotency-key"?: string;
10265
10488
  };
10489
+ path?: never;
10266
10490
  cookie?: never;
10267
10491
  };
10268
10492
  requestBody: {
10269
10493
  content: {
10270
- "application/json": components["schemas"]["RoastArtisanImportReplaceRequest"];
10494
+ "application/json": components["schemas"]["RoastImportFromReferenceRequest"];
10271
10495
  };
10272
10496
  };
10273
10497
  responses: {
10274
- /** @description The updated roast profile plus import summary */
10275
- 200: {
10498
+ /** @description The created roast profile plus import summary */
10499
+ 201: {
10276
10500
  headers: {
10277
10501
  "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
10278
10502
  "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
@@ -10283,7 +10507,7 @@ interface paths {
10283
10507
  [name: string]: unknown;
10284
10508
  };
10285
10509
  content: {
10286
- "application/json": components["schemas"]["RoastImportResponse"];
10510
+ "application/json": components["schemas"]["RoastImportFromReferenceResponse"];
10287
10511
  };
10288
10512
  };
10289
10513
  /** @description Invalid query parameter */
@@ -10331,7 +10555,7 @@ interface paths {
10331
10555
  "application/json": components["schemas"]["ErrorResponse"];
10332
10556
  };
10333
10557
  };
10334
- /** @description No such roast profile owned by the caller */
10558
+ /** @description No such coffee lot owned by the caller */
10335
10559
  404: {
10336
10560
  headers: {
10337
10561
  "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
@@ -10395,22 +10619,181 @@ interface paths {
10395
10619
  };
10396
10620
  };
10397
10621
  };
10398
- post?: never;
10622
+ delete?: never;
10623
+ options?: never;
10624
+ head?: never;
10625
+ patch?: never;
10626
+ trace?: never;
10627
+ };
10628
+ "/v1/roasts/{id}/artisan-import": {
10629
+ parameters: {
10630
+ query?: never;
10631
+ header?: never;
10632
+ path?: never;
10633
+ cookie?: never;
10634
+ };
10635
+ get?: never;
10399
10636
  /**
10400
- * Clear a roast's Artisan import
10401
- * @description Remove import-derived temperature samples, event markers, and artisan_import_log rows from one of the caller's existing roasts without deleting the roast profile. Import-derived profile metrics are reset to manual/null values. Requires an authenticated session, or an owner-bound API key carrying the exact roast:write scope.
10637
+ * Replace a roast's Artisan import
10638
+ * @description Re-derive one of the caller's existing roasts from an Artisan `.alog` file: replace its temperature curve, event markers, milestones, chart bounds, and computed metrics, and write an artisan_import_log entry atomically. The roast's identity (coffee, batch name, roast date, weights, and user notes) is preserved. Optional `If-Match: <last_updated>` enables optimistic concurrency (409 on mismatch). Requires an authenticated session, or an owner-bound API key carrying the exact roast:write scope.
10402
10639
  */
10403
- delete: {
10640
+ put: {
10404
10641
  parameters: {
10405
10642
  query?: never;
10406
- header?: never;
10643
+ header?: {
10644
+ "if-match"?: string;
10645
+ };
10407
10646
  path: {
10408
10647
  id: number;
10409
10648
  };
10410
10649
  cookie?: never;
10411
10650
  };
10412
- requestBody?: never;
10413
- responses: {
10651
+ requestBody: {
10652
+ content: {
10653
+ "application/json": components["schemas"]["RoastArtisanImportReplaceRequest"];
10654
+ };
10655
+ };
10656
+ responses: {
10657
+ /** @description The updated roast profile plus import summary */
10658
+ 200: {
10659
+ headers: {
10660
+ "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
10661
+ "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
10662
+ "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
10663
+ "X-RateLimit-Burst-Limit": components["headers"]["X-RateLimit-Burst-Limit"];
10664
+ "X-RateLimit-Burst-Remaining": components["headers"]["X-RateLimit-Burst-Remaining"];
10665
+ "X-RateLimit-Burst-Reset": components["headers"]["X-RateLimit-Burst-Reset"];
10666
+ [name: string]: unknown;
10667
+ };
10668
+ content: {
10669
+ "application/json": components["schemas"]["RoastImportResponse"];
10670
+ };
10671
+ };
10672
+ /** @description Invalid query parameter */
10673
+ 400: {
10674
+ headers: {
10675
+ "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
10676
+ "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
10677
+ "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
10678
+ "X-RateLimit-Burst-Limit": components["headers"]["X-RateLimit-Burst-Limit"];
10679
+ "X-RateLimit-Burst-Remaining": components["headers"]["X-RateLimit-Burst-Remaining"];
10680
+ "X-RateLimit-Burst-Reset": components["headers"]["X-RateLimit-Burst-Reset"];
10681
+ [name: string]: unknown;
10682
+ };
10683
+ content: {
10684
+ "application/json": components["schemas"]["ErrorResponse"];
10685
+ };
10686
+ };
10687
+ /** @description Authentication required */
10688
+ 401: {
10689
+ headers: {
10690
+ "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
10691
+ "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
10692
+ "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
10693
+ "X-RateLimit-Burst-Limit": components["headers"]["X-RateLimit-Burst-Limit"];
10694
+ "X-RateLimit-Burst-Remaining": components["headers"]["X-RateLimit-Burst-Remaining"];
10695
+ "X-RateLimit-Burst-Reset": components["headers"]["X-RateLimit-Burst-Reset"];
10696
+ [name: string]: unknown;
10697
+ };
10698
+ content: {
10699
+ "application/json": components["schemas"]["ErrorResponse"];
10700
+ };
10701
+ };
10702
+ /** @description Insufficient entitlement (plan or role) */
10703
+ 403: {
10704
+ headers: {
10705
+ "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
10706
+ "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
10707
+ "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
10708
+ "X-RateLimit-Burst-Limit": components["headers"]["X-RateLimit-Burst-Limit"];
10709
+ "X-RateLimit-Burst-Remaining": components["headers"]["X-RateLimit-Burst-Remaining"];
10710
+ "X-RateLimit-Burst-Reset": components["headers"]["X-RateLimit-Burst-Reset"];
10711
+ [name: string]: unknown;
10712
+ };
10713
+ content: {
10714
+ "application/json": components["schemas"]["ErrorResponse"];
10715
+ };
10716
+ };
10717
+ /** @description No such roast profile owned by the caller */
10718
+ 404: {
10719
+ headers: {
10720
+ "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
10721
+ "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
10722
+ "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
10723
+ "X-RateLimit-Burst-Limit": components["headers"]["X-RateLimit-Burst-Limit"];
10724
+ "X-RateLimit-Burst-Remaining": components["headers"]["X-RateLimit-Burst-Remaining"];
10725
+ "X-RateLimit-Burst-Reset": components["headers"]["X-RateLimit-Burst-Reset"];
10726
+ [name: string]: unknown;
10727
+ };
10728
+ content: {
10729
+ "application/json": components["schemas"]["ErrorResponse"];
10730
+ };
10731
+ };
10732
+ /** @description Write conflict: an If-Match precondition failed */
10733
+ 409: {
10734
+ headers: {
10735
+ "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
10736
+ "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
10737
+ "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
10738
+ "X-RateLimit-Burst-Limit": components["headers"]["X-RateLimit-Burst-Limit"];
10739
+ "X-RateLimit-Burst-Remaining": components["headers"]["X-RateLimit-Burst-Remaining"];
10740
+ "X-RateLimit-Burst-Reset": components["headers"]["X-RateLimit-Burst-Reset"];
10741
+ [name: string]: unknown;
10742
+ };
10743
+ content: {
10744
+ "application/json": components["schemas"]["ErrorResponse"];
10745
+ };
10746
+ };
10747
+ /** @description Per-user mutation throttle exceeded; retry after a short wait Customer API keys may also receive an account monthly or machine burst quota rejection. */
10748
+ 429: {
10749
+ headers: {
10750
+ "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
10751
+ "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
10752
+ "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
10753
+ "X-RateLimit-Burst-Limit": components["headers"]["X-RateLimit-Burst-Limit"];
10754
+ "X-RateLimit-Burst-Remaining": components["headers"]["X-RateLimit-Burst-Remaining"];
10755
+ "X-RateLimit-Burst-Reset": components["headers"]["X-RateLimit-Burst-Reset"];
10756
+ "Retry-After": components["headers"]["Retry-After"];
10757
+ "X-RateLimit-Blocked-By": components["headers"]["X-RateLimit-Blocked-By"];
10758
+ [name: string]: unknown;
10759
+ };
10760
+ content: {
10761
+ "application/json": components["schemas"]["ErrorResponse"];
10762
+ };
10763
+ };
10764
+ /** @description Roast writes are not enabled in this environment */
10765
+ 503: {
10766
+ headers: {
10767
+ "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
10768
+ "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
10769
+ "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
10770
+ "X-RateLimit-Burst-Limit": components["headers"]["X-RateLimit-Burst-Limit"];
10771
+ "X-RateLimit-Burst-Remaining": components["headers"]["X-RateLimit-Burst-Remaining"];
10772
+ "X-RateLimit-Burst-Reset": components["headers"]["X-RateLimit-Burst-Reset"];
10773
+ [name: string]: unknown;
10774
+ };
10775
+ content: {
10776
+ "application/json": components["schemas"]["ErrorResponse"];
10777
+ };
10778
+ };
10779
+ };
10780
+ };
10781
+ post?: never;
10782
+ /**
10783
+ * Clear a roast's Artisan import
10784
+ * @description Remove import-derived temperature samples, event markers, and artisan_import_log rows from one of the caller's existing roasts without deleting the roast profile. Import-derived profile metrics are reset to manual/null values. Requires an authenticated session, or an owner-bound API key carrying the exact roast:write scope.
10785
+ */
10786
+ delete: {
10787
+ parameters: {
10788
+ query?: never;
10789
+ header?: never;
10790
+ path: {
10791
+ id: number;
10792
+ };
10793
+ cookie?: never;
10794
+ };
10795
+ requestBody?: never;
10796
+ responses: {
10414
10797
  /** @description The cleared roast id plus deleted row counts */
10415
10798
  200: {
10416
10799
  headers: {
@@ -13794,7 +14177,13 @@ interface components {
13794
14177
  updatedAt: string;
13795
14178
  };
13796
14179
  ReferenceProfileListResponse: {
13797
- data: components["schemas"]["ReferenceProfileSummary"][];
14180
+ data: (components["schemas"]["ReferenceProfileSummary"] & {
14181
+ /** @description The executed roast the current revision was saved from, or null for an uploaded or planned profile. */
14182
+ sourceRoast: {
14183
+ id: number;
14184
+ revision: string;
14185
+ } | null;
14186
+ })[];
13798
14187
  meta: {
13799
14188
  /** @enum {string} */
13800
14189
  resource: "reference-profiles";
@@ -13996,110 +14385,248 @@ interface components {
13996
14385
  fileContent: string;
13997
14386
  fileSize?: number;
13998
14387
  };
14388
+ RoastSourceErrorResponse: {
14389
+ error: {
14390
+ code: string;
14391
+ message: string;
14392
+ /**
14393
+ * @description Present when code is `roast_artisan_source_unavailable`. `no_artisan_import`: the roast was entered manually or logged live. `artisan_file_not_retained`: it was imported before Artisan files were kept. `artisan_file_too_large`: its file is larger than a reference profile can hold.
14394
+ * @enum {string}
14395
+ */
14396
+ reason?: "no_artisan_import" | "artisan_file_not_retained" | "artisan_file_too_large";
14397
+ };
14398
+ };
13999
14399
  ReferenceProfileFromRoastRequest: {
14000
14400
  roastId: number;
14401
+ /** @description The roast's current revision token (its last_updated value). */
14001
14402
  roastRevision: string;
14403
+ /**
14404
+ * @description chart_snapshot keeps a comparison-only chart. artisan_source copies the roast's stored Artisan file so a planned profile can be built from it.
14405
+ * @default chart_snapshot
14406
+ * @enum {string}
14407
+ */
14408
+ basis: "chart_snapshot" | "artisan_source";
14002
14409
  title?: string;
14003
14410
  notes?: string;
14004
14411
  };
14005
- ProfileComparisonResponse: {
14412
+ ReferenceProfileRoastCandidatesResponse: {
14006
14413
  data: {
14007
- /** @enum {string} */
14008
- alignment: "charge";
14009
- /** @enum {string} */
14010
- targetUnit: "F" | "C";
14011
- left: {
14012
- type: string;
14013
- id: string;
14014
- revision: string;
14015
- };
14016
- right: {
14017
- type: string;
14018
- id: string;
14019
- revision: string;
14020
- };
14021
- series: {
14022
- id: string;
14023
- name: string;
14024
- /** @enum {string} */
14025
- kind: "bean_temperature" | "environmental_temperature" | "auxiliary";
14026
- unit: string;
14027
- points: {
14028
- timeMilliseconds: number;
14029
- left: number;
14030
- right: number;
14031
- delta: number;
14032
- }[];
14033
- }[];
14034
- milestones: {
14035
- name: string;
14036
- leftMilliseconds: number;
14037
- rightMilliseconds: number;
14038
- deltaMilliseconds: number;
14414
+ roasts: {
14415
+ roastId: number;
14416
+ roastRevision: string;
14417
+ label: string;
14418
+ batchName: string | null;
14419
+ coffeeName: string | null;
14420
+ roastDate: string | null;
14421
+ reference: {
14422
+ /** Format: uuid */
14423
+ profileId: string;
14424
+ /** Format: uuid */
14425
+ revisionId: string;
14426
+ saved: boolean;
14427
+ };
14039
14428
  }[];
14429
+ eligibleCount: number;
14430
+ totalRoastCount: number;
14431
+ ineligibleRoastCount: number;
14040
14432
  };
14041
14433
  meta: {
14042
14434
  /** @enum {string} */
14043
- resource: "profile-comparisons";
14435
+ resource: "reference-profile-roast-candidates";
14044
14436
  /** @enum {string} */
14045
- namespace: "/v1/profile-comparisons";
14437
+ namespace: "/v1/reference-profiles";
14046
14438
  /** @enum {string} */
14047
14439
  version: "v1";
14048
14440
  };
14049
14441
  };
14050
- ProfileComparisonRequest: {
14051
- left: {
14052
- /** @enum {string} */
14053
- type: "reference_revision";
14054
- /** Format: uuid */
14055
- revisionId: string;
14056
- } | {
14057
- /** @enum {string} */
14058
- type: "executed_roast";
14059
- roastId: number;
14060
- roastRevision: string;
14061
- };
14062
- right: {
14063
- /** @enum {string} */
14064
- type: "reference_revision";
14442
+ ReferenceProfileRoastGenerationPreviewResponse: {
14443
+ data: {
14065
14444
  /** Format: uuid */
14066
- revisionId: string;
14067
- } | {
14068
- /** @enum {string} */
14069
- type: "executed_roast";
14070
- roastId: number;
14071
- roastRevision: string;
14072
- };
14073
- /**
14074
- * @default charge
14075
- * @enum {string}
14076
- */
14077
- alignment: "charge";
14078
- /** @enum {string} */
14079
- targetUnit: "F" | "C";
14080
- /** @default 400 */
14081
- targetPoints: number;
14082
- };
14083
- AccountDeletionOperation: {
14084
- /** Format: uuid */
14085
- operationId: string;
14086
- /** @enum {string} */
14087
- status: "accepted" | "provider_deleting" | "local_cleaning" | "auth_deleting" | "post_auth_cleanup" | "retryable" | "conflict" | "completed";
14088
- };
14089
- BillingCheckoutSession: {
14090
- /** Format: uuid */
14091
- admissionId: string;
14092
- /** @enum {string} */
14093
- status: "accepted" | "attempting" | "published" | "settled" | "closed" | "conflict";
14094
- clientSecret: string | null;
14095
- };
14096
- MarketBriefDraftState: {
14097
- /** Format: uuid */
14098
- draftId: string;
14099
- edition: number;
14100
- productionCommit: string;
14101
- /** @enum {string} */
14102
- status: "creating" | "uncertain" | "created" | "conflict";
14445
+ parentRevisionId: string;
14446
+ title: string;
14447
+ userGoal: string | null;
14448
+ modelRecommendation: string | null;
14449
+ userEdits: string | null;
14450
+ changes: {
14451
+ temperatureAdjustments: {
14452
+ /** @enum {string} */
14453
+ kind: "bean_temperature" | "environmental_temperature";
14454
+ startMilliseconds: number;
14455
+ endMilliseconds: number;
14456
+ delta: number;
14457
+ }[];
14458
+ };
14459
+ measuredFacts: {
14460
+ /** @enum {string} */
14461
+ temperatureUnit: "F" | "C";
14462
+ adjustments: {
14463
+ /** @enum {string} */
14464
+ kind: "bean_temperature" | "environmental_temperature";
14465
+ startMilliseconds: number;
14466
+ endMilliseconds: number;
14467
+ requestedDelta: number;
14468
+ /** @enum {string} */
14469
+ unit: "F" | "C";
14470
+ changedSampleCount: number;
14471
+ unchangedZeroSampleCount: number;
14472
+ parent: {
14473
+ first: {
14474
+ timeMilliseconds: number;
14475
+ value: number;
14476
+ } | null;
14477
+ last: {
14478
+ timeMilliseconds: number;
14479
+ value: number;
14480
+ } | null;
14481
+ minimum: number | null;
14482
+ maximum: number | null;
14483
+ };
14484
+ planned: {
14485
+ first: {
14486
+ timeMilliseconds: number;
14487
+ value: number;
14488
+ } | null;
14489
+ last: {
14490
+ timeMilliseconds: number;
14491
+ value: number;
14492
+ } | null;
14493
+ minimum: number | null;
14494
+ maximum: number | null;
14495
+ };
14496
+ }[];
14497
+ /** @enum {boolean} */
14498
+ eventsUnchanged: true;
14499
+ };
14500
+ chart: components["schemas"]["ReferenceProfileChart"];
14501
+ /** @enum {boolean} */
14502
+ exportEligible: true;
14503
+ /**
14504
+ * Format: uuid
14505
+ * @description The reference this roast's Artisan file is, or will be, saved under.
14506
+ */
14507
+ parentProfileId: string;
14508
+ /** @description Whether that reference already exists. A preview never creates it. */
14509
+ parentSaved: boolean;
14510
+ sourceRoast: {
14511
+ id: number;
14512
+ revision: string;
14513
+ label: string;
14514
+ batchName: string | null;
14515
+ coffeeName: string | null;
14516
+ roastDate: string | null;
14517
+ };
14518
+ };
14519
+ meta: {
14520
+ /** @enum {string} */
14521
+ resource: "reference-profile-previews";
14522
+ /** @enum {string} */
14523
+ namespace: "/v1/reference-profiles";
14524
+ /** @enum {string} */
14525
+ version: "v1";
14526
+ };
14527
+ };
14528
+ ReferenceProfileRoastGenerationRequest: components["schemas"]["ReferenceProfileGenerationRequest"] & {
14529
+ roastId: number;
14530
+ roastRevision: string;
14531
+ };
14532
+ ProfileComparisonResponse: {
14533
+ data: {
14534
+ /** @enum {string} */
14535
+ alignment: "charge";
14536
+ /** @enum {string} */
14537
+ targetUnit: "F" | "C";
14538
+ left: {
14539
+ type: string;
14540
+ id: string;
14541
+ revision: string;
14542
+ };
14543
+ right: {
14544
+ type: string;
14545
+ id: string;
14546
+ revision: string;
14547
+ };
14548
+ series: {
14549
+ id: string;
14550
+ name: string;
14551
+ /** @enum {string} */
14552
+ kind: "bean_temperature" | "environmental_temperature" | "auxiliary";
14553
+ unit: string;
14554
+ points: {
14555
+ timeMilliseconds: number;
14556
+ left: number;
14557
+ right: number;
14558
+ delta: number;
14559
+ }[];
14560
+ }[];
14561
+ milestones: {
14562
+ name: string;
14563
+ leftMilliseconds: number;
14564
+ rightMilliseconds: number;
14565
+ deltaMilliseconds: number;
14566
+ }[];
14567
+ };
14568
+ meta: {
14569
+ /** @enum {string} */
14570
+ resource: "profile-comparisons";
14571
+ /** @enum {string} */
14572
+ namespace: "/v1/profile-comparisons";
14573
+ /** @enum {string} */
14574
+ version: "v1";
14575
+ };
14576
+ };
14577
+ ProfileComparisonRequest: {
14578
+ left: {
14579
+ /** @enum {string} */
14580
+ type: "reference_revision";
14581
+ /** Format: uuid */
14582
+ revisionId: string;
14583
+ } | {
14584
+ /** @enum {string} */
14585
+ type: "executed_roast";
14586
+ roastId: number;
14587
+ roastRevision: string;
14588
+ };
14589
+ right: {
14590
+ /** @enum {string} */
14591
+ type: "reference_revision";
14592
+ /** Format: uuid */
14593
+ revisionId: string;
14594
+ } | {
14595
+ /** @enum {string} */
14596
+ type: "executed_roast";
14597
+ roastId: number;
14598
+ roastRevision: string;
14599
+ };
14600
+ /**
14601
+ * @default charge
14602
+ * @enum {string}
14603
+ */
14604
+ alignment: "charge";
14605
+ /** @enum {string} */
14606
+ targetUnit: "F" | "C";
14607
+ /** @default 400 */
14608
+ targetPoints: number;
14609
+ };
14610
+ AccountDeletionOperation: {
14611
+ /** Format: uuid */
14612
+ operationId: string;
14613
+ /** @enum {string} */
14614
+ status: "accepted" | "provider_deleting" | "local_cleaning" | "auth_deleting" | "post_auth_cleanup" | "retryable" | "conflict" | "completed";
14615
+ };
14616
+ BillingCheckoutSession: {
14617
+ /** Format: uuid */
14618
+ admissionId: string;
14619
+ /** @enum {string} */
14620
+ status: "accepted" | "attempting" | "published" | "settled" | "closed" | "conflict";
14621
+ clientSecret: string | null;
14622
+ };
14623
+ MarketBriefDraftState: {
14624
+ /** Format: uuid */
14625
+ draftId: string;
14626
+ edition: number;
14627
+ productionCommit: string;
14628
+ /** @enum {string} */
14629
+ status: "creating" | "uncertain" | "created" | "conflict";
14103
14630
  };
14104
14631
  MarketBriefDraftResponse: {
14105
14632
  data: components["schemas"]["MarketBriefDraftState"];
@@ -14690,6 +15217,13 @@ interface components {
14690
15217
  fermentation_type?: string[];
14691
15218
  process_additives?: string[];
14692
15219
  processing_disclosure_level?: string[];
15220
+ grade_size?: string[];
15221
+ grade_altitude?: string[];
15222
+ grade_defects?: string[];
15223
+ grade_cup?: string[];
15224
+ grade_preparation?: string[];
15225
+ screen_size_min?: string[];
15226
+ elevation_band?: string[];
14693
15227
  };
14694
15228
  /** @description Counted facet values for CLI/agent use. Counts are computed after visibility and entitled query filters are applied. */
14695
15229
  facets: {
@@ -14757,6 +15291,34 @@ interface components {
14757
15291
  value: string;
14758
15292
  count: number;
14759
15293
  }[];
15294
+ grade_size?: {
15295
+ value: string;
15296
+ count: number;
15297
+ }[];
15298
+ grade_altitude?: {
15299
+ value: string;
15300
+ count: number;
15301
+ }[];
15302
+ grade_defects?: {
15303
+ value: string;
15304
+ count: number;
15305
+ }[];
15306
+ grade_cup?: {
15307
+ value: string;
15308
+ count: number;
15309
+ }[];
15310
+ grade_preparation?: {
15311
+ value: string;
15312
+ count: number;
15313
+ }[];
15314
+ screen_size_min?: {
15315
+ value: string;
15316
+ count: number;
15317
+ }[];
15318
+ elevation_band?: {
15319
+ value: string;
15320
+ count: number;
15321
+ }[];
14760
15322
  };
14761
15323
  meta: {
14762
15324
  /** @enum {string} */
@@ -16516,6 +17078,8 @@ interface components {
16516
17078
  }[];
16517
17079
  };
16518
17080
  change_set_summary: string;
17081
+ source_roast_id?: number | string;
17082
+ source_roast_revision?: string;
16519
17083
  };
16520
17084
  } | {
16521
17085
  /** @description Stable operation id. Repeating it with the same action payload replays the stored result; changing the payload returns 409. */
@@ -17354,6 +17918,61 @@ interface components {
17354
17918
  /** @description Reported source size in bytes for import-log metadata; defaults to the content length. */
17355
17919
  fileSize?: number;
17356
17920
  };
17921
+ RoastImportFromReferenceResponse: {
17922
+ data: {
17923
+ roast: components["schemas"]["RoastDetailResource"];
17924
+ import: components["schemas"]["ArtisanImportSummary"];
17925
+ reference: {
17926
+ /** Format: uuid */
17927
+ profileId: string;
17928
+ /** Format: uuid */
17929
+ revisionId: string;
17930
+ /** @description Whether the reference now lists the new roast as a linked roast. */
17931
+ linked: boolean;
17932
+ };
17933
+ };
17934
+ meta: {
17935
+ /** @enum {string} */
17936
+ resource: "roasts";
17937
+ /** @enum {string} */
17938
+ namespace: "/v1/roasts";
17939
+ /** @enum {string} */
17940
+ version: "v1";
17941
+ auth: {
17942
+ /** @enum {string} */
17943
+ kind: "session" | "api-key";
17944
+ /** @enum {string|null} */
17945
+ role: "admin" | "member" | "viewer" | null;
17946
+ /** @enum {string|null} */
17947
+ apiPlan: "viewer" | "member" | "enterprise" | null;
17948
+ };
17949
+ };
17950
+ };
17951
+ RoastImportFromReferenceRequest: {
17952
+ /**
17953
+ * Format: uuid
17954
+ * @description A saved Artisan reference profile owned by the caller.
17955
+ */
17956
+ referenceProfileId: string;
17957
+ /**
17958
+ * Format: uuid
17959
+ * @description That reference's current revision.
17960
+ */
17961
+ referenceRevisionId: string;
17962
+ /** @description green_coffee_inv.id owned by the caller to roast against. */
17963
+ coffeeId: number;
17964
+ /** @description Batch name; defaults to '<coffee> - <roast date>'. */
17965
+ batchName?: string;
17966
+ /** @description Roast date (YYYY-MM-DD); defaults to the file's date. */
17967
+ roastDate?: string;
17968
+ /** @description Input weight in oz; defaults to the file's weight if present. */
17969
+ ozIn?: number;
17970
+ /** @description Output weight in oz; defaults to the file's weight if present. */
17971
+ ozOut?: number;
17972
+ /** @description Roast notes; overrides the generated import summary note. */
17973
+ roastNotes?: string;
17974
+ roastTargets?: string;
17975
+ };
17357
17976
  RoastArtisanImportReplaceRequest: {
17358
17977
  /** @description Source file name. Must end in .alog, .alog.json, or .json (Artisan export). */
17359
17978
  fileName: string;
@@ -18263,6 +18882,10 @@ type RoastChartSeries = components["schemas"]["RoastChartSeries"];
18263
18882
  type RoastChartEvent = components["schemas"]["RoastChartEvent"];
18264
18883
  type ReferenceProfileImportRequest = NonNullable<paths["/v1/reference-profiles/imports"]["post"]["requestBody"]>["content"]["application/json"];
18265
18884
  type ReferenceProfileFromRoastRequest = NonNullable<paths["/v1/reference-profiles/from-roast"]["post"]["requestBody"]>["content"]["application/json"];
18885
+ /** Request body for {@link ParchmentClient.referenceProfiles.previewFromRoast}. */
18886
+ type ReferenceProfileRoastGenerationRequest = NonNullable<paths["/v1/reference-profiles/from-roast/preview"]["post"]["requestBody"]>["content"]["application/json"];
18887
+ /** Query parameters for {@link ParchmentClient.referenceProfiles.roastCandidates}. */
18888
+ type ReferenceProfileRoastCandidatesQuery = NonNullable<paths["/v1/reference-profiles/from-roast/candidates"]["get"]["parameters"]["query"]>;
18266
18889
  type ReferenceProfileUpdateRequest = NonNullable<paths["/v1/reference-profiles/{id}"]["patch"]["requestBody"]>["content"]["application/json"];
18267
18890
  type ReferenceProfileGenerationRequest = NonNullable<paths["/v1/reference-profiles/{id}/revisions/{revisionId}/preview"]["post"]["requestBody"]>["content"]["application/json"];
18268
18891
  type ProfileComparisonRequest = NonNullable<paths["/v1/profile-comparisons"]["post"]["requestBody"]>["content"]["application/json"];
@@ -18278,6 +18901,8 @@ type RoastUpdateRequest = NonNullable<paths["/v1/roasts/{id}"]["patch"]["request
18278
18901
  type RoastLiveCurveRequest = NonNullable<paths["/v1/roasts/{id}/live-curve"]["put"]["requestBody"]>["content"]["application/json"];
18279
18902
  /** Request body for {@link ParchmentClient.roasts.import}. */
18280
18903
  type RoastImportRequest = NonNullable<paths["/v1/roasts/imports"]["post"]["requestBody"]>["content"]["application/json"];
18904
+ /** Request body for {@link ParchmentClient.roasts.importFromReference}. */
18905
+ type RoastImportFromReferenceRequest = NonNullable<paths["/v1/roasts/imports/from-reference"]["post"]["requestBody"]>["content"]["application/json"];
18281
18906
  /** Request body for {@link ParchmentClient.roasts.replaceArtisanImport}. */
18282
18907
  type RoastArtisanImportReplaceRequest = NonNullable<paths["/v1/roasts/{id}/artisan-import"]["put"]["requestBody"]>["content"]["application/json"];
18283
18908
  /** Query parameters for {@link ParchmentClient.sales.list}. */
@@ -20780,6 +21405,7 @@ declare function createParchmentClient(options: ParchmentClientOptions): {
20780
21405
  screenMax?: number | null;
20781
21406
  includeUnknownScreen?: "true" | "false";
20782
21407
  gradeCode?: string | string[];
21408
+ gradeDimension?: "size" | "altitude" | "defects" | "cup" | "preparation";
20783
21409
  peaberry?: "true" | "false";
20784
21410
  labAnalyzed?: "true" | "false";
20785
21411
  moistureMax?: number | null;
@@ -20886,6 +21512,7 @@ declare function createParchmentClient(options: ParchmentClientOptions): {
20886
21512
  screenMax?: number | null;
20887
21513
  includeUnknownScreen?: "true" | "false";
20888
21514
  gradeCode?: string | string[];
21515
+ gradeDimension?: "size" | "altitude" | "defects" | "cup" | "preparation";
20889
21516
  peaberry?: "true" | "false";
20890
21517
  labAnalyzed?: "true" | "false";
20891
21518
  moistureMax?: number | null;
@@ -20940,6 +21567,7 @@ declare function createParchmentClient(options: ParchmentClientOptions): {
20940
21567
  screenMax?: number | null;
20941
21568
  includeUnknownScreen?: "true" | "false";
20942
21569
  gradeCode?: string | string[];
21570
+ gradeDimension?: "size" | "altitude" | "defects" | "cup" | "preparation";
20943
21571
  peaberry?: "true" | "false";
20944
21572
  labAnalyzed?: "true" | "false";
20945
21573
  moistureMax?: number | null;
@@ -21073,6 +21701,7 @@ declare function createParchmentClient(options: ParchmentClientOptions): {
21073
21701
  screenMax?: number | null;
21074
21702
  includeUnknownScreen?: "true" | "false";
21075
21703
  gradeCode?: string | string[];
21704
+ gradeDimension?: "size" | "altitude" | "defects" | "cup" | "preparation";
21076
21705
  peaberry?: "true" | "false";
21077
21706
  labAnalyzed?: "true" | "false";
21078
21707
  moistureMax?: number | null;
@@ -21103,6 +21732,7 @@ declare function createParchmentClient(options: ParchmentClientOptions): {
21103
21732
  facets: (query?: CatalogFacetsQuery, headers?: CatalogFacetsHeaders) => Promise<openapi_fetch.FetchResponse<{
21104
21733
  parameters: {
21105
21734
  query?: {
21735
+ include?: "grading";
21106
21736
  stocked?: "true" | "false" | "all";
21107
21737
  showWholesale?: "true" | "false";
21108
21738
  wholesaleOnly?: "true" | "false";
@@ -21135,6 +21765,7 @@ declare function createParchmentClient(options: ParchmentClientOptions): {
21135
21765
  screenMax?: number | null;
21136
21766
  includeUnknownScreen?: "true" | "false";
21137
21767
  gradeCode?: string | string[];
21768
+ gradeDimension?: "size" | "altitude" | "defects" | "cup" | "preparation";
21138
21769
  peaberry?: "true" | "false";
21139
21770
  labAnalyzed?: "true" | "false";
21140
21771
  moistureMax?: number | null;
@@ -21203,6 +21834,7 @@ declare function createParchmentClient(options: ParchmentClientOptions): {
21203
21834
  }, {
21204
21835
  params: {
21205
21836
  query: {
21837
+ include?: "grading";
21206
21838
  stocked?: "true" | "false" | "all";
21207
21839
  showWholesale?: "true" | "false";
21208
21840
  wholesaleOnly?: "true" | "false";
@@ -21235,6 +21867,7 @@ declare function createParchmentClient(options: ParchmentClientOptions): {
21235
21867
  screenMax?: number | null;
21236
21868
  includeUnknownScreen?: "true" | "false";
21237
21869
  gradeCode?: string | string[];
21870
+ gradeDimension?: "size" | "altitude" | "defects" | "cup" | "preparation";
21238
21871
  peaberry?: "true" | "false";
21239
21872
  labAnalyzed?: "true" | "false";
21240
21873
  moistureMax?: number | null;
@@ -23874,7 +24507,7 @@ declare function createParchmentClient(options: ParchmentClientOptions): {
23874
24507
  [name: string]: unknown;
23875
24508
  };
23876
24509
  content: {
23877
- "application/json": components["schemas"]["ErrorResponse"];
24510
+ "application/json": components["schemas"]["RoastSourceErrorResponse"];
23878
24511
  };
23879
24512
  };
23880
24513
  401: {
@@ -24043,6 +24676,8 @@ declare function createParchmentClient(options: ParchmentClientOptions): {
24043
24676
  }[];
24044
24677
  };
24045
24678
  change_set_summary: string;
24679
+ source_roast_id?: number | string;
24680
+ source_roast_revision?: string;
24046
24681
  };
24047
24682
  } | {
24048
24683
  executionId: string;
@@ -29284,31 +29919,190 @@ declare function createParchmentClient(options: ParchmentClientOptions): {
29284
29919
  } | undefined;
29285
29920
  }, `${string}/${string}`>>;
29286
29921
  /**
29287
- * Replace the Artisan import data on one of the caller's existing roasts,
29288
- * re-deriving its curve, events, and computed metrics while preserving the
29289
- * roast's identity. Pass `ifMatch` (the roast's `last_updated`) to enable
29290
- * optimistic concurrency (409 on mismatch).
29922
+ * Create a roast profile from the Artisan file stored with one of the
29923
+ * caller's uploaded reference profiles. Only uploaded Artisan references
29924
+ * qualify: planned (generated) profiles are never recorded as roasts,
29925
+ * and a reference saved from an existing roast is refused. Requires
29926
+ * Mallard Studio plus a session, or an owner-bound API key carrying the
29927
+ * exact `roast:read` and `roast:write` scopes. The optional
29928
+ * `idempotencyKey` is payload-bound.
29291
29929
  */
29292
- replaceArtisanImport: (id: number, body: RoastArtisanImportReplaceRequest, options?: {
29293
- ifMatch?: string;
29930
+ importFromReference: (body: RoastImportFromReferenceRequest, options?: {
29931
+ idempotencyKey?: string;
29294
29932
  }) => Promise<openapi_fetch.FetchResponse<{
29295
29933
  parameters: {
29296
29934
  query?: never;
29297
29935
  header?: {
29298
- "if-match"?: string;
29299
- };
29300
- path: {
29301
- id: number;
29936
+ "idempotency-key"?: string;
29302
29937
  };
29938
+ path?: never;
29303
29939
  cookie?: never;
29304
29940
  };
29305
29941
  requestBody: {
29306
29942
  content: {
29307
- "application/json": components["schemas"]["RoastArtisanImportReplaceRequest"];
29943
+ "application/json": components["schemas"]["RoastImportFromReferenceRequest"];
29308
29944
  };
29309
29945
  };
29310
29946
  responses: {
29311
- 200: {
29947
+ 201: {
29948
+ headers: {
29949
+ "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
29950
+ "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
29951
+ "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
29952
+ "X-RateLimit-Burst-Limit": components["headers"]["X-RateLimit-Burst-Limit"];
29953
+ "X-RateLimit-Burst-Remaining": components["headers"]["X-RateLimit-Burst-Remaining"];
29954
+ "X-RateLimit-Burst-Reset": components["headers"]["X-RateLimit-Burst-Reset"];
29955
+ [name: string]: unknown;
29956
+ };
29957
+ content: {
29958
+ "application/json": components["schemas"]["RoastImportFromReferenceResponse"];
29959
+ };
29960
+ };
29961
+ 400: {
29962
+ headers: {
29963
+ "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
29964
+ "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
29965
+ "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
29966
+ "X-RateLimit-Burst-Limit": components["headers"]["X-RateLimit-Burst-Limit"];
29967
+ "X-RateLimit-Burst-Remaining": components["headers"]["X-RateLimit-Burst-Remaining"];
29968
+ "X-RateLimit-Burst-Reset": components["headers"]["X-RateLimit-Burst-Reset"];
29969
+ [name: string]: unknown;
29970
+ };
29971
+ content: {
29972
+ "application/json": components["schemas"]["ErrorResponse"];
29973
+ };
29974
+ };
29975
+ 401: {
29976
+ headers: {
29977
+ "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
29978
+ "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
29979
+ "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
29980
+ "X-RateLimit-Burst-Limit": components["headers"]["X-RateLimit-Burst-Limit"];
29981
+ "X-RateLimit-Burst-Remaining": components["headers"]["X-RateLimit-Burst-Remaining"];
29982
+ "X-RateLimit-Burst-Reset": components["headers"]["X-RateLimit-Burst-Reset"];
29983
+ [name: string]: unknown;
29984
+ };
29985
+ content: {
29986
+ "application/json": components["schemas"]["ErrorResponse"];
29987
+ };
29988
+ };
29989
+ 403: {
29990
+ headers: {
29991
+ "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
29992
+ "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
29993
+ "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
29994
+ "X-RateLimit-Burst-Limit": components["headers"]["X-RateLimit-Burst-Limit"];
29995
+ "X-RateLimit-Burst-Remaining": components["headers"]["X-RateLimit-Burst-Remaining"];
29996
+ "X-RateLimit-Burst-Reset": components["headers"]["X-RateLimit-Burst-Reset"];
29997
+ [name: string]: unknown;
29998
+ };
29999
+ content: {
30000
+ "application/json": components["schemas"]["ErrorResponse"];
30001
+ };
30002
+ };
30003
+ 404: {
30004
+ headers: {
30005
+ "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
30006
+ "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
30007
+ "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
30008
+ "X-RateLimit-Burst-Limit": components["headers"]["X-RateLimit-Burst-Limit"];
30009
+ "X-RateLimit-Burst-Remaining": components["headers"]["X-RateLimit-Burst-Remaining"];
30010
+ "X-RateLimit-Burst-Reset": components["headers"]["X-RateLimit-Burst-Reset"];
30011
+ [name: string]: unknown;
30012
+ };
30013
+ content: {
30014
+ "application/json": components["schemas"]["ErrorResponse"];
30015
+ };
30016
+ };
30017
+ 409: {
30018
+ headers: {
30019
+ "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
30020
+ "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
30021
+ "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
30022
+ "X-RateLimit-Burst-Limit": components["headers"]["X-RateLimit-Burst-Limit"];
30023
+ "X-RateLimit-Burst-Remaining": components["headers"]["X-RateLimit-Burst-Remaining"];
30024
+ "X-RateLimit-Burst-Reset": components["headers"]["X-RateLimit-Burst-Reset"];
30025
+ [name: string]: unknown;
30026
+ };
30027
+ content: {
30028
+ "application/json": components["schemas"]["ErrorResponse"];
30029
+ };
30030
+ };
30031
+ 429: {
30032
+ headers: {
30033
+ "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
30034
+ "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
30035
+ "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
30036
+ "X-RateLimit-Burst-Limit": components["headers"]["X-RateLimit-Burst-Limit"];
30037
+ "X-RateLimit-Burst-Remaining": components["headers"]["X-RateLimit-Burst-Remaining"];
30038
+ "X-RateLimit-Burst-Reset": components["headers"]["X-RateLimit-Burst-Reset"];
30039
+ "Retry-After": components["headers"]["Retry-After"];
30040
+ "X-RateLimit-Blocked-By": components["headers"]["X-RateLimit-Blocked-By"];
30041
+ [name: string]: unknown;
30042
+ };
30043
+ content: {
30044
+ "application/json": components["schemas"]["ErrorResponse"];
30045
+ };
30046
+ };
30047
+ 503: {
30048
+ headers: {
30049
+ "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
30050
+ "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
30051
+ "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
30052
+ "X-RateLimit-Burst-Limit": components["headers"]["X-RateLimit-Burst-Limit"];
30053
+ "X-RateLimit-Burst-Remaining": components["headers"]["X-RateLimit-Burst-Remaining"];
30054
+ "X-RateLimit-Burst-Reset": components["headers"]["X-RateLimit-Burst-Reset"];
30055
+ [name: string]: unknown;
30056
+ };
30057
+ content: {
30058
+ "application/json": components["schemas"]["ErrorResponse"];
30059
+ };
30060
+ };
30061
+ };
30062
+ }, {
30063
+ body: {
30064
+ referenceProfileId: string;
30065
+ referenceRevisionId: string;
30066
+ coffeeId: number;
30067
+ batchName?: string;
30068
+ roastDate?: string;
30069
+ ozIn?: number;
30070
+ ozOut?: number;
30071
+ roastNotes?: string;
30072
+ roastTargets?: string;
30073
+ };
30074
+ params: {
30075
+ header: {
30076
+ "idempotency-key": string;
30077
+ };
30078
+ } | undefined;
30079
+ }, `${string}/${string}`>>;
30080
+ /**
30081
+ * Replace the Artisan import data on one of the caller's existing roasts,
30082
+ * re-deriving its curve, events, and computed metrics while preserving the
30083
+ * roast's identity. Pass `ifMatch` (the roast's `last_updated`) to enable
30084
+ * optimistic concurrency (409 on mismatch).
30085
+ */
30086
+ replaceArtisanImport: (id: number, body: RoastArtisanImportReplaceRequest, options?: {
30087
+ ifMatch?: string;
30088
+ }) => Promise<openapi_fetch.FetchResponse<{
30089
+ parameters: {
30090
+ query?: never;
30091
+ header?: {
30092
+ "if-match"?: string;
30093
+ };
30094
+ path: {
30095
+ id: number;
30096
+ };
30097
+ cookie?: never;
30098
+ };
30099
+ requestBody: {
30100
+ content: {
30101
+ "application/json": components["schemas"]["RoastArtisanImportReplaceRequest"];
30102
+ };
30103
+ };
30104
+ responses: {
30105
+ 200: {
29312
30106
  headers: {
29313
30107
  "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
29314
30108
  "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
@@ -29803,7 +30597,9 @@ declare function createParchmentClient(options: ParchmentClientOptions): {
29803
30597
  409: {
29804
30598
  headers: {
29805
30599
  "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
29806
- "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
30600
+ "X-RateLimit-Remaining":
30601
+ /** Available exact 30-day comparisons, with no empty-origin search. */
30602
+ components["headers"]["X-RateLimit-Remaining"];
29807
30603
  "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
29808
30604
  "X-RateLimit-Burst-Limit": components["headers"]["X-RateLimit-Burst-Limit"];
29809
30605
  "X-RateLimit-Burst-Remaining": components["headers"]["X-RateLimit-Burst-Remaining"];
@@ -29833,7 +30629,7 @@ declare function createParchmentClient(options: ParchmentClientOptions): {
29833
30629
  id: string;
29834
30630
  revisionId: string;
29835
30631
  };
29836
- cookie?: never;
30632
+ cookie? /** Metadata-trend index (process/disclosure/Purveyor Score over time). */: never;
29837
30633
  };
29838
30634
  requestBody: {
29839
30635
  content: {
@@ -30303,6 +31099,13 @@ declare function createParchmentClient(options: ParchmentClientOptions): {
30303
31099
  };
30304
31100
  };
30305
31101
  }, `${string}/${string}`>>;
31102
+ /**
31103
+ * Save an executed roast as a reference. `basis: "artisan_source"`
31104
+ * copies the roast's stored Artisan file so a planned profile can be
31105
+ * built from it, and returns the reference already saved from that
31106
+ * roast's file instead of a duplicate; the default
31107
+ * `"chart_snapshot"` keeps a comparison-only chart.
31108
+ */
30306
31109
  fromRoast: (body: ReferenceProfileFromRoastRequest, idempotencyKey: string) => Promise<openapi_fetch.FetchResponse<{
30307
31110
  parameters: {
30308
31111
  query?: never;
@@ -30318,6 +31121,20 @@ declare function createParchmentClient(options: ParchmentClientOptions): {
30318
31121
  };
30319
31122
  };
30320
31123
  responses: {
31124
+ 200: {
31125
+ headers: {
31126
+ "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
31127
+ "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
31128
+ "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
31129
+ "X-RateLimit-Burst-Limit": components["headers"]["X-RateLimit-Burst-Limit"];
31130
+ "X-RateLimit-Burst-Remaining": components["headers"]["X-RateLimit-Burst-Remaining"];
31131
+ "X-RateLimit-Burst-Reset": components["headers"]["X-RateLimit-Burst-Reset"];
31132
+ [name: string]: unknown;
31133
+ };
31134
+ content: {
31135
+ "application/json": components["schemas"]["ReferenceProfileResponse"];
31136
+ };
31137
+ };
30321
31138
  201: {
30322
31139
  headers: {
30323
31140
  "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
@@ -30343,7 +31160,7 @@ declare function createParchmentClient(options: ParchmentClientOptions): {
30343
31160
  [name: string]: unknown;
30344
31161
  };
30345
31162
  content: {
30346
- "application/json": components["schemas"]["ErrorResponse"];
31163
+ "application/json": components["schemas"]["RoastSourceErrorResponse"];
30347
31164
  };
30348
31165
  };
30349
31166
  401: {
@@ -30408,6 +31225,7 @@ declare function createParchmentClient(options: ParchmentClientOptions): {
30408
31225
  body: {
30409
31226
  roastId: number;
30410
31227
  roastRevision: string;
31228
+ basis: "chart_snapshot" | "artisan_source";
30411
31229
  title?: string;
30412
31230
  notes?: string;
30413
31231
  };
@@ -30417,6 +31235,195 @@ declare function createParchmentClient(options: ParchmentClientOptions): {
30417
31235
  };
30418
31236
  };
30419
31237
  }, `${string}/${string}`>>;
31238
+ /**
31239
+ * List the caller's executed roasts whose Artisan file is on record and
31240
+ * can therefore be the base for a planned profile, newest first.
31241
+ */
31242
+ roastCandidates: (query?: ReferenceProfileRoastCandidatesQuery) => Promise<openapi_fetch.FetchResponse<{
31243
+ parameters: {
31244
+ query?: {
31245
+ limit?: number;
31246
+ };
31247
+ header?: never;
31248
+ path?: never;
31249
+ cookie?: never;
31250
+ };
31251
+ requestBody?: never;
31252
+ responses: {
31253
+ 200: {
31254
+ headers: {
31255
+ "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
31256
+ "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
31257
+ "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
31258
+ "X-RateLimit-Burst-Limit": components["headers"]["X-RateLimit-Burst-Limit"];
31259
+ "X-RateLimit-Burst-Remaining": components["headers"]["X-RateLimit-Burst-Remaining"];
31260
+ "X-RateLimit-Burst-Reset": components["headers"]["X-RateLimit-Burst-Reset"];
31261
+ [name: string]: unknown;
31262
+ };
31263
+ content: {
31264
+ "application/json": components["schemas"]["ReferenceProfileRoastCandidatesResponse"];
31265
+ };
31266
+ };
31267
+ 401: {
31268
+ headers: {
31269
+ "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
31270
+ "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
31271
+ "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
31272
+ "X-RateLimit-Burst-Limit": components["headers"]["X-RateLimit-Burst-Limit"];
31273
+ "X-RateLimit-Burst-Remaining": components["headers"]["X-RateLimit-Burst-Remaining"];
31274
+ "X-RateLimit-Burst-Reset": components["headers"]["X-RateLimit-Burst-Reset"];
31275
+ [name: string]: unknown;
31276
+ };
31277
+ content: {
31278
+ "application/json": components["schemas"]["ErrorResponse"];
31279
+ };
31280
+ };
31281
+ 403: {
31282
+ headers: {
31283
+ "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
31284
+ "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
31285
+ "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
31286
+ "X-RateLimit-Burst-Limit": components["headers"]["X-RateLimit-Burst-Limit"];
31287
+ "X-RateLimit-Burst-Remaining": components["headers"]["X-RateLimit-Burst-Remaining"];
31288
+ "X-RateLimit-Burst-Reset": components["headers"]["X-RateLimit-Burst-Reset"];
31289
+ [name: string]: unknown;
31290
+ };
31291
+ content: {
31292
+ "application/json": components["schemas"]["ErrorResponse"];
31293
+ };
31294
+ };
31295
+ 429: components["responses"]["ApiRateLimitExceeded"];
31296
+ };
31297
+ }, {
31298
+ params: {
31299
+ query: {
31300
+ limit?: number;
31301
+ } | undefined;
31302
+ };
31303
+ }, `${string}/${string}`>>;
31304
+ /**
31305
+ * Preview a planned profile built directly on an executed roast's stored
31306
+ * Artisan file. Read-only: nothing is saved and the roast is unchanged.
31307
+ */
31308
+ previewFromRoast: (body: ReferenceProfileRoastGenerationRequest) => Promise<openapi_fetch.FetchResponse<{
31309
+ parameters: {
31310
+ query?: never;
31311
+ header?: never;
31312
+ path?: never;
31313
+ cookie?: never;
31314
+ };
31315
+ requestBody: {
31316
+ content: {
31317
+ "application/json": components["schemas"]["ReferenceProfileRoastGenerationRequest"];
31318
+ };
31319
+ };
31320
+ responses: {
31321
+ 200: {
31322
+ headers: {
31323
+ "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
31324
+ "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
31325
+ "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
31326
+ "X-RateLimit-Burst-Limit": components["headers"]["X-RateLimit-Burst-Limit"];
31327
+ "X-RateLimit-Burst-Remaining": components["headers"]["X-RateLimit-Burst-Remaining"];
31328
+ "X-RateLimit-Burst-Reset": components["headers"]["X-RateLimit-Burst-Reset"];
31329
+ [name: string]: unknown;
31330
+ };
31331
+ content: {
31332
+ "application/json": components["schemas"]["ReferenceProfileRoastGenerationPreviewResponse"];
31333
+ };
31334
+ };
31335
+ 400: {
31336
+ headers: {
31337
+ "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
31338
+ "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
31339
+ "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
31340
+ "X-RateLimit-Burst-Limit": components["headers"]["X-RateLimit-Burst-Limit"];
31341
+ "X-RateLimit-Burst-Remaining": components["headers"]["X-RateLimit-Burst-Remaining"];
31342
+ "X-RateLimit-Burst-Reset": components["headers"]["X-RateLimit-Burst-Reset"];
31343
+ [name: string]: unknown;
31344
+ };
31345
+ content: {
31346
+ "application/json": components["schemas"]["RoastSourceErrorResponse"];
31347
+ };
31348
+ };
31349
+ 401: {
31350
+ headers: {
31351
+ "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
31352
+ "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
31353
+ "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
31354
+ "X-RateLimit-Burst-Limit": components["headers"]["X-RateLimit-Burst-Limit"];
31355
+ "X-RateLimit-Burst-Remaining": components["headers"]["X-RateLimit-Burst-Remaining"];
31356
+ "X-RateLimit-Burst-Reset": components["headers"]["X-RateLimit-Burst-Reset"];
31357
+ [name: string]: unknown;
31358
+ };
31359
+ content: {
31360
+ "application/json": components["schemas"]["ErrorResponse"];
31361
+ };
31362
+ };
31363
+ 403: {
31364
+ headers: {
31365
+ "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
31366
+ "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
31367
+ "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
31368
+ "X-RateLimit-Burst-Limit": components["headers"]["X-RateLimit-Burst-Limit"];
31369
+ "X-RateLimit-Burst-Remaining": components["headers"]["X-RateLimit-Burst-Remaining"];
31370
+ "X-RateLimit-Burst-Reset": components["headers"]["X-RateLimit-Burst-Reset"];
31371
+ [name: string]: unknown;
31372
+ };
31373
+ content: {
31374
+ "application/json": components["schemas"]["ErrorResponse"];
31375
+ };
31376
+ };
31377
+ 404: {
31378
+ headers: {
31379
+ "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
31380
+ "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
31381
+ "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
31382
+ "X-RateLimit-Burst-Limit": components["headers"]["X-RateLimit-Burst-Limit"];
31383
+ "X-RateLimit-Burst-Remaining": components["headers"]["X-RateLimit-Burst-Remaining"];
31384
+ "X-RateLimit-Burst-Reset": components["headers"]["X-RateLimit-Burst-Reset"];
31385
+ [name: string]: unknown;
31386
+ };
31387
+ content: {
31388
+ "application/json": components["schemas"]["ErrorResponse"];
31389
+ };
31390
+ };
31391
+ 409: {
31392
+ headers: {
31393
+ "X-RateLimit-Limit": components["headers"]["X-RateLimit-Limit"];
31394
+ "X-RateLimit-Remaining": components["headers"]["X-RateLimit-Remaining"];
31395
+ "X-RateLimit-Reset": components["headers"]["X-RateLimit-Reset"];
31396
+ "X-RateLimit-Burst-Limit": components["headers"]["X-RateLimit-Burst-Limit"];
31397
+ "X-RateLimit-Burst-Remaining": components["headers"]["X-RateLimit-Burst-Remaining"];
31398
+ "X-RateLimit-Burst-Reset": components["headers"]["X-RateLimit-Burst-Reset"];
31399
+ [name: string]: unknown;
31400
+ };
31401
+ content: {
31402
+ "application/json": components["schemas"]["ErrorResponse"];
31403
+ };
31404
+ };
31405
+ 429: components["responses"]["ApiRateLimitExceeded"];
31406
+ };
31407
+ }, {
31408
+ body: {
31409
+ title: string;
31410
+ notes?: string;
31411
+ userGoal?: string;
31412
+ modelRecommendation?: string;
31413
+ userEdits?: string;
31414
+ changes: {
31415
+ temperatureAdjustments: {
31416
+ kind: "bean_temperature" | "environmental_temperature";
31417
+ startMilliseconds: number;
31418
+ endMilliseconds: number;
31419
+ delta: number;
31420
+ }[];
31421
+ };
31422
+ } & {
31423
+ roastId: number;
31424
+ roastRevision: string;
31425
+ };
31426
+ }, `${string}/${string}`>>;
30420
31427
  update: (id: string, body: ReferenceProfileUpdateRequest) => Promise<openapi_fetch.FetchResponse<{
30421
31428
  parameters: {
30422
31429
  query?: never;
@@ -30582,9 +31589,7 @@ declare function createParchmentClient(options: ParchmentClientOptions): {
30582
31589
  [name: string]: unknown;
30583
31590
  };
30584
31591
  content: {
30585
- "application/json":
30586
- /** Request body for {@link ParchmentClient.apiKeys.create}. */
30587
- components["schemas"]["ErrorResponse"];
31592
+ "application/json": components["schemas"]["ErrorResponse"];
30588
31593
  };
30589
31594
  };
30590
31595
  403: {
@@ -31788,7 +32793,7 @@ type ParchmentClientMethod = MethodPaths<Omit<ParchmentClient, "raw">>;
31788
32793
  * SDK (such as the CLI) can import this list to prove they cover everything
31789
32794
  * the web agent can do.
31790
32795
  */
31791
- declare const CHAT_AGENT_CAPABILITIES: readonly ["me", "catalog.list", "catalog.facets", "catalog.rank", "catalog.suppliers", "catalog.similar", "catalog.compare", "catalog.grades", "catalog.priceHistory", "inventory.list", "roasts.list", "roasts.get", "roasts.chartData", "referenceProfiles.list", "referenceProfiles.get", "referenceProfiles.chart", "referenceProfiles.compare", "referenceProfiles.preview", "tasting.get", "priceIndex.list", "priceIndex.stats", "priceIndex.comparisons", "priceIndex.comparison", "priceIndex.history", "market.signals", "market.metadataIndex", "market.overview", "market.evidence"];
32796
+ declare const CHAT_AGENT_CAPABILITIES: readonly ["me", "catalog.list", "catalog.facets", "catalog.rank", "catalog.suppliers", "catalog.similar", "catalog.compare", "catalog.grades", "catalog.priceHistory", "inventory.list", "roasts.list", "roasts.get", "roasts.chartData", "referenceProfiles.list", "referenceProfiles.get", "referenceProfiles.chart", "referenceProfiles.compare", "referenceProfiles.preview", "referenceProfiles.roastCandidates", "referenceProfiles.previewFromRoast", "tasting.get", "priceIndex.list", "priceIndex.stats", "priceIndex.comparisons", "priceIndex.comparison", "priceIndex.history", "market.signals", "market.metadataIndex", "market.overview", "market.evidence"];
31792
32797
  type ChatAgentCapability = (typeof CHAT_AGENT_CAPABILITIES)[number];
31793
32798
  /**
31794
32799
  * Writes the web agent can propose. The agent never writes directly: it