@purveyors/cli 0.30.0 → 0.32.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.
Files changed (48) hide show
  1. package/README.md +12 -12
  2. package/dist/commands/auth.d.ts +23 -19
  3. package/dist/commands/auth.d.ts.map +1 -1
  4. package/dist/commands/auth.js +234 -355
  5. package/dist/commands/auth.js.map +1 -1
  6. package/dist/commands/inventory.js +4 -4
  7. package/dist/commands/inventory.js.map +1 -1
  8. package/dist/commands/roast.d.ts +4 -4
  9. package/dist/commands/roast.d.ts.map +1 -1
  10. package/dist/commands/roast.js +30 -30
  11. package/dist/commands/roast.js.map +1 -1
  12. package/dist/commands/sales.d.ts +8 -10
  13. package/dist/commands/sales.d.ts.map +1 -1
  14. package/dist/commands/sales.js +9 -9
  15. package/dist/commands/sales.js.map +1 -1
  16. package/dist/commands/tasting.js +10 -10
  17. package/dist/commands/tasting.js.map +1 -1
  18. package/dist/lib/ai.d.ts +18 -9
  19. package/dist/lib/ai.d.ts.map +1 -1
  20. package/dist/lib/ai.js +20 -31
  21. package/dist/lib/ai.js.map +1 -1
  22. package/dist/lib/auth-client.d.ts +16 -18
  23. package/dist/lib/auth-client.d.ts.map +1 -1
  24. package/dist/lib/auth-client.js +4 -6
  25. package/dist/lib/auth-client.js.map +1 -1
  26. package/dist/lib/auth-guard.d.ts +3 -3
  27. package/dist/lib/auth-guard.d.ts.map +1 -1
  28. package/dist/lib/auth-guard.js +9 -9
  29. package/dist/lib/auth-guard.js.map +1 -1
  30. package/dist/lib/catalog.js +2 -2
  31. package/dist/lib/catalog.js.map +1 -1
  32. package/dist/lib/interactive/watch.d.ts +3 -3
  33. package/dist/lib/interactive/watch.d.ts.map +1 -1
  34. package/dist/lib/interactive/watch.js +11 -8
  35. package/dist/lib/interactive/watch.js.map +1 -1
  36. package/dist/lib/manifest.d.ts.map +1 -1
  37. package/dist/lib/manifest.js +6 -5
  38. package/dist/lib/manifest.js.map +1 -1
  39. package/dist/lib/market.d.ts.map +1 -1
  40. package/dist/lib/parchment-base.d.ts.map +1 -1
  41. package/dist/lib/parchment-base.js +1 -3
  42. package/dist/lib/parchment-base.js.map +1 -1
  43. package/dist/lib/parchment.d.ts +2 -2
  44. package/dist/lib/parchment.js +9 -9
  45. package/dist/lib/parchment.js.map +1 -1
  46. package/dist/lib/roast.js +1 -1
  47. package/dist/lib/roast.js.map +1 -1
  48. package/package.json +2 -2
package/README.md CHANGED
@@ -69,7 +69,7 @@ purvey auth login
69
69
  # For agents, CI, or remote machines, use headless flow:
70
70
  # purvey auth login --headless
71
71
 
72
- # If automatic browser callback handling fails or you paste a bad URL, paste the full callback URL back into the terminal. The CLI keeps waiting until a valid callback is received.
72
+ # Headless login prints an approval URL. Approve it in any browser; the CLI completes automatically.
73
73
 
74
74
  # 2. Confirm the stored API key and role
75
75
  purvey auth status
@@ -158,12 +158,12 @@ Headless login for agents, CI, and remote machines:
158
158
 
159
159
  ```bash
160
160
  purvey auth login --headless
161
- # CLI prints a Google OAuth URL
162
- # Open it in any browser and sign in
163
- # Paste the full callback URL back into the terminal
161
+ # CLI prints a purveyors.io approval URL
162
+ # Open it in any browser, sign in, and approve access
163
+ # The CLI completes automatically
164
164
  ```
165
165
 
166
- If the browser cannot return to the CLI during interactive login, paste the full callback URL back into the terminal. Invalid pasted URLs are ignored, and the CLI keeps waiting until a valid callback is received. Use `purvey auth login --headless` when you need the CLI to print the OAuth URL for another browser.
166
+ Both modes use Parchment's short-lived device authorization flow. The CLI keeps its PKCE verifier in memory, receives a scoped Parchment API key after browser approval, and never runs a localhost callback server or asks you to paste a callback URL. If browser launch fails, the interactive command prints the approval URL and keeps waiting.
167
167
 
168
168
  Status:
169
169
 
@@ -293,8 +293,8 @@ purvey auth logout
293
293
 
294
294
  Notes:
295
295
 
