From 97ffa67f841341c36113ec7783105daf7d4d389a Mon Sep 17 00:00:00 2001 From: morluto <76467478+morluto@users.noreply.github.com> Date: Sun, 15 Nov 2026 20:21:04 +0800 Subject: [PATCH] refactor(setup): require the platform in client-layer readers and private-profile helpers (#11074) * refactor(setup): require the platform in client-layer readers and private-profile helpers * refactor(setup): drop the client-layer readers' unused host import --- scripts/verify/architecture-guard-baselines.json | 1 - src/application/ClientConfigurationFiles.ts | 3 +-- src/application/ClientPrivateProfile.ts | 11 ++++++----- src/application/ClientRegistrationStatus.ts | 3 ++- src/application/McpClientRegistration.ts | 14 +++++++++----- src/application/SetupClientConfiguration.ts | 5 ++++- src/application/SupportedClients.ts | 3 +-- 7 files changed, 23 insertions(+), 17 deletions(-) diff --git a/scripts/verify/architecture-guard-baselines.json b/scripts/verify/architecture-guard-baselines.json index 2ba80d4e70..3288355462 100644 --- a/scripts/verify/architecture-guard-baselines.json +++ b/scripts/verify/architecture-guard-baselines.json @@ -293,7 +293,6 @@ "src/application/Doctor.ts": 1, "src/application/DshCordisPatch.ts": 2, "src/application/JsonFiles.ts": 1, - "src/application/McpClientRegistration.ts": 3, "src/application/SetupHost.ts": 1, "src/application/SupportedClients.ts": 2, "src/application/Uninstall.ts": 1, diff --git a/src/application/ClientConfigurationFiles.ts b/src/application/ClientConfigurationFiles.ts index a58612dc75..0844784c7e 100644 --- a/src/application/ClientConfigurationFiles.ts +++ b/src/application/ClientConfigurationFiles.ts @@ -1,4 +1,3 @@ -import { HOST_PLATFORM } from "../platform/HostPlatform.js"; import { err, ok, type Result } from "../domain/result.js"; import { RegularFileCleanupFailure } from "../filesystem/OwnedRegularFile.js"; import { readRegularFileText } from "./RegularFileRead.js"; @@ -295,7 +294,7 @@ export const inlineRegistrationOverride = ( client: Pick, sources: readonly ClientConfigurationSource[], desired: unknown, - platform: NodeJS.Platform = HOST_PLATFORM.platform, + platform: NodeJS.Platform, ): ClientInlineConfiguration["origin"] | undefined => { const name = PRODUCT_IDENTITY.mcpServerKey; const inline = sources.filter( diff --git a/src/application/ClientPrivateProfile.ts b/src/application/ClientPrivateProfile.ts index 52e2a4dff7..6b751817e7 100644 --- a/src/application/ClientPrivateProfile.ts +++ b/src/application/ClientPrivateProfile.ts @@ -1,4 +1,3 @@ -import { HOST_PLATFORM } from "../platform/HostPlatform.js"; import { constants } from "node:fs"; import { lstat, open, realpath, stat } from "node:fs/promises"; import { dirname } from "node:path"; @@ -41,7 +40,7 @@ export type PrivateProfilePermissions = */ export const privateProfileModesCurrent = async ( configPath: string, - platform: NodeJS.Platform = HOST_PLATFORM.platform, + platform: NodeJS.Platform, ): Promise => { if (platform === "win32") return true; // Setup and `rea mcp add` publish a linked profile at its canonical path, @@ -136,9 +135,11 @@ export const securePrivateDirectory = async ( return changed; }; -/** Mode requests cannot establish Windows ACL privacy on this host. */ -export const privateProfilePermissions = (): PrivateProfilePermissions => - HOST_PLATFORM.platform === "win32" +/** Mode requests cannot establish Windows ACL privacy on `platform`. */ +export const privateProfilePermissions = ( + platform: NodeJS.Platform, +): PrivateProfilePermissions => + platform === "win32" ? { kind: "requested_windows_modes", requestedDirectoryMode: PRIVATE_PROFILE_MODES.directory, diff --git a/src/application/ClientRegistrationStatus.ts b/src/application/ClientRegistrationStatus.ts index 800bbe4579..06f5882422 100644 --- a/src/application/ClientRegistrationStatus.ts +++ b/src/application/ClientRegistrationStatus.ts @@ -1,4 +1,5 @@ import { RegularFileCleanupFailure } from "../filesystem/OwnedRegularFile.js"; +import { HOST_PLATFORM } from "../platform/HostPlatform.js"; import { readClientPolicyBlock } from "./GeminiClientSettings.js"; import { inlineRegistrationOrigins, @@ -165,7 +166,7 @@ export const readClientRegistrationInspections = async ( const inspections: ClientRegistrationInspection[] = []; for (const client of await resolveSupportedClients( home, - options.platform, + options.platform ?? HOST_PLATFORM.platform, options.environment, options.systemPaths, )) { diff --git a/src/application/McpClientRegistration.ts b/src/application/McpClientRegistration.ts index 0db155788c..dac805c4d0 100644 --- a/src/application/McpClientRegistration.ts +++ b/src/application/McpClientRegistration.ts @@ -1,4 +1,5 @@ import { mkdir } from "node:fs/promises"; +import { HOST_PLATFORM } from "../platform/HostPlatform.js"; import { dirname } from "node:path"; import { AnalysisCleanupLeaseGroup } from "../artifacts/AnalysisCleanupLease.js"; @@ -174,7 +175,10 @@ export const registerMcpClient = async ( : {}), }); checkCancellation(); - if (client.privateProfile !== undefined && process.platform !== "win32") + if ( + client.privateProfile !== undefined && + HOST_PLATFORM.platform !== "win32" + ) await securePrivateDirectory( dirname(path), client.privateProfile.home, @@ -202,7 +206,7 @@ export const registerMcpClient = async ( status: "configured", ...(backupPath === undefined ? {} : { backupPath }), ...(client.privateProfile !== undefined - ? { permissions: privateProfilePermissions() } + ? { permissions: privateProfilePermissions(HOST_PLATFORM.platform) } : {}), }); }); @@ -268,7 +272,7 @@ const unchangedRegistration = async ( parsed.requiresRewrite === true || !clientConfigurationValuesEqual(parsed.document, updated) || (client.privateProfile !== undefined && - process.platform !== "win32" && + HOST_PLATFORM.platform !== "win32" && ((snapshot?.state.mode ?? 0) & 0o777) !== PRIVATE_PROFILE_MODES.file) ) return undefined; @@ -284,7 +288,7 @@ const unchangedRegistration = async ( checkCancellation(); await verifyEffectiveRegistration(prepared, current.text); const permissionsChanged = - client.privateProfile !== undefined && process.platform !== "win32" + client.privateProfile !== undefined && HOST_PLATFORM.platform !== "win32" ? await securePrivateDirectory( dirname(path), client.privateProfile.home, @@ -295,7 +299,7 @@ const unchangedRegistration = async ( return { status: permissionsChanged ? "configured" : "unchanged", ...(client.privateProfile !== undefined - ? { permissions: privateProfilePermissions() } + ? { permissions: privateProfilePermissions(HOST_PLATFORM.platform) } : {}), }; }; diff --git a/src/application/SetupClientConfiguration.ts b/src/application/SetupClientConfiguration.ts index 6c1f9a823e..f7647b9c9b 100644 --- a/src/application/SetupClientConfiguration.ts +++ b/src/application/SetupClientConfiguration.ts @@ -1269,7 +1269,10 @@ const privateProfileCurrent = async ( ): Promise => client.privateProfile === undefined || (original !== undefined && - (await privateProfileModesCurrent(client.configPath))); + (await privateProfileModesCurrent( + client.configPath, + HOST_PLATFORM.platform, + ))); const clientConfigurationDesired = async ( client: SetupClient, diff --git a/src/application/SupportedClients.ts b/src/application/SupportedClients.ts index a9092454c9..e8ac607b9a 100644 --- a/src/application/SupportedClients.ts +++ b/src/application/SupportedClients.ts @@ -1,4 +1,3 @@ -import { HOST_PLATFORM } from "../platform/HostPlatform.js"; import type { ClientRegistrationConnectionProfile, ClientRegistrationProfile, @@ -2104,7 +2103,7 @@ export const supportedClients = ( */ export const resolveSupportedClients = async ( home: string, - platform: NodeJS.Platform = HOST_PLATFORM.platform, + platform: NodeJS.Platform, env: ClientPathContext["env"] = process.env, systemPaths: ClientSystemPaths = {}, ): Promise => {