From 296aaa2f926fa62f4af9d1daad1d3a2bc9575f46 Mon Sep 17 00:00:00 2001 From: Ryan DJ Lee Date: Mon, 13 Apr 2026 10:09:44 -0400 Subject: [PATCH] Fix scope parsing to handle space-separated input from PowerShell MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit parseStoreAuthScopes splits on commas only, but Windows PowerShell can transform comma-separated CLI args into space-separated strings before they reach Node.js. This causes the entire string "read_products read_inventory" to be treated as one unrecognized scope, triggering a false "fewer scopes than requested" error. Split on /[\s,]+/ instead — matching Core's own ScopeSet.parse_scopes which already handles both delimiters. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../cli/services/store/auth/scopes.test.ts | 20 +++++++++++++++++++ .../cli/src/cli/services/store/auth/scopes.ts | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/packages/cli/src/cli/services/store/auth/scopes.test.ts b/packages/cli/src/cli/services/store/auth/scopes.test.ts index 5dbb0dba04f..25674f54cb6 100644 --- a/packages/cli/src/cli/services/store/auth/scopes.test.ts +++ b/packages/cli/src/cli/services/store/auth/scopes.test.ts @@ -17,6 +17,26 @@ describe('store auth scope helpers', () => { expect(mergeRequestedAndStoredScopes(['read_products'], ['read_orders'])).toEqual(['read_orders', 'read_products']) }) + test('parseStoreAuthScopes splits space-separated scopes (PowerShell transforms commas to spaces)', () => { + expect(parseStoreAuthScopes('read_products read_inventory')).toEqual(['read_products', 'read_inventory']) + }) + + test('parseStoreAuthScopes splits mixed comma-and-space delimiters', () => { + expect(parseStoreAuthScopes('read_products, read_inventory')).toEqual(['read_products', 'read_inventory']) + }) + + test('resolveGrantedScopes succeeds when requested scopes were space-separated (PowerShell bug scenario)', () => { + expect( + resolveGrantedScopes( + { + access_token: 'token', + scope: 'read_products,read_inventory', + }, + ['read_products', 'read_inventory'], + ), + ).toEqual(['read_products', 'read_inventory']) + }) + test('resolveGrantedScopes accepts compressed write scopes that imply requested reads', () => { expect( resolveGrantedScopes( diff --git a/packages/cli/src/cli/services/store/auth/scopes.ts b/packages/cli/src/cli/services/store/auth/scopes.ts index efe8a2b5913..1b5b286c156 100644 --- a/packages/cli/src/cli/services/store/auth/scopes.ts +++ b/packages/cli/src/cli/services/store/auth/scopes.ts @@ -4,7 +4,7 @@ import type {StoreTokenResponse} from './token-client.js' export function parseStoreAuthScopes(input: string): string[] { const scopes = input - .split(',') + .split(/[\s,]+/) .map((scope) => scope.trim()) .filter(Boolean)