296
- - `auth login` uses browser-based Google OAuth, listens for the localhost callback, and also accepts a pasted callback URL if the browser cannot return to the CLI. Invalid pasted callback URLs are ignored so you can paste again while the CLI keeps waiting.
297
- - `auth login --headless` prints an OAuth URL and accepts a pasted callback URL.
296
+ - `auth login` opens a short-lived purveyors.io approval request and completes automatically after approval. If browser launch fails, it prints the same URL and keeps polling.
297
+ - `auth login --headless` prints the approval URL without trying to open a local browser. Approve it from any browser; nothing is pasted back.
298
298
  - `auth status --json` is the safest mode for scripts.
299
299
  - `auth status --csv` is supported for spreadsheet-style checks, but JSON remains the better integration format.
300
300
 
@@ -449,7 +449,7 @@ Notes:
449
449
 
450
450
  - `price-index` is backed by the canonical Parchment API `GET /v1/price-index` through `@purveyors/sdk`.
451
451
  - Session-token use requires the local `member` role; API-key use is accepted via `PARCHMENT_API_KEY` or `PURVEYORS_API_KEY` and PPI entitlement is enforced server-side.
452
- - `PARCHMENT_API_BASE_URL` overrides the canonical API base for this SDK-backed command. `PURVEYORS_BASE_URL` is also accepted for shared environment compatibility.
452
+ - `PARCHMENT_API_BASE_URL` overrides the canonical API base for this SDK-backed command.
453
453
 
454
454
  ### market
455
455
 
@@ -668,6 +668,7 @@ Notes:
668
668
  - `--coffee-id` uses inventory IDs.
669
669
  - `roast import` and `roast watch` normalize pasted paths by trimming whitespace, removing one layer of matching quotes, and accepting common shell-escaped characters.
670
670
  - `roast watch --auto-match` is mutually exclusive with `--coffee-id`.
671
+ - `roast watch --auto-match` sends 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.
671
672
  - `roast watch --commit-mode` defaults to `batch`.
672
673
 
673
674
  ### sales
@@ -882,11 +883,10 @@ Use the right ID for the right command.
882
883
 
883
884
  ## Environment variables
884
885
 
885
- - `PURVEYORS_SUPABASE_URL`: override the Supabase Auth issuer used only for OAuth bootstrap
886
886
  - `PURVEYORS_BASE_URL`: override the Purveyors web base URL
887
887
  - `PURVEYORS_API_KEY`: explicit API-key override for canonical Parchment commands
888
888
  - `PARCHMENT_API_KEY`: preferred API-key variable for SDK-backed Parchment commands; also accepted for API-backed proof and paid-tier similarity paths
889
- - `PARCHMENT_API_BASE_URL`: override the SDK-backed Parchment API base URL for `market`, `price-index`, and `procurement` commands
889
+ - `PARCHMENT_API_BASE_URL`: override the SDK-backed Parchment API base URL, including `market`, `price-index`, `procurement`, and roast auto-classification requests
890
890
  - `PURVEY_DEBUG`: enable verbose error output
891
891
 
892
892
  ## For AI agents
@@ -905,7 +905,7 @@ Why this CLI works well for agents:
905
905
 
906
906
  - stable command names
907
907
  - structured stdout by default
908
- - browser auth with pasted-callback fallback and headless auth
908
+ - browser approval with automatic polling and a first-class headless mode
909
909
  - documented exit codes and role boundaries
910
910
  - dedicated machine-readable manifest command
911
911
  - dedicated dense human-readable reference command
@@ -919,7 +919,7 @@ Agent integration rules of thumb:
919
919
 
920
920
  - Discover first with `purvey manifest`, then call the narrowest command or package subpath that fits the job.
921
921
  - Use `purvey context` when a human-readable operator summary is useful before tool selection.
922
- - Use `purvey auth login` for normal user workflows. OAuth is used only to bootstrap a machine-scoped Parchment API key; the CLI does not retain Supabase session or refresh tokens. Environment `PURVEYORS_API_KEY` or `PARCHMENT_API_KEY` values remain available for explicit automation overrides.
922
+ - Use `purvey auth login` for normal user workflows. Parchment coordinates browser approval and returns a machine-scoped API key; the CLI stores no web session, request token, or PKCE verifier. Environment `PURVEYORS_API_KEY` or `PARCHMENT_API_KEY` values remain available for explicit automation overrides.
923
923
  - Treat `--include-proof` as API output, not a local scoring feature. If a filter cannot round-trip through `/v1/catalog?include=proof`, the CLI rejects that invocation instead of returning misleading proof data.
924
924
  - Treat `catalog similar` as the canonical `/v1/catalog/{id}/similar` contract. Preserve the distinction between `canonical_candidates` and `similar_recommendations`; do not flatten or re-sort grouped results unless you have a specific downstream reason.
