@purveyors/cli 0.33.1 → 0.33.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/README.md +81 -2
  2. package/dist/commands/context.d.ts.map +1 -1
  3. package/dist/commands/context.js +2 -0
  4. package/dist/commands/context.js.map +1 -1
  5. package/dist/commands/manifest.d.ts.map +1 -1
  6. package/dist/commands/manifest.js +2 -0
  7. package/dist/commands/manifest.js.map +1 -1
  8. package/dist/commands/reference-profile.d.ts +4 -0
  9. package/dist/commands/reference-profile.d.ts.map +1 -0
  10. package/dist/commands/reference-profile.js +157 -0
  11. package/dist/commands/reference-profile.js.map +1 -0
  12. package/dist/lib/cherry.d.ts +2 -16
  13. package/dist/lib/cherry.d.ts.map +1 -1
  14. package/dist/lib/cherry.js +19 -5
  15. package/dist/lib/cherry.js.map +1 -1
  16. package/dist/lib/interactive/watch.d.ts +2 -3
  17. package/dist/lib/interactive/watch.d.ts.map +1 -1
  18. package/dist/lib/interactive/watch.js +4 -26
  19. package/dist/lib/interactive/watch.js.map +1 -1
  20. package/dist/lib/manifest.d.ts.map +1 -1
  21. package/dist/lib/manifest.js +214 -2
  22. package/dist/lib/manifest.js.map +1 -1
  23. package/dist/lib/market.d.ts +6 -2
  24. package/dist/lib/market.d.ts.map +1 -1
  25. package/dist/lib/reference-profiles.d.ts +102 -0
  26. package/dist/lib/reference-profiles.d.ts.map +1 -0
  27. package/dist/lib/reference-profiles.js +145 -0
  28. package/dist/lib/reference-profiles.js.map +1 -0
  29. package/dist/lib/roast.d.ts +29 -60
  30. package/dist/lib/roast.d.ts.map +1 -1
  31. package/dist/lib/roast.js.map +1 -1
  32. package/dist/program.d.ts.map +1 -1
  33. package/dist/program.js +13 -0
  34. package/dist/program.js.map +1 -1
  35. package/package.json +2 -2
  36. package/dist/lib/artisan/parser.d.ts +0 -19
  37. package/dist/lib/artisan/parser.d.ts.map +0 -1
  38. package/dist/lib/artisan/parser.js +0 -376
  39. package/dist/lib/artisan/parser.js.map +0 -1
  40. package/dist/lib/artisan/temperature.d.ts +0 -52
  41. package/dist/lib/artisan/temperature.d.ts.map +0 -1
  42. package/dist/lib/artisan/temperature.js +0 -101
  43. package/dist/lib/artisan/temperature.js.map +0 -1
  44. package/dist/lib/artisan/types.d.ts +0 -195
  45. package/dist/lib/artisan/types.d.ts.map +0 -1
  46. package/dist/lib/artisan/types.js +0 -35
  47. package/dist/lib/artisan/types.js.map +0 -1
  48. package/dist/lib/artisan/validator.d.ts +0 -14
  49. package/dist/lib/artisan/validator.d.ts.map +0 -1
  50. package/dist/lib/artisan/validator.js +0 -228
  51. package/dist/lib/artisan/validator.js.map +0 -1
package/README.md CHANGED
@@ -145,11 +145,12 @@ Remote data commands require a valid owner-bound API key with the required scope
145
145
  - `catalog search` structured process filters require the `member` role
146
146
  - `market` has public teaser slices for `signals --summary`, unfiltered retail `stats`, and process/retail/month `metadata`; all filtered or non-public slices require Parchment Intelligence access enforced server-side
147
147
  - `price-index`, `procurement`, `inventory`, `roast`, `sales`, and `tasting` require the `member` role
148
+ - `reference-profile` requires a `member` credential plus Studio access, enforced server-side by Parchment
148
149
 
149
150
  `purvey` uses Google OAuth through purveyors.io.
150
151
 
151
152
  Set `PARCHMENT_API_KEY` (or `PURVEYORS_API_KEY`) to authenticate SDK-backed catalog,
152
- inventory, roast, sales, tasting-read, market, price-index, and procurement operations
153
+ inventory, roast, reference-profile, sales, tasting-read, market, price-index, and procurement operations
153
154
  without using the API key created by `purvey auth login`. Environment credentials take precedence.
154
155
 
155
156
  Interactive login:
@@ -192,6 +193,8 @@ Credentials are stored at `~/.config/purvey/credentials.json`.
192
193
  | `viewer` | `catalog search`, `catalog get`, `catalog stats`, excluding structured process filters |
193
194
  | `member` | All viewer commands, `catalog similar`, structured process filters on `catalog search`, plus `price-index`, `procurement`, `inventory`, `roast`, `sales`, and `tasting` through the scoped key created by `purvey auth login` |
194
195
 
