From ad5672a54101b46158da82c55a50ec9a84b9f3ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Isaac=20Rold=C3=A1n?= Date: Thu, 9 Jul 2026 19:07:53 +0200 Subject: [PATCH 1/2] Add order-insensitive deep object comparison to cli-kit Adds `deepCompareWithOrderInsensitiveArrays` (plus private helpers) to `@shopify/cli-kit/common/object`. Deeply compares two values while treating arrays as unordered, which the deploy/release config breakdown will use to compare webhook subscriptions regardless of ordering. Purely additive: no existing export is modified. Co-Authored-By: Claude Opus 4.8 (1M context) From 439eb86b2ed319474f37afd20b086d823a3e6864 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Isaac=20Rold=C3=A1n?= Date: Thu, 9 Jul 2026 19:09:53 +0200 Subject: [PATCH 2/2] Classify webhook subscription modules as configuration experience `normalizeExperience` now receives the spec identifier and maps the webhook subscription spec to the `configuration` experience. This makes the active-app-version deploy/release classification (added later in this stack) treat webhook subscriptions as configuration rather than extensions. No consumer relies on the new classification yet, so behavior is unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../developer-platform-client/app-management-client.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/app/src/cli/utilities/developer-platform-client/app-management-client.ts b/packages/app/src/cli/utilities/developer-platform-client/app-management-client.ts index 32457c5c47f..d324070d6b7 100644 --- a/packages/app/src/cli/utilities/developer-platform-client/app-management-client.ts +++ b/packages/app/src/cli/utilities/developer-platform-client/app-management-client.ts @@ -129,6 +129,7 @@ import { AppLogsSubscribeMutationVariables, } from '../../api/graphql/app-management/generated/app-logs-subscribe.js' import {SourceExtension} from '../../api/graphql/app-management/generated/types.js' +import {WebhookSubscriptionSpecIdentifier} from '../../models/extensions/specifications/app_config_webhook_subscription.js' import {fetchOrganizations} from '@shopify/organizations' import {getAppAutomationToken} from '@shopify/cli-kit/node/environment' import {ensureAuthenticatedAppManagementAndBusinessPlatform, Session} from '@shopify/cli-kit/node/session' @@ -445,7 +446,7 @@ export class AppManagementClient implements DeveloperPlatformClient { managementExperience: 'cli', registrationLimit: spec.uidStrategy.appModuleLimit, uidStrategy: uidStrategyFromTypename(spec.uidStrategy.__typename), - experience: normalizeExperience(spec.experience), + experience: normalizeExperience(spec.experience, spec.identifier), validationSchema: spec.validationSchema, }), ) @@ -687,7 +688,7 @@ export class AppManagementClient implements DeveloperPlatformClient { registrationTitle: mod.handle, specification: { identifier: mod.specification.identifier, - experience: normalizeExperience(mod.specification.experience), + experience: normalizeExperience(mod.specification.experience, mod.specification.identifier), options: { managementExperience: 'cli', }, @@ -1370,7 +1371,8 @@ type SpecificationExperience = 'extension' | 'configuration' | 'deprecated' * Normalizes the raw experience string from the API into a known union value. * Falls back to 'extension' for any unexpected/unknown values and logs a debug message. */ -function normalizeExperience(raw: string): SpecificationExperience { +function normalizeExperience(raw: string, type: string): SpecificationExperience { + if (type === WebhookSubscriptionSpecIdentifier) return 'configuration' switch (raw) { case 'extension': case 'configuration': @@ -1428,7 +1430,7 @@ function appModuleVersion(mod: ReleasedAppModuleFragment): Required