925
925
  - Treat `market`, `price-index`, and `procurement` as SDK-backed canonical API reads. Do not add procurement create/write behavior to this command group until the Phase 2 write contract ships.
@@ -1,27 +1,31 @@
1
1
  import { Command } from 'commander';
2
- import type { StoredCredentials } from '../types/index.js';
3
2
  import { type ParchmentClient } from '@purveyors/sdk';
4
- interface CallbackResult {
5
- accessToken: string;
6
- refreshToken: string;
7
- expiresIn: number;
8
- }
9
- interface ManualCallbackReader {
10
- promise: Promise<CallbackResult>;
11
- close: () => void;
3
+ import type { StoredCredentials } from '../types/index.js';
4
+ type CliAuthClient = Pick<ParchmentClient, 'cliAuth'>;
5
+ interface DeviceLoginOptions {
6
+ headless: boolean;
7
+ client?: CliAuthClient;
8
+ machineName?: string;
9
+ openBrowser?: (url: string) => Promise<boolean>;
10
+ sleep?: (milliseconds: number, signal?: AbortSignal) => Promise<void>;
11
+ signal?: AbortSignal;
12
+ exchangeCancellationTimeoutMs?: number;
13
+ onExchangeCancellationWait?: () => void;
12
14
  }
13
- type ManualCallbackQuestion = (query: string, callback: (answer: string) => void) => void;
14
- export declare function createOAuthUrl(redirectTo: string): string;
15
- export declare function exchangeOAuthSessionForApiKey(accessToken: string, clientOverride?: ParchmentClient): Promise<StoredCredentials>;
16
- /**
17
- * Extract Supabase OAuth tokens from a full callback URL, URL fragment, or
18
- * query string. Exported for auth-flow contract tests.
19
- */
20
- export declare function parseOAuthCallbackUrl(callbackUrl: string, expectedState?: string): CallbackResult;
21
- export declare function createManualCallbackReaderForQuestion(question: ManualCallbackQuestion, closeQuestion: () => void, canRead: boolean, expectedState?: string): ManualCallbackReader | null;
15
+ /** Generate an RFC 7636 verifier and its S256 challenge. */
16
+ export declare function createPkcePair(): {
17
+ verifier: string;
18
+ challenge: string;
19
+ };
20
+ /** Normalize hostnames to Parchment's stable, human-readable machine-name contract. */
21
+ export declare function normalizeMachineName(value: string): string;
22
+ /** Open the verification page, returning false when no browser command is available. */
23
+ export declare function openVerificationPage(url: string): Promise<boolean>;
22
24
  /**
23
- * Build and return the `auth` command subtree.
25
+ * Run the Parchment-owned browser/device authorization protocol.
26
+ * The verifier and signed request token remain memory-only and are discarded on exit.
24
27
  */
28
+ export declare function performDeviceLogin(options: DeviceLoginOptions): Promise<StoredCredentials>;
25
29
  export declare function buildAuthCommand(): Command;
26
30
  export {};
27
31
  //# sourceMappingURL=auth.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,OAAO,KAAK,EAAiB,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAI1E,OAAO,EAAyB,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAwB7E,UAAU,cAAc;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB;AASD,UAAU,oBAAoB;IAC5B,OAAO,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;IACjC,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAED,KAAK,sBAAsB,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,KAAK,IAAI,CAAC;AAE1F,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAKzD;AAiBD,wBAAsB,6BAA6B,CACjD,WAAW,EAAE,MAAM,EACnB,cAAc,CAAC,EAAE,eAAe,GAC/B,OAAO,CAAC,iBAAiB,CAAC,CAwC5B;AAsHD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,cAAc,CA2CjG;AAED,wBAAgB,qCAAqC,CACnD,QAAQ,EAAE,sBAAsB,EAChC,aAAa,EAAE,MAAM,IAAI,EACzB,OAAO,EAAE,OAAO,EAChB,aAAa,CAAC,EAAE,MAAM,GACrB,oBAAoB,GAAG,IAAI,CAwC7B;AAsLD;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CAmF1C"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,OAAO,EAAyB,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAQ7E,OAAO,KAAK,EAAiB,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAK1E,KAAK,aAAa,GAAG,IAAI,CAAC,eAAe,EAAE,SAAS,CAAC,CAAC;AAEtD,UAAU,kBAAkB;IAC1B,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAChD,KAAK,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtE,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,6BAA6B,CAAC,EAAE,MAAM,CAAC;IACvC,0BAA0B,CAAC,EAAE,MAAM,IAAI,CAAC;CACzC;AAWD,4DAA4D;AAC5D,wBAAgB,cAAc,IAAI;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAIxE;AAUD,uFAAuF;AACvF,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAS1D;AAuFD,wFAAwF;AACxF,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAiBxE;AAeD;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAiGhG;AAiFD,wBAAgB,gBAAgB,IAAI,OAAO,CA0E1C"}