196
+ The `reference-profile` commands also require Studio access; the API enforces this entitlement.
197
+
195
198
  Market Index teaser slices are public. Filtered `market signals`, origin/process/wholesale `market stats`, and non-public `market metadata` slices require Parchment Intelligence access; API-key denial is enforced by the canonical API. The stored login key carries `catalog:read`, which is also the canonical read scope for Market Index, Price Index, and procurement.
196
199
 
197
200
  `auth`, `config`, `context`, and `manifest` remain available without pre-existing credentials.
@@ -669,6 +672,65 @@ Notes:
669
672
  - `roast watch --auto-match` uses the `@purveyors/cli/cherry` helper to send roast metadata and the current stocked-inventory candidates to the canonical Parchment `POST /v1/roasts/classify` endpoint via `@purveyors/sdk`; it never calls an AI provider directly.
670
673
  - `roast watch --commit-mode` defaults to `batch`.
671
674
 
675
+ ### reference-profile
676
+
677
+ - `purvey reference-profile list [--include-archived]`
678
+ - `purvey reference-profile get <profile-id>`
679
+ - `purvey reference-profile chart <profile-id> <revision-id>`
680
+ - `purvey reference-profile import <file>`
681
+ - `purvey reference-profile preview <profile-id> <revision-id> --request <file>`
682
+ - `purvey reference-profile save <profile-id> <revision-id> --request <file>`
683
+ - `purvey reference-profile export <profile-id> <revision-id> --output <file>`
684
+
685
+ Reference-profile commands use the canonical Parchment API through `@purveyors/sdk`. They
686
+ require a member credential and Studio access, which Parchment enforces server-side.
687
+
688
+ `reference-profile import` uploads an Artisan `.alog` or another file accepted by the
689
+ canonical importer. Parchment owns parsing and private source retention. It creates a
690
+ reference profile, not an executed roast. `get` returns its current revision; pass
691
+ `data.currentRevision.id` to `chart`, `preview`, or `save`.
692
+
693
+ `preview` and `save` take the same JSON request file. The first supported edits are
694
+ explicit bounded bean-temperature or environmental-temperature adjustments over a time
695
+ interval in milliseconds. Each request supports at most 12 adjustments; intervals must
696
+ be ordered and each nonzero `delta` is bounded from -20 to 20. For example:
697
+
698
+ ```json
699
+ {
700
+ "title": "Slightly later development",
701
+ "notes": "Small next-batch adjustment",
702
+ "changes": {
703
+ "temperatureAdjustments": [
704
+ {
705
+ "kind": "bean_temperature",
706
+ "startMilliseconds": 300000,
707
+ "endMilliseconds": 420000,
708
+ "delta": 3
709
+ }
710
+ ]
711
+ }
712
+ }
713
+ ```
714
+
715
+ Example flow:
716
+
717
+ Replace the sample UUIDs below with the profile and revision IDs returned by your commands.
718
+
719
+ ```bash
720
+ purvey reference-profile import ~/artisan/ethiopia.alog --title "Ethiopia baseline" --pretty
721
+ purvey reference-profile get 5ea1af6f-234c-43a9-9bf8-5678dd24f854 --pretty
722
+ purvey reference-profile preview 5ea1af6f-234c-43a9-9bf8-5678dd24f854 8d2c41e0-7b9a-4f3e-a6d1-2c9e5f07b3a4 --request changes.json --pretty
723
+ purvey reference-profile save 5ea1af6f-234c-43a9-9bf8-5678dd24f854 8d2c41e0-7b9a-4f3e-a6d1-2c9e5f07b3a4 --request changes.json --pretty
724
+ purvey reference-profile export 0b7e9f52-3c61-4d8a-9e24-6f1a8c3d5b90 c43a1d7e-95b2-4e06-8f7c-1d2b3a4e5f68 --output ~/artisan/next-batch.alog
725
+ ```
726
+
727
+ Writes generate a new idempotency key per invocation. Pass `--idempotency-key <key>` on
728
+ `import` or `save` and reuse that key to safely retry the same request. `export` requires a
729
+ saved generated revision, writes the unsigned `.alog` plan locally, and emits a JSON
730
+ receipt; it refuses to overwrite an existing file unless `--force` is passed. A generated
731
+ profile is never executed roast history, and this CLI does not claim verified Artisan 4.2
732
+ playback compatibility.
733
+
672
734
  ### sales
673
735
 
674
736
  - `purvey sales list`
@@ -852,6 +914,21 @@ purvey roast watch --resume
852
914
 
853
915
  Watch mode runs until Ctrl+C or SIGTERM. On shutdown it waits for active imports, commits queued batch-mode roasts, prints the verification summary, and leaves session state available for `--resume`.
854
916
 
917
+ ### Plan an Artisan reference
918
+
919
+ Replace the sample UUIDs with IDs returned by your own import and save commands.
920
+
921
+ ```bash
922
+ purvey reference-profile import ~/artisan/ethiopia.alog --title "Ethiopia baseline"
923
+ purvey reference-profile get 5ea1af6f-234c-43a9-9bf8-5678dd24f854 --pretty
924
+ purvey reference-profile preview 5ea1af6f-234c-43a9-9bf8-5678dd24f854 8d2c41e0-7b9a-4f3e-a6d1-2c9e5f07b3a4 --request changes.json --pretty
925
+ purvey reference-profile save 5ea1af6f-234c-43a9-9bf8-5678dd24f854 8d2c41e0-7b9a-4f3e-a6d1-2c9e5f07b3a4 --request changes.json
926
+ purvey reference-profile export 0b7e9f52-3c61-4d8a-9e24-6f1a8c3d5b90 c43a1d7e-95b2-4e06-8f7c-1d2b3a4e5f68 --output ~/artisan/next-batch.alog
927
+ ```
928
+
929
+ Review the preview before saving. The export is an unsigned plan; Artisan 4.2 playback
930
+ compatibility has not yet been established.
931
+
855
932
  ### Export records for spreadsheets
856
933
 
857
934
  ```bash
@@ -878,13 +955,15 @@ Use the right ID for the right command.
878
955
  - `roast_id`: `roast_data` rows; used by `roast get/delete`, `sales record --roast-id`, `roast list --roast-id`
879
956
  - `sales record` also supports resolving a roast from `inventory id` plus `--batch-name`; because sales retain inventory + batch rather than roast ID, duplicate batch names on one inventory item are rejected
880
957
  - `sale id`: `coffee_sales` rows; used by `sales update/delete`
958
+ - `reference_profile_id`: owner-scoped Studio profile UUID; used by `reference-profile get/chart/preview/save/export`
959
+ - `reference_revision_id`: immutable revision UUID; used by `reference-profile chart/preview/save/export`
881
960
 
882
961
  ## Environment variables
883
962
 
884
963
  - `PURVEYORS_BASE_URL`: override the Purveyors web base URL
885
964
  - `PURVEYORS_API_KEY`: explicit API-key override for canonical Parchment commands
886
965
  - `PARCHMENT_API_KEY`: preferred API-key variable for SDK-backed Parchment commands; also accepted for API-backed proof and paid-tier similarity paths
887
- - `PARCHMENT_API_BASE_URL`: override the SDK-backed Parchment API base URL, including `market`, `price-index`, `procurement`, and roast auto-classification requests
966
+ - `PARCHMENT_API_BASE_URL`: override the SDK-backed Parchment API base URL, including `market`, `price-index`, `procurement`, `reference-profile`, and roast auto-classification requests
888
967
  - `PURVEY_DEBUG`: enable verbose error output
889
968
 
890
969
  ## For AI agents
@@ -1 +1 @@
1
- {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/commands/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,wBAAgB,mBAAmB,IAAI,OAAO,CAoD7C"}
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/commands/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,wBAAgB,mBAAmB,IAAI,OAAO,CAsD7C"}
@@ -12,6 +12,7 @@ Default output is the dense human-readable operator reference.
12
12
  Preferred machine contract: \`purvey manifest\`.
13
13
  Use --json or --pretty only when an existing \`purvey context\` caller needs manifest parity.
14
14
  Use \`@purveyors/cli/manifest\` for the same contract inside Node.js or agent runtimes.
15
+ Studio reference workflows are listed under \`reference-profile\` in the manifest; they require Studio access.
15
16
 
16
17
  Examples:
17
18
  purvey context
@@ -20,6 +21,7 @@ Examples:
20
21
  purvey context --pretty
21
22
  purvey context --json > cli-manifest.json
22
23
  purvey manifest
24
+ purvey reference-profile --help
23
25
  `)
24
26
  .action(withErrorHandling(async (opts, cmd) => {
25
27
  const globalOpts = cmd.optsWithGlobals();
@@ -1 +1 @@
1
- {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/commands/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG9C,MAAM,UAAU,mBAAmB;IACjC,OAAO,IAAI,OAAO,CAAC,SAAS,CAAC;SAC1B,WAAW,CACV,kGAAkG,CACnG;SACA,MAAM,CAAC,QAAQ,EAAE,6DAA6D,CAAC;SAC/E,MAAM,CAAC,UAAU,EAAE,8DAA8D,CAAC;SAClF,WAAW,CACV,OAAO,EACP;;;;;;;;;;;;;CAaL,CACI;SACA,MAAM,CACL,iBAAiB,CAAC,KAAK,EAAE,IAA6B,EAAE,GAAY,EAAE,EAAE;QACtE,MAAM,UAAU,GAAG,GAAG,CAAC,eAAe,EAAmB,CAAC;QAC1D,MAAM,QAAQ,GAAG,cAAc,EAAE,CAAC;QAClC,MAAM,SAAS,GACb,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;YAClB,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC;YACpB,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC;YACxB,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QAE7B,IAAI,UAAU,CAAC,GAAG,EAAE,CAAC;YACnB,MAAM,IAAI,UAAU,CAClB,kBAAkB,EAClB,4EAA4E,CAC7E,CAAC;QACJ,CAAC;QAED,IAAI,SAAS,EAAE,CAAC;YACd,UAAU,CAAC,QAAQ,EAAE;gBACnB,IAAI,EAAE,IAAI;gBACV,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC;aAC3D,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC3C,CAAC,CAAC,CACH,CAAC;AACN,CAAC"}
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/commands/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG9C,MAAM,UAAU,mBAAmB;IACjC,OAAO,IAAI,OAAO,CAAC,SAAS,CAAC;SAC1B,WAAW,CACV,kGAAkG,CACnG;SACA,MAAM,CAAC,QAAQ,EAAE,6DAA6D,CAAC;SAC/E,MAAM,CAAC,UAAU,EAAE,8DAA8D,CAAC;SAClF,WAAW,CACV,OAAO,EACP;;;;;;;;;;;;;;;CAeL,CACI;SACA,MAAM,CACL,iBAAiB,CAAC,KAAK,EAAE,IAA6B,EAAE,GAAY,EAAE,EAAE;QACtE,MAAM,UAAU,GAAG,GAAG,CAAC,eAAe,EAAmB,CAAC;QAC1D,MAAM,QAAQ,GAAG,cAAc,EAAE,CAAC;QAClC,MAAM,SAAS,GACb,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;YAClB,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC;YACpB,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC;YACxB,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QAE7B,IAAI,UAAU,CAAC,GAAG,EAAE,CAAC;YACnB,MAAM,IAAI,UAAU,CAClB,kBAAkB,EAClB,4EAA4E,CAC7E,CAAC;QACJ,CAAC;QAED,IAAI,SAAS,EAAE,CAAC;YACd,UAAU,CAAC,QAAQ,EAAE;gBACnB,IAAI,EAAE,IAAI;gBACV,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC;aAC3D,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC3C,CAAC,CAAC,CACH,CAAC;AACN,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/commands/manifest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,wBAAgB,oBAAoB,IAAI,OAAO,CAsC9C"}
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/commands/manifest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,wBAAgB,oBAAoB,IAAI,OAAO,CAwC9C"}
@@ -10,12 +10,14 @@ export function buildManifestCommand() {
10
10
  .addHelpText('after', `
11
11
  Preferred machine-readable entrypoint for shells, scripts, and agents.
12
12
  Use \`purvey context --json\` only for compatibility with existing context-based callers.
13
+ The \`reference-profile\` command group describes the SDK-backed Studio Artisan plan workflow.
13
14
 
14
15
  Examples:
15
16
  purvey manifest
16
17
  purvey manifest --pretty
17
18
  purvey manifest > cli-manifest.json
18
19
  purvey manifest | jq '.commandGroups[].name'
20
+ purvey manifest | jq '.commandGroups[] | select(.name == "reference-profile")'
19
21
  node --input-type=module -e "import { getCliManifest } from '@purveyors/cli/manifest'; console.log(JSON.stringify(getCliManifest()))"
20
22
  `)
21
23
  .action(withErrorHandling(async (opts, cmd) => {
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/commands/manifest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG9C,MAAM,UAAU,oBAAoB;IAClC,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC;SAC3B,WAAW,CACV,0FAA0F,CAC3F;SACA,MAAM,CAAC,QAAQ,EAAE,6CAA6C,CAAC;SAC/D,MAAM,CAAC,UAAU,EAAE,oCAAoC,CAAC;SACxD,WAAW,CACV,OAAO,EACP;;;;;;;;;;CAUL,CACI;SACA,MAAM,CACL,iBAAiB,CAAC,KAAK,EAAE,IAA6B,EAAE,GAAY,EAAE,EAAE;QACtE,MAAM,UAAU,GAAG,GAAG,CAAC,eAAe,EAAmB,CAAC;QAE1D,IAAI,UAAU,CAAC,GAAG,EAAE,CAAC;YACnB,MAAM,IAAI,UAAU,CAClB,kBAAkB,EAClB,sEAAsE,CACvE,CAAC;QACJ,CAAC;QAED,UAAU,CAAC,cAAc,EAAE,EAAE;YAC3B,IAAI,EAAE,IAAI;YACV,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC;SAC3D,CAAC,CAAC;IACL,CAAC,CAAC,CACH,CAAC;AACN,CAAC"}
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/commands/manifest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG9C,MAAM,UAAU,oBAAoB;IAClC,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC;SAC3B,WAAW,CACV,0FAA0F,CAC3F;SACA,MAAM,CAAC,QAAQ,EAAE,6CAA6C,CAAC;SAC/D,MAAM,CAAC,UAAU,EAAE,oCAAoC,CAAC;SACxD,WAAW,CACV,OAAO,EACP;;;;;;;;;;;;CAYL,CACI;SACA,MAAM,CACL,iBAAiB,CAAC,KAAK,EAAE,IAA6B,EAAE,GAAY,EAAE,EAAE;QACtE,MAAM,UAAU,GAAG,GAAG,CAAC,eAAe,EAAmB,CAAC;QAE1D,IAAI,UAAU,CAAC,GAAG,EAAE,CAAC;YACnB,MAAM,IAAI,UAAU,CAClB,kBAAkB,EAClB,sEAAsE,CACvE,CAAC;QACJ,CAAC;QAED,UAAU,CAAC,cAAc,EAAE,EAAE;YAC3B,IAAI,EAAE,IAAI;YACV,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC;SAC3D,CAAC,CAAC;IACL,CAAC,CAAC,CACH,CAAC;AACN,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { Command } from 'commander';
2
+ /** `purvey reference-profile` — owner-scoped Studio plans through Parchment's SDK. */
3
+ export declare function buildReferenceProfileCommand(): Command;
4
+ //# sourceMappingURL=reference-profile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reference-profile.d.ts","sourceRoot":"","sources":["../../src/commands/reference-profile.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA0BpC,sFAAsF;AACtF,wBAAgB,4BAA4B,IAAI,OAAO,CAuPtD"}
@@ -0,0 +1,157 @@
1
+ import { basename } from 'node:path';
2
+ import { readFile, stat } from 'node:fs/promises';
3
+ import { Command } from 'commander';
4
+ import { PrvrsError, withErrorHandling } from '../lib/errors.js';
5
+ import { exportGeneratedReferenceProfile, getReferenceProfile, getReferenceProfileChart, importReferenceProfile, listReferenceProfiles, parseReferenceProfileImportRequest, previewReferenceProfile, readReferenceProfileGenerationRequest, REFERENCE_PROFILE_SOURCE_MAX_BYTES, saveGeneratedReferenceProfile, writeGeneratedReferenceFile, } from '../lib/reference-profiles.js';
6
+ import { normalizePathInput } from '../lib/path-input.js';
7
+ import { outputData } from '../lib/output.js';
8
+ function idempotencyKeyOption(command, description) {
9
+ return command.option('--idempotency-key <key>', `${description}; a new UUID is generated when omitted`);
10
+ }
11
+ /** `purvey reference-profile` — owner-scoped Studio plans through Parchment's SDK. */
12
+ export function buildReferenceProfileCommand() {
13
+ const referenceProfile = new Command('reference-profile').description('Preview, save, and export Studio Artisan reference plans through Parchment');
14
+ referenceProfile
15
+ .command('list')
16
+ .description('List your Studio reference profiles')
17
+ .option('--include-archived', 'Include archived reference profiles')
18
+ .addHelpText('after', `
19
+ Examples:
20
+ purvey reference-profile list --pretty
21
+ purvey reference-profile list --include-archived --json
22
+
23
+ Notes:
24
+ Requires a member credential and Studio access; entitlement is enforced by Parchment.`)
25
+ .action(withErrorHandling(async (opts, cmd) => {
26
+ const globalOpts = cmd.optsWithGlobals();
27
+ const data = await listReferenceProfiles(Boolean(opts.includeArchived));
28
+ outputData(data, globalOpts);
29
+ }));
30
+ referenceProfile
31
+ .command('get <profile-id>')
32
+ .description('Get one reference profile and its current revision')
33
+ .addHelpText('after', `
34
+ Example:
35
+ purvey reference-profile get 5ea1af6f-234c-43a9-9bf8-5678dd24f854 --pretty
36
+
37
+ Use data.currentRevision.id as the revision id for chart, preview, and save.`)
38
+ .action(withErrorHandling(async (profileId, _opts, cmd) => {
39
+ const globalOpts = cmd.optsWithGlobals();
40
+ const data = await getReferenceProfile(profileId);
41
+ outputData(data, globalOpts);
42
+ }));
43
+ referenceProfile
44
+ .command('chart <profile-id> <revision-id>')
45
+ .description('Get the typed Artisan chart for a reference revision')
46
+ .addHelpText('after', `
47
+ Example:
48
+ purvey reference-profile chart 5ea1af6f-234c-43a9-9bf8-5678dd24f854 8d2c41e0-7b9a-4f3e-a6d1-2c9e5f07b3a4 --pretty`)
49
+ .action(withErrorHandling(async (profileId, revisionId, _opts, cmd) => {
50
+ const globalOpts = cmd.optsWithGlobals();
51
+ const data = await getReferenceProfileChart(profileId, revisionId);
52
+ outputData(data, globalOpts);
53
+ }));
54
+ const importCommand = referenceProfile
55
+ .command('import <file>')
56
+ .description('Upload an Artisan reference file as a private Studio profile')
57
+ .option('--title <text>', 'Title for the reference profile')
58
+ .option('--notes <text>', 'Notes about the reference profile')
59
+ .addHelpText('after', `
60
+ Examples:
61
+ purvey reference-profile import ~/artisan/ethiopia.alog --title "Ethiopia baseline" --pretty
62
+ purvey reference-profile import ~/artisan/ethiopia.alog --idempotency-key 3f6c2a1b-8e4d-4b7a-9c05-7e1f2d3a4b5c --json
63
+
64
+ Notes:
65
+ Parchment parses and retains the private source (up to 10,000,000 bytes); this command does not create roast history.
66
+ Reuse an explicit idempotency key to safely retry the same upload.`);
67
+ idempotencyKeyOption(importCommand, 'Stable key for safe retries');
68
+ importCommand.action(withErrorHandling(async (inputPath, opts, cmd) => {
69
+ const globalOpts = cmd.optsWithGlobals();
70
+ const filePath = normalizePathInput(inputPath);
71
+ if (!filePath) {
72
+ throw new PrvrsError('INVALID_ARGUMENT', 'The Artisan reference file path cannot be blank.');
73
+ }
74
+ const fileInfo = await stat(filePath);
75
+ if (!fileInfo.isFile()) {
76
+ throw new PrvrsError('INVALID_ARGUMENT', 'The Artisan reference path must be a file.');
77
+ }
78
+ if (fileInfo.size === 0 || fileInfo.size > REFERENCE_PROFILE_SOURCE_MAX_BYTES) {
79
+ throw new PrvrsError('INVALID_ARGUMENT', `The Artisan reference must be between 1 and ${REFERENCE_PROFILE_SOURCE_MAX_BYTES} bytes.`);
80
+ }
81
+ const fileContent = await readFile(filePath, 'utf8');
82
+ const body = parseReferenceProfileImportRequest({
83
+ ...(opts.title !== undefined ? { title: String(opts.title) } : {}),
84
+ ...(opts.notes !== undefined ? { notes: String(opts.notes) } : {}),
85
+ fileName: basename(filePath),
86
+ fileContent,
87
+ fileSize: Buffer.byteLength(fileContent, 'utf8'),
88
+ });
89
+ const data = await importReferenceProfile(body, opts.idempotencyKey ? String(opts.idempotencyKey) : undefined);
90
+ outputData(data, globalOpts);
91
+ }));
92
+ const previewCommand = referenceProfile
93
+ .command('preview <profile-id> <revision-id>')
94
+ .description('Preview a bounded set of temperature adjustments without saving')
95
+ .requiredOption('--request <file>', 'JSON file with a title and bounded temperature adjustments')
96
+ .addHelpText('after', `
97
+ Example:
98
+ purvey reference-profile preview 5ea1af6f-234c-43a9-9bf8-5678dd24f854 8d2c41e0-7b9a-4f3e-a6d1-2c9e5f07b3a4 --request changes.json --pretty
99
+
100
+ The request file is also the exact body accepted by save. Parchment recalculates from the
101
+ immutable parent; preview never changes or stores the source.`);
102
+ previewCommand.action(withErrorHandling(async (profileId, revisionId, opts, cmd) => {
103
+ const globalOpts = cmd.optsWithGlobals();
104
+ const request = await readReferenceProfileGenerationRequest(String(opts.request));
105
+ const data = await previewReferenceProfile(profileId, revisionId, request);
106
+ outputData(data, globalOpts);
107
+ }));
108
+ const saveCommand = referenceProfile
109
+ .command('save <profile-id> <revision-id>')
110
+ .description('Save the previewed changes as a new immutable generated reference')
111
+ .requiredOption('--request <file>', 'JSON file with a title and bounded temperature adjustments');
112
+ idempotencyKeyOption(saveCommand, 'Stable key for safe retries');
113
+ saveCommand.addHelpText('after', `
114
+ Example:
115
+ purvey reference-profile save 5ea1af6f-234c-43a9-9bf8-5678dd24f854 8d2c41e0-7b9a-4f3e-a6d1-2c9e5f07b3a4 --request changes.json --pretty
116
+
117
+ Notes:
118
+ Omit --idempotency-key to generate a new key for this call. Reuse an explicit key to replay a retry.
119
+ A generated reference is a plan, not executed roast history.`);
120
+ saveCommand.action(withErrorHandling(async (profileId, revisionId, opts, cmd) => {
121
+ const globalOpts = cmd.optsWithGlobals();
122
+ const request = await readReferenceProfileGenerationRequest(String(opts.request));
123
+ const data = await saveGeneratedReferenceProfile(profileId, revisionId, request, opts.idempotencyKey ? String(opts.idempotencyKey) : undefined);
124
+ outputData(data, globalOpts);
125
+ }));
126
+ const exportCommand = referenceProfile
127
+ .command('export <profile-id> <revision-id>')
128
+ .description('Download a saved generated reference as an unsigned Artisan .alog plan')
129
+ .requiredOption('--output <file>', 'Destination for the generated .alog file')
130
+ .option('--force', 'Overwrite the destination file if it already exists')
131
+ .addHelpText('after', `
132
+ Example:
133
+ purvey reference-profile export 0b7e9f52-3c61-4d8a-9e24-6f1a8c3d5b90 c43a1d7e-95b2-4e06-8f7c-1d2b3a4e5f68 --output ~/artisan/next-batch.alog
134
+
135
+ Only a saved generated revision can be exported. Export writes the .alog file locally and
136
+ prints a JSON receipt; it does not claim verified Artisan 4.2 playback compatibility.`);
137
+ exportCommand.action(withErrorHandling(async (profileId, revisionId, opts, cmd) => {
138
+ const globalOpts = cmd.optsWithGlobals();
139
+ const destination = normalizePathInput(String(opts.output ?? ''));
140
+ if (!destination) {
141
+ throw new PrvrsError('INVALID_ARGUMENT', 'The export destination path cannot be blank.');
142
+ }
143
+ const result = await exportGeneratedReferenceProfile(profileId, revisionId);
144
+ const outputFile = await writeGeneratedReferenceFile(result.data.fileContent, destination, Boolean(opts.force));
145
+ outputData({
146
+ data: {
147
+ profileId,
148
+ revisionId,
149
+ fileName: result.data.fileName,
150
+ fileSize: result.data.fileSize,
151
+ outputPath: outputFile,
152
+ },
153
+ }, globalOpts);
154
+ }));
155
+ return referenceProfile;
156
+ }
157
+ //# sourceMappingURL=reference-profile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reference-profile.js","sourceRoot":"","sources":["../../src/commands/reference-profile.ts"],"names":[],"mappings":"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"}
@@ -1,21 +1,7 @@
1
1
  /** Cherry roast classification through the canonical Parchment API. */
2
2
  import type { CredentialContext } from './auth-client.js';
3
- export interface ClassifyRoastInput {
4
- alogMetadata: {
5
- title: string;
6
- filename?: string;
7
- roastertype?: string;
8
- beans?: string;
9
- roastingnotes?: string;
10
- weight?: [number, number, string];
11
- };
12
- inventory: Array<{
13
- id: number;
14
- coffee_name: string;
15
- origin?: string;
16
- processing?: string;
17
- }>;
18
- }
3
+ import type { components } from '@purveyors/sdk';
4
+ export type ClassifyRoastInput = components['schemas']['RoastClassificationRequest'];
19
5
  export interface ClassifyRoastResult {
20
6
  match: {
21
7
  inventoryId: number;
@@ -1 +1 @@
1
- {"version":3,"file":"cherry.d.ts","sourceRoot":"","sources":["../../src/lib/cherry.ts"],"names":[],"mappings":"AAAA,uEAAuE;AAEvE,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"}
1
+ {"version":3,"file":"cherry.d.ts","sourceRoot":"","sources":["../../src/lib/cherry.ts"],"names":[],"mappings":"AAAA,uEAAuE;AAEvE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAKjD,MAAM,MAAM,kBAAkB,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,4BAA4B,CAAC,CAAC;AAErF,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;AAwHD;;;;;GAKG;AACH,wBAAsB,aAAa,CACjC,iBAAiB,EAAE,iBAAiB,GAAG,wBAAwB,EAC/D,KAAK,EAAE,kBAAkB,GACxB,OAAO,CAAC,mBAAmB,CAAC,CAiB9B"}
@@ -27,11 +27,6 @@ function normalizeWeight(value) {
27
27
  return [input, output, unit];
28
28
  }
29
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
30
  const inventory = input.inventory.slice(0, CLASSIFICATION_INVENTORY_LIMIT).map((item, index) => {
36
31
  if (!Number.isInteger(item.id) || item.id <= 0) {
37
32
  throw new Error(`Invalid roast classification input: inventory[${index}].id must be a positive integer.`);
@@ -44,6 +39,25 @@ function normalizeClassificationInput(input) {
44
39
  processing: normalizeOptionalString(item.processing, CLASSIFICATION_STRING_LIMIT),
45
40
  };
46
41
  });
42
+ if ('artisanSource' in input) {
43
+ const fileName = normalizeOptionalString(input.artisanSource.fileName, CLASSIFICATION_STRING_LIMIT);
44
+ if (!fileName) {
45
+ throw new Error('Invalid roast classification input: artisanSource.fileName cannot be blank.');
46
+ }
47
+ return {
48
+ artisanSource: {
49
+ fileName,
50
+ // Source content is integrity-sensitive. Never trim or rewrite it client-side.
51
+ fileContent: input.artisanSource.fileContent,
52
+ },
53
+ inventory,
54
+ };
55
+ }
56
+ const filename = normalizeOptionalString(input.alogMetadata.filename, CLASSIFICATION_STRING_LIMIT);
57
+ const title = normalizeOptionalString(input.alogMetadata.title, CLASSIFICATION_STRING_LIMIT) ?? filename;
58
+ if (!title) {
59
+ throw new Error('Invalid roast classification input: alogMetadata.title and filename cannot both be blank.');
60
+ }
47
61
  return {
48
62
  alogMetadata: {
49
63
  title,
@@ -1 +1 @@
1
- {"version":3,"file":"cherry.js","sourceRoot":"","sources":["../../src/lib/cherry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cherry.js","sourceRoot":"","sources":["../../src/lib/cherry.ts"],"names":[],"mappings":"AAAA,uEAAuE;AAIvE,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAwBxE,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,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,IAAI,eAAe,IAAI,KAAK,EAAE,CAAC;QAC7B,MAAM,QAAQ,GAAG,uBAAuB,CACtC,KAAK,CAAC,aAAa,CAAC,QAAQ,EAC5B,2BAA2B,CAC5B,CAAC;QACF,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CACb,6EAA6E,CAC9E,CAAC;QACJ,CAAC;QACD,OAAO;YACL,aAAa,EAAE;gBACb,QAAQ;gBACR,+EAA+E;gBAC/E,WAAW,EAAE,KAAK,CAAC,aAAa,CAAC,WAAW;aAC7C;YACD,SAAS;SACV,CAAC;IACJ,CAAC;IAED,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,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,6BAA6B,CAC9B,CAAC;IAEF,qEAAqE;IACrE,OAAO;QACL,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,IAAI;KAC1B,CAAC;AACJ,CAAC"}
@@ -9,7 +9,6 @@ import { watch } from 'fs';
9
9
  import { readFile, access } from 'fs/promises';
10
10
  import type { CredentialContext } from '../auth-client.js';
11
11
  import type { ImportRoastResult } from '../roast.js';
12
- import type { MilestoneData, ProcessedRoastData } from '../artisan/types.js';
13
12
  import { listInventory } from '../inventory.js';
14
13
  /**
15
14
  * Arguments for a single watched roast import. Identity is resolved by the
@@ -52,8 +51,8 @@ export interface ImportRecord {
52
51
  batchName: string;
53
52
  status: 'pending' | 'success' | 'failed' | 'needs-review';
54
53
  error?: string;
55
- milestones?: MilestoneData;
56
- phases?: ProcessedRoastData['phases'];
54
+ milestones?: ImportRoastResult['milestones'];
55
+ phases?: ImportRoastResult['phases'];
57
56
  importedAt: string;
58
57
  selectedCoffeeId?: number;
59
58
  selectedCoffeeName?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../../../src/lib/interactive/watch.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../../../src/lib/interactive/watch.ts"],"names":[],"mappings":"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"}
@@ -708,25 +708,6 @@ function uniqueSupplierMatch(filename, inventory) {
708
708
  * Returns skip=true if confidence < 50 or if the AI call fails.
709
709
  */
710
710
  async function runAutoMatch(credentialContext, userId, filename, fileContent, inventoryLister, sessionTokenProvider) {
711
- // Parse alog metadata without full import
712
- let alogMetadata;
713
- try {
714
- const { processAlogFile } = await import('../artisan/parser.js');
715
- const parsed = processAlogFile(fileContent);
716
- alogMetadata = {
717
- title: typeof parsed.title === 'string' ? parsed.title : filename,
718
- roastertype: typeof parsed.roastertype === 'string' ? parsed.roastertype : undefined,
719
- beans: typeof parsed.beans === 'string' ? parsed.beans : undefined,
720
- roastingnotes: typeof parsed.roastingnotes === 'string' ? parsed.roastingnotes : undefined,
721
- weight: Array.isArray(parsed.weight)
722
- ? parsed.weight
723
- : undefined,
724
- };
725
- }
726
- catch {
727
- // If we can't parse the file, fall back to filename as title
728
- alogMetadata = { title: filename };
729
- }
730
711
  // Fetch the user's stocked inventory
731
712
  let inventory = [];
732
713
  try {
@@ -773,14 +754,11 @@ async function runAutoMatch(credentialContext, userId, filename, fileContent, in
773
754
  // Call the AI classifier
774
755
  try {
775
756
  const { classifyRoast } = await import('../cherry.js');
776
- // Always include the filename — it often contains the bean name
777
- // even when the .alog XML title is generic (e.g. "Roaster Scope")
778
- const enrichedMetadata = {
779
- ...alogMetadata,
780
- filename,
781
- };
782
757
  const result = await classifyRoast(credentialContext, {
783
- alogMetadata: enrichedMetadata,
758
+ artisanSource: {
759
+ fileName: filename,
760
+ fileContent,
761
+ },
784
762
  inventory,
785
763
  });
786
764
  if (!result.match) {