openmeld 0.3.94 → 0.3.96

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.
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { r as runSpaceAddMembers } from "./command-z9T11Rju.js";
3
+ import { r as runSpaceAddMembers } from "./command-cWXoKcwr.js";
4
4
  //#region src/space/add-me-membership.ts
5
5
  async function runSpaceAddMeMembership(input) {
6
6
  return await runSpaceAddMembers(input);
@@ -8,4 +8,4 @@ async function runSpaceAddMeMembership(input) {
8
8
  //#endregion
9
9
  export { runSpaceAddMeMembership };
10
10
 
11
- //# sourceMappingURL=add-me-membership-C_2sB0YD.js.map
11
+ //# sourceMappingURL=add-me-membership-CWKBMx0m.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"add-me-membership-C_2sB0YD.js","names":[],"sources":["../src/space/add-me-membership.ts"],"sourcesContent":["import { runSpaceAddMembers } from \"./command\";\nimport type { SpaceCommandNavigationStatus } from \"./navigation-status\";\n\nexport type SpaceAddMeMembershipInput = Parameters<\n typeof runSpaceAddMembers\n>[0];\nexport type SpaceAddMeMembershipRunner = (\n input: SpaceAddMeMembershipInput\n) => Promise<SpaceCommandNavigationStatus>;\n\nexport async function runSpaceAddMeMembership(\n input: SpaceAddMeMembershipInput\n): Promise<SpaceCommandNavigationStatus> {\n return await runSpaceAddMembers(input);\n}\n"],"mappings":";;;;AAUA,eAAsB,wBACpB,OACuC;CACvC,OAAO,MAAM,mBAAmB,KAAK;AACvC"}
1
+ {"version":3,"file":"add-me-membership-CWKBMx0m.js","names":[],"sources":["../src/space/add-me-membership.ts"],"sourcesContent":["import { runSpaceAddMembers } from \"./command\";\nimport type { SpaceCommandNavigationStatus } from \"./navigation-status\";\n\nexport type SpaceAddMeMembershipInput = Parameters<\n typeof runSpaceAddMembers\n>[0];\nexport type SpaceAddMeMembershipRunner = (\n input: SpaceAddMeMembershipInput\n) => Promise<SpaceCommandNavigationStatus>;\n\nexport async function runSpaceAddMeMembership(\n input: SpaceAddMeMembershipInput\n): Promise<SpaceCommandNavigationStatus> {\n return await runSpaceAddMembers(input);\n}\n"],"mappings":";;;;AAUA,eAAsB,wBACpB,OACuC;CACvC,OAAO,MAAM,mBAAmB,KAAK;AACvC"}
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  import { T as normalizeBaseUrl, _n as __exportAll } from "./base-url-Cv9x5Es9.js";
4
- import { I as OPENMELD_HEADER_REQUESTED_ORGANIZATION_ID, R as buildOpenMeldRequestContextHeaders, h as createOpenMeldApiClient } from "./dist-DXBncfSC.js";
5
- import { C as MAX_SPACE_REQUEST_TIMEOUT_MS, T as MIN_SPACE_REQUEST_TIMEOUT_MS, a as getAuthSessionState, b as DEFAULT_SPACE_REQUEST_TIMEOUT_MS } from "./auth-session-CTkKQOEP.js";
4
+ import { I as OPENMELD_HEADER_REQUESTED_ORGANIZATION_ID, R as buildOpenMeldRequestContextHeaders, h as createOpenMeldApiClient } from "./dist-BBWU3O-I.js";
5
+ import { E as MIN_SPACE_REQUEST_TIMEOUT_MS, a as getAuthSessionState, w as MAX_SPACE_REQUEST_TIMEOUT_MS, x as DEFAULT_SPACE_REQUEST_TIMEOUT_MS } from "./auth-session-BcT7IOfJ.js";
6
6
  import crypto from "node:crypto";
7
7
  //#region src/config/auth-request-compatibility.ts
8
8
  function resolveAuthRequestCompatibility(input) {
@@ -381,4 +381,4 @@ function createCliApiClientFoundation(baseUrl, options = {}) {
381
381
  //#endregion
382
382
  export { buildOpenMeldProfileIdentityRequestHeadersWithAuth as a, buildRequestAuthHeaders as c, buildOpenMeldRequestContextFromProfile as d, buildOpenMeldRequestContextFromProfileIdentity as f, resolveSpaceRequestTimeoutMsForDiagnostics as i, canAttachAuthTokenToRequest as l, resolveAuthRequestCompatibility as m, createCliApiClientFoundation as n, buildOpenMeldProfileRequestHeadersWithAuth as o, deriveAuthBaseUrlFromGatewayUrl as p, fetchSpaceRequestWithTimeout as r, buildOpenMeldRequestContextHeadersWithAuth as s, api_client_foundation_exports as t, resolveAuthTokenAttachment as u };
383
383
 
384
- //# sourceMappingURL=api-client-foundation-BjoKBD1e.js.map
384
+ //# sourceMappingURL=api-client-foundation-BJIJ540D.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"api-client-foundation-BjoKBD1e.js","names":["resolveSpaceRequestTimeoutMsForDiagnostics","resolveSpaceRequestTimeoutMsForCliDiagnostics"],"sources":["../src/config/auth-request-compatibility.ts","../src/config/openmeld-request-context.ts","../src/config/request-headers.ts","../src/space/request-timeout.ts","../src/space/fetch-with-timeout.ts","../src/space/api-client-foundation.ts"],"sourcesContent":["import { normalizeBaseUrl } from \"../protocol/urls\";\nimport type { StoredAuthSession } from \"./auth-session\";\n\nexport type AuthRequestCompatibilityReason =\n | \"invalid_request_url\"\n | \"invalid_auth_url\"\n | \"insecure_transport\"\n | \"host_mismatch\"\n | \"loopback\"\n | \"same_host\"\n | \"gateway_sibling\";\n\nexport type AuthRequestCompatibility = {\n compatible: boolean;\n reason: AuthRequestCompatibilityReason;\n requestHost: string | null;\n authHost: string | null;\n expectedGatewayHost: string | null;\n};\n\nexport function resolveAuthRequestCompatibility(input: {\n session: StoredAuthSession;\n requestUrl: string;\n}): AuthRequestCompatibility {\n const requestUrl = parseUrlOrNull(input.requestUrl);\n if (!requestUrl) {\n return {\n compatible: false,\n reason: \"invalid_request_url\",\n requestHost: null,\n authHost: null,\n expectedGatewayHost: null,\n };\n }\n\n const authBaseUrl = parseUrlOrNull(input.session.authBaseUrl);\n if (!authBaseUrl) {\n return {\n compatible: false,\n reason: \"invalid_auth_url\",\n requestHost: requestUrl.host,\n authHost: null,\n expectedGatewayHost: null,\n };\n }\n\n const expectedGatewayHost = deriveGatewayHost(authBaseUrl);\n const requestHost = requestUrl.host;\n const authHost = authBaseUrl.host;\n\n if (\n isLoopbackHostname(requestUrl.hostname) &&\n isLoopbackHostname(authBaseUrl.hostname)\n ) {\n return {\n compatible: true,\n reason: \"loopback\",\n requestHost,\n authHost,\n expectedGatewayHost,\n };\n }\n\n if (!isSecureTransportProtocol(requestUrl.protocol)) {\n return {\n compatible: false,\n reason: \"insecure_transport\",\n requestHost,\n authHost,\n expectedGatewayHost,\n };\n }\n\n if (requestHost === authHost) {\n return {\n compatible: true,\n reason: \"same_host\",\n requestHost,\n authHost,\n expectedGatewayHost,\n };\n }\n\n if (expectedGatewayHost && requestHost === expectedGatewayHost) {\n return {\n compatible: true,\n reason: \"gateway_sibling\",\n requestHost,\n authHost,\n expectedGatewayHost,\n };\n }\n\n return {\n compatible: false,\n reason: \"host_mismatch\",\n requestHost,\n authHost,\n expectedGatewayHost,\n };\n}\n\nexport function canUseAuthSessionForRequest(input: {\n session: StoredAuthSession;\n requestUrl: string;\n}): boolean {\n return resolveAuthRequestCompatibility(input).compatible;\n}\n\nexport function deriveAuthBaseUrlFromGatewayUrl(\n gatewayUrl: string\n): string | null {\n const parsed = parseUrlOrNull(gatewayUrl);\n if (!parsed) {\n return null;\n }\n if (!isHttpTransportProtocol(parsed.protocol)) {\n return null;\n }\n if (!parsed.hostname.startsWith(\"gateway.\")) {\n return null;\n }\n\n const authUrl = new URL(parsed.toString());\n authUrl.hostname = `auth.${parsed.hostname.slice(\"gateway.\".length)}`;\n authUrl.pathname = \"/\";\n authUrl.search = \"\";\n authUrl.hash = \"\";\n return normalizeBaseUrl(authUrl.toString());\n}\n\nfunction deriveGatewayHost(authBaseUrl: URL): string | null {\n if (!authBaseUrl.hostname.startsWith(\"auth.\")) {\n return null;\n }\n\n const gatewayUrl = new URL(authBaseUrl.toString());\n gatewayUrl.hostname = `gateway.${authBaseUrl.hostname.slice(\"auth.\".length)}`;\n return gatewayUrl.host;\n}\n\nfunction parseUrlOrNull(value: string): URL | null {\n try {\n return new URL(value);\n } catch {\n return null;\n }\n}\n\nfunction isLoopbackHostname(hostname: string): boolean {\n return (\n hostname === \"localhost\" || hostname === \"127.0.0.1\" || hostname === \"::1\"\n );\n}\n\nfunction isSecureTransportProtocol(protocol: string): boolean {\n return protocol === \"https:\" || protocol === \"wss:\";\n}\n\nfunction isHttpTransportProtocol(protocol: string): boolean {\n return protocol === \"http:\" || protocol === \"https:\";\n}\n","import crypto from \"node:crypto\";\nimport type { OpenMeldRequestContext } from \"@openmeld/schemas/types\";\nimport type { OpenMeldProfile } from \"./openmeld-profiles-api\";\n\nexport type OpenMeldRequestContextProfileIdentity = {\n openMeldProfileId: string;\n profileKind?: \"human\" | \"agent\" | \"system\";\n kind?: \"human\" | \"agent\";\n profileHandle?: string;\n profileName: string;\n ownerUserId?: string;\n ownerName?: string;\n agentControllerConversationId?: string;\n};\n\nexport function buildOpenMeldRequestContextFromProfile(input: {\n openMeldProfile: OpenMeldProfile;\n requestId?: string;\n agentControllerConversationId?: string;\n}): OpenMeldRequestContext {\n const requestId =\n normalizeOptionalText(input.requestId) ?? crypto.randomUUID();\n const agentControllerConversationId = normalizeOptionalText(\n input.agentControllerConversationId\n );\n const ownerName = normalizeOptionalText(input.openMeldProfile.ownerName);\n\n return {\n actorContext: {\n requestId,\n openMeldProfileId: input.openMeldProfile.openMeldProfileId,\n profileKind: input.openMeldProfile.profileKind,\n profileHandle: input.openMeldProfile.profileHandle,\n profileName: input.openMeldProfile.profileName,\n ownerUserId: input.openMeldProfile.ownerUserId,\n ...(ownerName ? { ownerName } : {}),\n },\n ...(agentControllerConversationId ? { agentControllerConversationId } : {}),\n };\n}\n\nexport function buildOpenMeldRequestContextFromProfileIdentity(input: {\n profileIdentity: OpenMeldRequestContextProfileIdentity;\n requestId?: string;\n}): OpenMeldRequestContext {\n const requestId =\n normalizeOptionalText(input.requestId) ?? crypto.randomUUID();\n const profileHandle = normalizeOptionalText(\n input.profileIdentity.profileHandle\n );\n const ownerUserId = normalizeOptionalText(input.profileIdentity.ownerUserId);\n const ownerName = normalizeOptionalText(input.profileIdentity.ownerName);\n const agentControllerConversationId = normalizeOptionalText(\n input.profileIdentity.agentControllerConversationId\n );\n const profileKind =\n input.profileIdentity.profileKind ??\n (input.profileIdentity.kind === \"human\" ||\n input.profileIdentity.kind === \"agent\"\n ? input.profileIdentity.kind\n : \"system\");\n\n return {\n actorContext: {\n requestId,\n openMeldProfileId: input.profileIdentity.openMeldProfileId,\n profileKind,\n ...(profileHandle ? { profileHandle } : {}),\n profileName: input.profileIdentity.profileName,\n ...(ownerUserId ? { ownerUserId } : {}),\n ...(ownerName ? { ownerName } : {}),\n },\n ...(agentControllerConversationId ? { agentControllerConversationId } : {}),\n };\n}\n\nfunction normalizeOptionalText(value: unknown): string | null {\n const normalized = String(value ?? \"\").trim();\n return normalized.length > 0 ? normalized : null;\n}\n","import {\n buildOpenMeldRequestContextHeaders,\n type OpenMeldRequestContextHeadersInput,\n} from \"@openmeld/gateway-contract\";\nimport type { OpenMeldRequestContext } from \"@openmeld/schemas/types\";\nimport {\n type AuthRequestCompatibilityReason,\n canUseAuthSessionForRequest,\n resolveAuthRequestCompatibility,\n} from \"./auth-request-compatibility\";\nimport { getAuthSessionState, type StoredAuthSession } from \"./auth-session\";\nimport type { OpenMeldProfile } from \"./openmeld-profiles-api\";\nimport {\n buildOpenMeldRequestContextFromProfile,\n buildOpenMeldRequestContextFromProfileIdentity,\n type OpenMeldRequestContextProfileIdentity,\n} from \"./openmeld-request-context\";\n\nconst DEFAULT_TOKEN_TYPE = \"Bearer\";\nconst AUTHORIZATION_HEADER = \"Authorization\";\n\ntype RequestAuthHeadersInput = {\n authSession?: StoredAuthSession | null;\n requestUrl: string;\n};\n\ntype OpenMeldRequestContextHeadersWithAuthInput =\n OpenMeldRequestContextHeadersInput & {\n authSession?: StoredAuthSession | null;\n requestUrl: string;\n };\n\nexport type AuthTokenAttachment =\n | {\n status: \"attachable\";\n token: string;\n tokenType: string;\n }\n | {\n status: \"dropped\";\n reason: \"empty_token\" | AuthRequestCompatibilityReason;\n requestHost: string | null;\n authHost: string | null;\n expectedGatewayHost: string | null;\n };\n\nexport type DroppedAuthTokenAttachment = Extract<\n AuthTokenAttachment,\n { status: \"dropped\" }\n>;\n\nexport async function buildRequestAuthHeaders(\n input: RequestAuthHeadersInput\n): Promise<Record<string, string>> {\n const headers: Record<string, string> = {};\n await attachAuthHeader(headers, input);\n return headers;\n}\n\nexport async function buildOpenMeldRequestContextHeadersWithAuth(\n input: OpenMeldRequestContextHeadersWithAuthInput\n): Promise<Record<string, string>> {\n const headers = buildOpenMeldRequestContextHeaders(input);\n await attachAuthHeader(headers, input);\n return headers;\n}\n\nexport async function buildOpenMeldProfileRequestHeadersWithAuth(input: {\n openMeldProfile: OpenMeldProfile;\n requestUrl: string;\n authSession?: StoredAuthSession | null;\n agentControllerConversationId?: string;\n spacePassword?: string;\n}): Promise<Record<string, string>> {\n return await buildOpenMeldRequestContextHeadersWithAuth({\n requestContext: buildOpenMeldRequestContextFromProfile({\n openMeldProfile: input.openMeldProfile,\n agentControllerConversationId: input.agentControllerConversationId,\n }),\n requestUrl: input.requestUrl,\n ...(input.authSession === undefined\n ? {}\n : { authSession: input.authSession }),\n ...(input.spacePassword === undefined\n ? {}\n : { spacePassword: input.spacePassword }),\n });\n}\n\nexport async function buildOpenMeldProfileIdentityRequestHeadersWithAuth(input: {\n profileIdentity: OpenMeldRequestContextProfileIdentity;\n requestUrl: string;\n authSession?: StoredAuthSession | null;\n spacePassword?: string;\n}): Promise<Record<string, string>> {\n return await buildOpenMeldRequestContextHeadersWithAuth({\n requestContext: buildOpenMeldRequestContextFromProfileIdentity({\n profileIdentity: input.profileIdentity,\n }),\n requestUrl: input.requestUrl,\n ...(input.authSession === undefined\n ? {}\n : { authSession: input.authSession }),\n ...(input.spacePassword === undefined\n ? {}\n : { spacePassword: input.spacePassword }),\n });\n}\n\nexport function withSpacePassword(\n requestContext: OpenMeldRequestContext,\n spacePassword?: string\n): OpenMeldRequestContextHeadersInput {\n return {\n requestContext,\n ...(spacePassword === undefined ? {} : { spacePassword }),\n };\n}\n\n// One decision for \"can this stored session authenticate this request\", with\n// the drop reason preserved. Header building and the daemon stream connect\n// gate must share this so they cannot drift apart.\nexport function resolveAuthTokenAttachment(input: {\n session: StoredAuthSession;\n requestUrl: string;\n}): AuthTokenAttachment {\n const compatibility = resolveAuthRequestCompatibility({\n session: input.session,\n requestUrl: input.requestUrl,\n });\n const token = normalizeAccessToken(input.session);\n if (!token) {\n return {\n status: \"dropped\",\n reason: \"empty_token\",\n requestHost: compatibility.requestHost,\n authHost: compatibility.authHost,\n expectedGatewayHost: compatibility.expectedGatewayHost,\n };\n }\n if (!compatibility.compatible) {\n return {\n status: \"dropped\",\n reason: compatibility.reason,\n requestHost: compatibility.requestHost,\n authHost: compatibility.authHost,\n expectedGatewayHost: compatibility.expectedGatewayHost,\n };\n }\n return {\n status: \"attachable\",\n token,\n tokenType: normalizeTokenType(input.session.tokenType),\n };\n}\n\nasync function attachAuthHeader(\n headers: Record<string, string>,\n input: RequestAuthHeadersInput\n): Promise<void> {\n const session = await resolveAuthSessionForHeaders(input);\n if (session === null) {\n // No stored credentials exist, so there is nothing to strip: the caller\n // is knowingly sending an unauthenticated request.\n return;\n }\n\n const attachment = resolveAuthTokenAttachment({\n session,\n requestUrl: input.requestUrl,\n });\n if (attachment.status === \"dropped\") {\n // The caller holds a session it believes is usable. Dropping the token is\n // still the safe outcome (never leak credentials to an incompatible\n // host), but it must stay visible in diagnostics instead of silently\n // dialing bare and surfacing as a remote 401.\n warnDroppedAuthToken(attachment);\n return;\n }\n headers[AUTHORIZATION_HEADER] = `${attachment.tokenType} ${attachment.token}`;\n}\n\nfunction warnDroppedAuthToken(attachment: DroppedAuthTokenAttachment): void {\n console.warn(\"[openmeld.auth.request_token_dropped]\", {\n authHost: attachment.authHost,\n expectedGatewayHost: attachment.expectedGatewayHost,\n reason: attachment.reason,\n requestHost: attachment.requestHost,\n });\n}\n\nasync function resolveAuthSessionForHeaders(\n input: RequestAuthHeadersInput\n): Promise<StoredAuthSession | null> {\n if (input.authSession !== undefined) {\n return input.authSession;\n }\n\n const sessionState = await getAuthSessionState();\n if (sessionState.state !== \"valid\" || sessionState.session === null) {\n return null;\n }\n\n return sessionState.session;\n}\n\nfunction normalizeAccessToken(session: StoredAuthSession): string {\n return String(session.accessToken ?? \"\").trim();\n}\n\nfunction normalizeTokenType(tokenType: string | undefined): string {\n const normalized = String(tokenType ?? \"\").trim();\n return normalized.length > 0 ? normalized : DEFAULT_TOKEN_TYPE;\n}\n\nexport function canAttachAuthTokenToRequest(\n session: StoredAuthSession,\n requestUrl: string\n): boolean {\n return canUseAuthSessionForRequest({\n session,\n requestUrl,\n });\n}\n","import {\n DEFAULT_SPACE_CONVERSATION_VALIDATE_TIMEOUT_MS,\n DEFAULT_SPACE_REQUEST_TIMEOUT_MS,\n MAX_SPACE_REQUEST_TIMEOUT_MS,\n MIN_SPACE_REQUEST_TIMEOUT_MS,\n} from \"../strategy-constants\";\n\nconst SPACE_REQUEST_TIMEOUT_ENV_KEY = \"OPENMELD_SPACE_REQUEST_TIMEOUT_MS\";\n\nexport function resolveSpaceRequestTimeoutMs(override?: number): number {\n if (isFinitePositiveNumber(override)) {\n return clampSpaceRequestTimeoutMs(override);\n }\n\n const fromEnv = Number.parseInt(\n String(process.env[SPACE_REQUEST_TIMEOUT_ENV_KEY] ?? \"\"),\n 10\n );\n if (isFinitePositiveNumber(fromEnv)) {\n return clampSpaceRequestTimeoutMs(fromEnv);\n }\n\n return DEFAULT_SPACE_REQUEST_TIMEOUT_MS;\n}\n\nexport function resolveSpaceRequestTimeoutMsForDiagnostics(): number {\n return resolveSpaceRequestTimeoutMs(undefined);\n}\n\nexport function resolveSpaceConversationValidateTimeoutMs(): number {\n return Math.max(\n resolveSpaceRequestTimeoutMs(undefined),\n DEFAULT_SPACE_CONVERSATION_VALIDATE_TIMEOUT_MS\n );\n}\n\nfunction clampSpaceRequestTimeoutMs(value: number): number {\n const normalized = Math.trunc(value);\n return Math.max(\n MIN_SPACE_REQUEST_TIMEOUT_MS,\n Math.min(MAX_SPACE_REQUEST_TIMEOUT_MS, normalized)\n );\n}\n\nfunction isFinitePositiveNumber(value: unknown): value is number {\n return typeof value === \"number\" && Number.isFinite(value) && value > 0;\n}\n","import {\n resolveSpaceRequestTimeoutMs,\n resolveSpaceRequestTimeoutMsForDiagnostics as resolveSpaceRequestTimeoutMsForCliDiagnostics,\n} from \"./request-timeout\";\n\nexport async function fetchSpaceRequestWithTimeout(input: {\n url: string;\n operation: string;\n init?: RequestInit;\n timeoutMs?: number;\n}): Promise<Response> {\n const timeoutMs = resolveSpaceRequestTimeoutMs(input.timeoutMs);\n const timeoutSignal = AbortSignal.timeout(timeoutMs);\n const composed = composeAbortSignals(input.init?.signal, timeoutSignal);\n\n try {\n try {\n return await fetch(input.url, {\n ...input.init,\n signal: composed.signal,\n });\n } catch (error) {\n // A keep-alive connection that a proxy silently dropped fails exactly\n // once and undici evicts it; the retry rides a fresh connection. This\n // is what keeps a long-lived service working behind flaky proxies\n // without asking users to touch their network config.\n if (\n timeoutSignal.aborted ||\n composed.signal.aborted ||\n !shouldWrapNetworkRequestError(error)\n ) {\n throw error;\n }\n return await fetch(input.url, {\n ...input.init,\n signal: composed.signal,\n });\n }\n } catch (error) {\n if (timeoutSignal.aborted) {\n throw createSpaceRequestTimeoutError({\n operation: input.operation,\n timeoutMs,\n cause: error,\n });\n }\n if (shouldWrapNetworkRequestError(error)) {\n throw createSpaceRequestNetworkError({\n operation: input.operation,\n url: input.url,\n cause: error,\n });\n }\n throw error;\n } finally {\n composed.cleanup();\n }\n}\n\nexport function resolveSpaceRequestTimeoutMsForDiagnostics(): number {\n return resolveSpaceRequestTimeoutMsForCliDiagnostics();\n}\n\nfunction createSpaceRequestTimeoutError(input: {\n operation: string;\n timeoutMs: number;\n cause: unknown;\n}): Error {\n const error = new Error(\n `${input.operation} request timed out after ${input.timeoutMs}ms`,\n { cause: input.cause }\n ) as Error & { code?: string };\n error.code = \"network.timeout\";\n return error;\n}\n\nfunction createSpaceRequestNetworkError(input: {\n operation: string;\n url: string;\n cause: unknown;\n}): Error {\n const error = new Error(\n `${input.operation} request could not reach ${describeRequestTarget(input.url)} (${toErrorMessage(input.cause)})`,\n { cause: input.cause }\n ) as Error & { code?: string };\n error.code = \"network.request_failed\";\n return error;\n}\n\nfunction composeAbortSignals(\n parent: AbortSignal | null | undefined,\n timeout: AbortSignal\n): { signal: AbortSignal; cleanup: () => void } {\n if (!parent) {\n return {\n signal: timeout,\n cleanup: () => undefined,\n };\n }\n\n if (parent.aborted || timeout.aborted) {\n const controller = new AbortController();\n controller.abort();\n return {\n signal: controller.signal,\n cleanup: () => undefined,\n };\n }\n\n const controller = new AbortController();\n const abort = () => {\n controller.abort();\n };\n\n parent.addEventListener(\"abort\", abort, { once: true });\n timeout.addEventListener(\"abort\", abort, { once: true });\n\n return {\n signal: controller.signal,\n cleanup: () => {\n parent.removeEventListener(\"abort\", abort);\n timeout.removeEventListener(\"abort\", abort);\n },\n };\n}\n\nfunction describeRequestTarget(url: string): string {\n try {\n return new URL(url).origin;\n } catch {\n return url;\n }\n}\n\nfunction toErrorMessage(error: unknown): string {\n if (error instanceof Error) {\n const message = error.message.trim();\n return message.length > 0 ? message : \"request failed\";\n }\n const message = String(error ?? \"\").trim();\n return message.length > 0 ? message : \"request failed\";\n}\n\nfunction shouldWrapNetworkRequestError(error: unknown): boolean {\n if (error instanceof TypeError) {\n return true;\n }\n if (\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n typeof error.code === \"string\" &&\n error.code.startsWith(\"ERR_SSL_\")\n ) {\n return true;\n }\n const message = toErrorMessage(error).toLowerCase();\n return (\n message.includes(\"fetch failed\") ||\n message.includes(\"failed to fetch\") ||\n message.includes(\"network request failed\") ||\n message.includes(\"ssl_decryption_failed_or_bad_record_mac\")\n );\n}\n","import {\n createOpenMeldApiClient,\n type OpenMeldApiClientFoundation,\n} from \"@openmeld/api-client\";\nimport {\n buildOpenMeldRequestContextHeaders,\n OPENMELD_HEADER_REQUESTED_ORGANIZATION_ID,\n} from \"@openmeld/gateway-contract\";\nimport { buildRequestAuthHeaders } from \"../config/request-headers\";\nimport { fetchSpaceRequestWithTimeout } from \"./fetch-with-timeout\";\n\nexport function createCliApiClientFoundation(\n baseUrl: string,\n options: {\n onAuthHeadersResolved?: (headers: Record<string, string>) => void;\n organizationId?: string;\n } = {}\n): OpenMeldApiClientFoundation {\n return createOpenMeldApiClient({\n baseUrl,\n transport: async (request) =>\n await fetchSpaceRequestWithTimeout({\n url: request.url,\n operation: request.operation,\n init: request.init,\n timeoutMs: request.timeoutMs,\n }),\n getAuthHeaders: async ({ requestUrl }) => {\n const headers = await buildRequestAuthHeaders({\n requestUrl,\n });\n if (options.organizationId) {\n headers[OPENMELD_HEADER_REQUESTED_ORGANIZATION_ID] =\n options.organizationId;\n }\n options.onAuthHeadersResolved?.(headers);\n return headers;\n },\n getRequestContextHeaders: async ({ requestContext, spacePassword }) =>\n buildOpenMeldRequestContextHeaders({\n requestContext,\n ...(spacePassword === undefined ? {} : { spacePassword }),\n }),\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"api-client-foundation-BJIJ540D.js","names":["resolveSpaceRequestTimeoutMsForDiagnostics","resolveSpaceRequestTimeoutMsForCliDiagnostics"],"sources":["../src/config/auth-request-compatibility.ts","../src/config/openmeld-request-context.ts","../src/config/request-headers.ts","../src/space/request-timeout.ts","../src/space/fetch-with-timeout.ts","../src/space/api-client-foundation.ts"],"sourcesContent":["import { normalizeBaseUrl } from \"../protocol/urls\";\nimport type { StoredAuthSession } from \"./auth-session\";\n\nexport type AuthRequestCompatibilityReason =\n | \"invalid_request_url\"\n | \"invalid_auth_url\"\n | \"insecure_transport\"\n | \"host_mismatch\"\n | \"loopback\"\n | \"same_host\"\n | \"gateway_sibling\";\n\nexport type AuthRequestCompatibility = {\n compatible: boolean;\n reason: AuthRequestCompatibilityReason;\n requestHost: string | null;\n authHost: string | null;\n expectedGatewayHost: string | null;\n};\n\nexport function resolveAuthRequestCompatibility(input: {\n session: StoredAuthSession;\n requestUrl: string;\n}): AuthRequestCompatibility {\n const requestUrl = parseUrlOrNull(input.requestUrl);\n if (!requestUrl) {\n return {\n compatible: false,\n reason: \"invalid_request_url\",\n requestHost: null,\n authHost: null,\n expectedGatewayHost: null,\n };\n }\n\n const authBaseUrl = parseUrlOrNull(input.session.authBaseUrl);\n if (!authBaseUrl) {\n return {\n compatible: false,\n reason: \"invalid_auth_url\",\n requestHost: requestUrl.host,\n authHost: null,\n expectedGatewayHost: null,\n };\n }\n\n const expectedGatewayHost = deriveGatewayHost(authBaseUrl);\n const requestHost = requestUrl.host;\n const authHost = authBaseUrl.host;\n\n if (\n isLoopbackHostname(requestUrl.hostname) &&\n isLoopbackHostname(authBaseUrl.hostname)\n ) {\n return {\n compatible: true,\n reason: \"loopback\",\n requestHost,\n authHost,\n expectedGatewayHost,\n };\n }\n\n if (!isSecureTransportProtocol(requestUrl.protocol)) {\n return {\n compatible: false,\n reason: \"insecure_transport\",\n requestHost,\n authHost,\n expectedGatewayHost,\n };\n }\n\n if (requestHost === authHost) {\n return {\n compatible: true,\n reason: \"same_host\",\n requestHost,\n authHost,\n expectedGatewayHost,\n };\n }\n\n if (expectedGatewayHost && requestHost === expectedGatewayHost) {\n return {\n compatible: true,\n reason: \"gateway_sibling\",\n requestHost,\n authHost,\n expectedGatewayHost,\n };\n }\n\n return {\n compatible: false,\n reason: \"host_mismatch\",\n requestHost,\n authHost,\n expectedGatewayHost,\n };\n}\n\nexport function canUseAuthSessionForRequest(input: {\n session: StoredAuthSession;\n requestUrl: string;\n}): boolean {\n return resolveAuthRequestCompatibility(input).compatible;\n}\n\nexport function deriveAuthBaseUrlFromGatewayUrl(\n gatewayUrl: string\n): string | null {\n const parsed = parseUrlOrNull(gatewayUrl);\n if (!parsed) {\n return null;\n }\n if (!isHttpTransportProtocol(parsed.protocol)) {\n return null;\n }\n if (!parsed.hostname.startsWith(\"gateway.\")) {\n return null;\n }\n\n const authUrl = new URL(parsed.toString());\n authUrl.hostname = `auth.${parsed.hostname.slice(\"gateway.\".length)}`;\n authUrl.pathname = \"/\";\n authUrl.search = \"\";\n authUrl.hash = \"\";\n return normalizeBaseUrl(authUrl.toString());\n}\n\nfunction deriveGatewayHost(authBaseUrl: URL): string | null {\n if (!authBaseUrl.hostname.startsWith(\"auth.\")) {\n return null;\n }\n\n const gatewayUrl = new URL(authBaseUrl.toString());\n gatewayUrl.hostname = `gateway.${authBaseUrl.hostname.slice(\"auth.\".length)}`;\n return gatewayUrl.host;\n}\n\nfunction parseUrlOrNull(value: string): URL | null {\n try {\n return new URL(value);\n } catch {\n return null;\n }\n}\n\nfunction isLoopbackHostname(hostname: string): boolean {\n return (\n hostname === \"localhost\" || hostname === \"127.0.0.1\" || hostname === \"::1\"\n );\n}\n\nfunction isSecureTransportProtocol(protocol: string): boolean {\n return protocol === \"https:\" || protocol === \"wss:\";\n}\n\nfunction isHttpTransportProtocol(protocol: string): boolean {\n return protocol === \"http:\" || protocol === \"https:\";\n}\n","import crypto from \"node:crypto\";\nimport type { OpenMeldRequestContext } from \"@openmeld/schemas/types\";\nimport type { OpenMeldProfile } from \"./openmeld-profiles-api\";\n\nexport type OpenMeldRequestContextProfileIdentity = {\n openMeldProfileId: string;\n profileKind?: \"human\" | \"agent\" | \"system\";\n kind?: \"human\" | \"agent\";\n profileHandle?: string;\n profileName: string;\n ownerUserId?: string;\n ownerName?: string;\n agentControllerConversationId?: string;\n};\n\nexport function buildOpenMeldRequestContextFromProfile(input: {\n openMeldProfile: OpenMeldProfile;\n requestId?: string;\n agentControllerConversationId?: string;\n}): OpenMeldRequestContext {\n const requestId =\n normalizeOptionalText(input.requestId) ?? crypto.randomUUID();\n const agentControllerConversationId = normalizeOptionalText(\n input.agentControllerConversationId\n );\n const ownerName = normalizeOptionalText(input.openMeldProfile.ownerName);\n\n return {\n actorContext: {\n requestId,\n openMeldProfileId: input.openMeldProfile.openMeldProfileId,\n profileKind: input.openMeldProfile.profileKind,\n profileHandle: input.openMeldProfile.profileHandle,\n profileName: input.openMeldProfile.profileName,\n ownerUserId: input.openMeldProfile.ownerUserId,\n ...(ownerName ? { ownerName } : {}),\n },\n ...(agentControllerConversationId ? { agentControllerConversationId } : {}),\n };\n}\n\nexport function buildOpenMeldRequestContextFromProfileIdentity(input: {\n profileIdentity: OpenMeldRequestContextProfileIdentity;\n requestId?: string;\n}): OpenMeldRequestContext {\n const requestId =\n normalizeOptionalText(input.requestId) ?? crypto.randomUUID();\n const profileHandle = normalizeOptionalText(\n input.profileIdentity.profileHandle\n );\n const ownerUserId = normalizeOptionalText(input.profileIdentity.ownerUserId);\n const ownerName = normalizeOptionalText(input.profileIdentity.ownerName);\n const agentControllerConversationId = normalizeOptionalText(\n input.profileIdentity.agentControllerConversationId\n );\n const profileKind =\n input.profileIdentity.profileKind ??\n (input.profileIdentity.kind === \"human\" ||\n input.profileIdentity.kind === \"agent\"\n ? input.profileIdentity.kind\n : \"system\");\n\n return {\n actorContext: {\n requestId,\n openMeldProfileId: input.profileIdentity.openMeldProfileId,\n profileKind,\n ...(profileHandle ? { profileHandle } : {}),\n profileName: input.profileIdentity.profileName,\n ...(ownerUserId ? { ownerUserId } : {}),\n ...(ownerName ? { ownerName } : {}),\n },\n ...(agentControllerConversationId ? { agentControllerConversationId } : {}),\n };\n}\n\nfunction normalizeOptionalText(value: unknown): string | null {\n const normalized = String(value ?? \"\").trim();\n return normalized.length > 0 ? normalized : null;\n}\n","import {\n buildOpenMeldRequestContextHeaders,\n type OpenMeldRequestContextHeadersInput,\n} from \"@openmeld/gateway-contract\";\nimport type { OpenMeldRequestContext } from \"@openmeld/schemas/types\";\nimport {\n type AuthRequestCompatibilityReason,\n canUseAuthSessionForRequest,\n resolveAuthRequestCompatibility,\n} from \"./auth-request-compatibility\";\nimport { getAuthSessionState, type StoredAuthSession } from \"./auth-session\";\nimport type { OpenMeldProfile } from \"./openmeld-profiles-api\";\nimport {\n buildOpenMeldRequestContextFromProfile,\n buildOpenMeldRequestContextFromProfileIdentity,\n type OpenMeldRequestContextProfileIdentity,\n} from \"./openmeld-request-context\";\n\nconst DEFAULT_TOKEN_TYPE = \"Bearer\";\nconst AUTHORIZATION_HEADER = \"Authorization\";\n\ntype RequestAuthHeadersInput = {\n authSession?: StoredAuthSession | null;\n requestUrl: string;\n};\n\ntype OpenMeldRequestContextHeadersWithAuthInput =\n OpenMeldRequestContextHeadersInput & {\n authSession?: StoredAuthSession | null;\n requestUrl: string;\n };\n\nexport type AuthTokenAttachment =\n | {\n status: \"attachable\";\n token: string;\n tokenType: string;\n }\n | {\n status: \"dropped\";\n reason: \"empty_token\" | AuthRequestCompatibilityReason;\n requestHost: string | null;\n authHost: string | null;\n expectedGatewayHost: string | null;\n };\n\nexport type DroppedAuthTokenAttachment = Extract<\n AuthTokenAttachment,\n { status: \"dropped\" }\n>;\n\nexport async function buildRequestAuthHeaders(\n input: RequestAuthHeadersInput\n): Promise<Record<string, string>> {\n const headers: Record<string, string> = {};\n await attachAuthHeader(headers, input);\n return headers;\n}\n\nexport async function buildOpenMeldRequestContextHeadersWithAuth(\n input: OpenMeldRequestContextHeadersWithAuthInput\n): Promise<Record<string, string>> {\n const headers = buildOpenMeldRequestContextHeaders(input);\n await attachAuthHeader(headers, input);\n return headers;\n}\n\nexport async function buildOpenMeldProfileRequestHeadersWithAuth(input: {\n openMeldProfile: OpenMeldProfile;\n requestUrl: string;\n authSession?: StoredAuthSession | null;\n agentControllerConversationId?: string;\n spacePassword?: string;\n}): Promise<Record<string, string>> {\n return await buildOpenMeldRequestContextHeadersWithAuth({\n requestContext: buildOpenMeldRequestContextFromProfile({\n openMeldProfile: input.openMeldProfile,\n agentControllerConversationId: input.agentControllerConversationId,\n }),\n requestUrl: input.requestUrl,\n ...(input.authSession === undefined\n ? {}\n : { authSession: input.authSession }),\n ...(input.spacePassword === undefined\n ? {}\n : { spacePassword: input.spacePassword }),\n });\n}\n\nexport async function buildOpenMeldProfileIdentityRequestHeadersWithAuth(input: {\n profileIdentity: OpenMeldRequestContextProfileIdentity;\n requestUrl: string;\n authSession?: StoredAuthSession | null;\n spacePassword?: string;\n}): Promise<Record<string, string>> {\n return await buildOpenMeldRequestContextHeadersWithAuth({\n requestContext: buildOpenMeldRequestContextFromProfileIdentity({\n profileIdentity: input.profileIdentity,\n }),\n requestUrl: input.requestUrl,\n ...(input.authSession === undefined\n ? {}\n : { authSession: input.authSession }),\n ...(input.spacePassword === undefined\n ? {}\n : { spacePassword: input.spacePassword }),\n });\n}\n\nexport function withSpacePassword(\n requestContext: OpenMeldRequestContext,\n spacePassword?: string\n): OpenMeldRequestContextHeadersInput {\n return {\n requestContext,\n ...(spacePassword === undefined ? {} : { spacePassword }),\n };\n}\n\n// One decision for \"can this stored session authenticate this request\", with\n// the drop reason preserved. Header building and the daemon stream connect\n// gate must share this so they cannot drift apart.\nexport function resolveAuthTokenAttachment(input: {\n session: StoredAuthSession;\n requestUrl: string;\n}): AuthTokenAttachment {\n const compatibility = resolveAuthRequestCompatibility({\n session: input.session,\n requestUrl: input.requestUrl,\n });\n const token = normalizeAccessToken(input.session);\n if (!token) {\n return {\n status: \"dropped\",\n reason: \"empty_token\",\n requestHost: compatibility.requestHost,\n authHost: compatibility.authHost,\n expectedGatewayHost: compatibility.expectedGatewayHost,\n };\n }\n if (!compatibility.compatible) {\n return {\n status: \"dropped\",\n reason: compatibility.reason,\n requestHost: compatibility.requestHost,\n authHost: compatibility.authHost,\n expectedGatewayHost: compatibility.expectedGatewayHost,\n };\n }\n return {\n status: \"attachable\",\n token,\n tokenType: normalizeTokenType(input.session.tokenType),\n };\n}\n\nasync function attachAuthHeader(\n headers: Record<string, string>,\n input: RequestAuthHeadersInput\n): Promise<void> {\n const session = await resolveAuthSessionForHeaders(input);\n if (session === null) {\n // No stored credentials exist, so there is nothing to strip: the caller\n // is knowingly sending an unauthenticated request.\n return;\n }\n\n const attachment = resolveAuthTokenAttachment({\n session,\n requestUrl: input.requestUrl,\n });\n if (attachment.status === \"dropped\") {\n // The caller holds a session it believes is usable. Dropping the token is\n // still the safe outcome (never leak credentials to an incompatible\n // host), but it must stay visible in diagnostics instead of silently\n // dialing bare and surfacing as a remote 401.\n warnDroppedAuthToken(attachment);\n return;\n }\n headers[AUTHORIZATION_HEADER] = `${attachment.tokenType} ${attachment.token}`;\n}\n\nfunction warnDroppedAuthToken(attachment: DroppedAuthTokenAttachment): void {\n console.warn(\"[openmeld.auth.request_token_dropped]\", {\n authHost: attachment.authHost,\n expectedGatewayHost: attachment.expectedGatewayHost,\n reason: attachment.reason,\n requestHost: attachment.requestHost,\n });\n}\n\nasync function resolveAuthSessionForHeaders(\n input: RequestAuthHeadersInput\n): Promise<StoredAuthSession | null> {\n if (input.authSession !== undefined) {\n return input.authSession;\n }\n\n const sessionState = await getAuthSessionState();\n if (sessionState.state !== \"valid\" || sessionState.session === null) {\n return null;\n }\n\n return sessionState.session;\n}\n\nfunction normalizeAccessToken(session: StoredAuthSession): string {\n return String(session.accessToken ?? \"\").trim();\n}\n\nfunction normalizeTokenType(tokenType: string | undefined): string {\n const normalized = String(tokenType ?? \"\").trim();\n return normalized.length > 0 ? normalized : DEFAULT_TOKEN_TYPE;\n}\n\nexport function canAttachAuthTokenToRequest(\n session: StoredAuthSession,\n requestUrl: string\n): boolean {\n return canUseAuthSessionForRequest({\n session,\n requestUrl,\n });\n}\n","import {\n DEFAULT_SPACE_CONVERSATION_VALIDATE_TIMEOUT_MS,\n DEFAULT_SPACE_REQUEST_TIMEOUT_MS,\n MAX_SPACE_REQUEST_TIMEOUT_MS,\n MIN_SPACE_REQUEST_TIMEOUT_MS,\n} from \"../strategy-constants\";\n\nconst SPACE_REQUEST_TIMEOUT_ENV_KEY = \"OPENMELD_SPACE_REQUEST_TIMEOUT_MS\";\n\nexport function resolveSpaceRequestTimeoutMs(override?: number): number {\n if (isFinitePositiveNumber(override)) {\n return clampSpaceRequestTimeoutMs(override);\n }\n\n const fromEnv = Number.parseInt(\n String(process.env[SPACE_REQUEST_TIMEOUT_ENV_KEY] ?? \"\"),\n 10\n );\n if (isFinitePositiveNumber(fromEnv)) {\n return clampSpaceRequestTimeoutMs(fromEnv);\n }\n\n return DEFAULT_SPACE_REQUEST_TIMEOUT_MS;\n}\n\nexport function resolveSpaceRequestTimeoutMsForDiagnostics(): number {\n return resolveSpaceRequestTimeoutMs(undefined);\n}\n\nexport function resolveSpaceConversationValidateTimeoutMs(): number {\n return Math.max(\n resolveSpaceRequestTimeoutMs(undefined),\n DEFAULT_SPACE_CONVERSATION_VALIDATE_TIMEOUT_MS\n );\n}\n\nfunction clampSpaceRequestTimeoutMs(value: number): number {\n const normalized = Math.trunc(value);\n return Math.max(\n MIN_SPACE_REQUEST_TIMEOUT_MS,\n Math.min(MAX_SPACE_REQUEST_TIMEOUT_MS, normalized)\n );\n}\n\nfunction isFinitePositiveNumber(value: unknown): value is number {\n return typeof value === \"number\" && Number.isFinite(value) && value > 0;\n}\n","import {\n resolveSpaceRequestTimeoutMs,\n resolveSpaceRequestTimeoutMsForDiagnostics as resolveSpaceRequestTimeoutMsForCliDiagnostics,\n} from \"./request-timeout\";\n\nexport async function fetchSpaceRequestWithTimeout(input: {\n url: string;\n operation: string;\n init?: RequestInit;\n timeoutMs?: number;\n}): Promise<Response> {\n const timeoutMs = resolveSpaceRequestTimeoutMs(input.timeoutMs);\n const timeoutSignal = AbortSignal.timeout(timeoutMs);\n const composed = composeAbortSignals(input.init?.signal, timeoutSignal);\n\n try {\n try {\n return await fetch(input.url, {\n ...input.init,\n signal: composed.signal,\n });\n } catch (error) {\n // A keep-alive connection that a proxy silently dropped fails exactly\n // once and undici evicts it; the retry rides a fresh connection. This\n // is what keeps a long-lived service working behind flaky proxies\n // without asking users to touch their network config.\n if (\n timeoutSignal.aborted ||\n composed.signal.aborted ||\n !shouldWrapNetworkRequestError(error)\n ) {\n throw error;\n }\n return await fetch(input.url, {\n ...input.init,\n signal: composed.signal,\n });\n }\n } catch (error) {\n if (timeoutSignal.aborted) {\n throw createSpaceRequestTimeoutError({\n operation: input.operation,\n timeoutMs,\n cause: error,\n });\n }\n if (shouldWrapNetworkRequestError(error)) {\n throw createSpaceRequestNetworkError({\n operation: input.operation,\n url: input.url,\n cause: error,\n });\n }\n throw error;\n } finally {\n composed.cleanup();\n }\n}\n\nexport function resolveSpaceRequestTimeoutMsForDiagnostics(): number {\n return resolveSpaceRequestTimeoutMsForCliDiagnostics();\n}\n\nfunction createSpaceRequestTimeoutError(input: {\n operation: string;\n timeoutMs: number;\n cause: unknown;\n}): Error {\n const error = new Error(\n `${input.operation} request timed out after ${input.timeoutMs}ms`,\n { cause: input.cause }\n ) as Error & { code?: string };\n error.code = \"network.timeout\";\n return error;\n}\n\nfunction createSpaceRequestNetworkError(input: {\n operation: string;\n url: string;\n cause: unknown;\n}): Error {\n const error = new Error(\n `${input.operation} request could not reach ${describeRequestTarget(input.url)} (${toErrorMessage(input.cause)})`,\n { cause: input.cause }\n ) as Error & { code?: string };\n error.code = \"network.request_failed\";\n return error;\n}\n\nfunction composeAbortSignals(\n parent: AbortSignal | null | undefined,\n timeout: AbortSignal\n): { signal: AbortSignal; cleanup: () => void } {\n if (!parent) {\n return {\n signal: timeout,\n cleanup: () => undefined,\n };\n }\n\n if (parent.aborted || timeout.aborted) {\n const controller = new AbortController();\n controller.abort();\n return {\n signal: controller.signal,\n cleanup: () => undefined,\n };\n }\n\n const controller = new AbortController();\n const abort = () => {\n controller.abort();\n };\n\n parent.addEventListener(\"abort\", abort, { once: true });\n timeout.addEventListener(\"abort\", abort, { once: true });\n\n return {\n signal: controller.signal,\n cleanup: () => {\n parent.removeEventListener(\"abort\", abort);\n timeout.removeEventListener(\"abort\", abort);\n },\n };\n}\n\nfunction describeRequestTarget(url: string): string {\n try {\n return new URL(url).origin;\n } catch {\n return url;\n }\n}\n\nfunction toErrorMessage(error: unknown): string {\n if (error instanceof Error) {\n const message = error.message.trim();\n return message.length > 0 ? message : \"request failed\";\n }\n const message = String(error ?? \"\").trim();\n return message.length > 0 ? message : \"request failed\";\n}\n\nfunction shouldWrapNetworkRequestError(error: unknown): boolean {\n if (error instanceof TypeError) {\n return true;\n }\n if (\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n typeof error.code === \"string\" &&\n error.code.startsWith(\"ERR_SSL_\")\n ) {\n return true;\n }\n const message = toErrorMessage(error).toLowerCase();\n return (\n message.includes(\"fetch failed\") ||\n message.includes(\"failed to fetch\") ||\n message.includes(\"network request failed\") ||\n message.includes(\"ssl_decryption_failed_or_bad_record_mac\")\n );\n}\n","import {\n createOpenMeldApiClient,\n type OpenMeldApiClientFoundation,\n} from \"@openmeld/api-client\";\nimport {\n buildOpenMeldRequestContextHeaders,\n OPENMELD_HEADER_REQUESTED_ORGANIZATION_ID,\n} from \"@openmeld/gateway-contract\";\nimport { buildRequestAuthHeaders } from \"../config/request-headers\";\nimport { fetchSpaceRequestWithTimeout } from \"./fetch-with-timeout\";\n\nexport function createCliApiClientFoundation(\n baseUrl: string,\n options: {\n onAuthHeadersResolved?: (headers: Record<string, string>) => void;\n organizationId?: string;\n } = {}\n): OpenMeldApiClientFoundation {\n return createOpenMeldApiClient({\n baseUrl,\n transport: async (request) =>\n await fetchSpaceRequestWithTimeout({\n url: request.url,\n operation: request.operation,\n init: request.init,\n timeoutMs: request.timeoutMs,\n }),\n getAuthHeaders: async ({ requestUrl }) => {\n const headers = await buildRequestAuthHeaders({\n requestUrl,\n });\n if (options.organizationId) {\n headers[OPENMELD_HEADER_REQUESTED_ORGANIZATION_ID] =\n options.organizationId;\n }\n options.onAuthHeadersResolved?.(headers);\n return headers;\n },\n getRequestContextHeaders: async ({ requestContext, spacePassword }) =>\n buildOpenMeldRequestContextHeaders({\n requestContext,\n ...(spacePassword === undefined ? {} : { spacePassword }),\n }),\n });\n}\n"],"mappings":"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"}
@@ -3,10 +3,69 @@
3
3
  import { Nt as openMeldRootDir, _n as __exportAll } from "./base-url-Cv9x5Es9.js";
4
4
  import { t as CURRENT_DAEMON_EXECUTION_CONTRACT_EPOCH } from "./runtime-transport-J50KvRbm.js";
5
5
  import { createRequire } from "node:module";
6
+ import { z } from "zod/v4";
6
7
  import { join, resolve } from "node:path";
7
8
  import { createHash, randomUUID } from "node:crypto";
8
9
  import { chmod, mkdir, open, readFile, rename, rm, writeFile } from "node:fs/promises";
10
+ import { spawn } from "node:child_process";
9
11
  import { fileURLToPath } from "node:url";
12
+ //#region ../../packages/schemas/dist/schemas/local-machine/macos-keychain-helper.js
13
+ const MAC_OS_KEYCHAIN_AUTHENTICATION_INTERACTION = "disallow";
14
+ const macOsKeychainServiceSchema = z.string().trim().min(1).max(512);
15
+ const macOsKeychainAccountSchema = z.string().trim().min(1).max(512);
16
+ const macOsKeychainAccessTokenSchema = z.string().min(1).max(65536);
17
+ const macOsKeychainHelperOperationSchema = z.enum([
18
+ "store",
19
+ "read",
20
+ "delete"
21
+ ]);
22
+ const macOsKeychainHelperRequestSchema = z.discriminatedUnion("operation", [
23
+ z.strictObject({
24
+ schemaVersion: z.literal(2),
25
+ operation: z.literal("store"),
26
+ service: macOsKeychainServiceSchema,
27
+ account: macOsKeychainAccountSchema,
28
+ accessToken: macOsKeychainAccessTokenSchema,
29
+ authenticationInteraction: z.literal(MAC_OS_KEYCHAIN_AUTHENTICATION_INTERACTION)
30
+ }),
31
+ z.strictObject({
32
+ schemaVersion: z.literal(2),
33
+ operation: z.literal("read"),
34
+ service: macOsKeychainServiceSchema,
35
+ account: macOsKeychainAccountSchema,
36
+ authenticationInteraction: z.literal(MAC_OS_KEYCHAIN_AUTHENTICATION_INTERACTION)
37
+ }),
38
+ z.strictObject({
39
+ schemaVersion: z.literal(2),
40
+ operation: z.literal("delete"),
41
+ service: macOsKeychainServiceSchema,
42
+ account: macOsKeychainAccountSchema,
43
+ authenticationInteraction: z.literal(MAC_OS_KEYCHAIN_AUTHENTICATION_INTERACTION)
44
+ })
45
+ ]);
46
+ const macOsKeychainHelperMutationSuccessSchema = z.strictObject({
47
+ schemaVersion: z.literal(2),
48
+ ok: z.literal(true),
49
+ operation: z.enum(["store", "delete"])
50
+ });
51
+ const macOsKeychainHelperReadSuccessSchema = z.strictObject({
52
+ schemaVersion: z.literal(2),
53
+ ok: z.literal(true),
54
+ operation: z.literal("read"),
55
+ accessToken: z.union([macOsKeychainAccessTokenSchema, z.null()])
56
+ });
57
+ const macOsKeychainHelperErrorSchema = z.strictObject({
58
+ schemaVersion: z.literal(2),
59
+ ok: z.literal(false),
60
+ operation: macOsKeychainHelperOperationSchema,
61
+ errorMessage: z.string().trim().min(1).max(2048)
62
+ });
63
+ const macOsKeychainHelperResponseSchema = z.union([
64
+ macOsKeychainHelperMutationSuccessSchema,
65
+ macOsKeychainHelperReadSuccessSchema,
66
+ macOsKeychainHelperErrorSchema
67
+ ]);
68
+ //#endregion
10
69
  //#region src/strategy-constants.ts
11
70
  const DEFAULT_GATEWAY_CHAIN_TIMEOUT_MS = 3e4;
12
71
  const DEFAULT_REMOTE_SESSION_TIMEOUT_MS = 8e3;
@@ -49,16 +108,208 @@ function isBinaryDistribution() {
49
108
  }
50
109
  //#endregion
51
110
  //#region src/config/macos-native-keychain.ts
111
+ const MAC_OS_KEYCHAIN_HELPER_ARG = "__openmeld_macos_keychain_helper";
112
+ const HELPER_OUTPUT_MAX_BYTES = 128 * 1024;
52
113
  let loadedAddon = null;
114
+ let unresponsiveKeychainError = null;
53
115
  async function storeMacOsNativeKeychainToken(input) {
116
+ if (isBinaryDistribution()) {
117
+ await runBoundedMacOsNativeKeychainRequest({
118
+ operation: "store",
119
+ service: input.service,
120
+ account: input.account,
121
+ accessToken: input.accessToken
122
+ });
123
+ return;
124
+ }
54
125
  (await loadAddon()).store(input.service, input.account, input.accessToken);
55
126
  }
56
127
  async function readMacOsNativeKeychainToken(input) {
128
+ if (isBinaryDistribution()) return await runBoundedMacOsNativeKeychainRequest({
129
+ operation: "read",
130
+ service: input.service,
131
+ account: input.account
132
+ });
57
133
  return (await loadAddon()).read(input.service, input.account);
58
134
  }
59
135
  async function deleteMacOsNativeKeychainToken(input) {
136
+ if (isBinaryDistribution()) {
137
+ await runBoundedMacOsNativeKeychainRequest({
138
+ operation: "delete",
139
+ service: input.service,
140
+ account: input.account
141
+ });
142
+ return;
143
+ }
60
144
  (await loadAddon()).remove(input.service, input.account);
61
145
  }
146
+ async function runMacOsNativeKeychainRequestInChild(input, options = {}) {
147
+ const request = macOsKeychainHelperRequestSchema.parse({
148
+ schemaVersion: 2,
149
+ authenticationInteraction: MAC_OS_KEYCHAIN_AUTHENTICATION_INTERACTION,
150
+ ...input
151
+ });
152
+ const timeoutMs = options.timeoutMs ?? 5e3;
153
+ if (!(Number.isSafeInteger(timeoutMs) && timeoutMs > 0)) throw new Error("macOS Keychain helper timeout must be a positive integer");
154
+ return await new Promise((resolve, reject) => {
155
+ const child = spawn(process.execPath, [MAC_OS_KEYCHAIN_HELPER_ARG], {
156
+ env: process.env,
157
+ shell: false,
158
+ stdio: [
159
+ "pipe",
160
+ "pipe",
161
+ "pipe"
162
+ ],
163
+ windowsHide: true
164
+ });
165
+ let settled = false;
166
+ let stdout = "";
167
+ let stderr = "";
168
+ const clearDeadline = () => {
169
+ clearTimeout(deadline);
170
+ };
171
+ const rejectOnce = (error) => {
172
+ if (settled) return;
173
+ settled = true;
174
+ clearDeadline();
175
+ reject(error);
176
+ };
177
+ const deadline = setTimeout(() => {
178
+ if (settled) return;
179
+ settled = true;
180
+ child.kill("SIGKILL");
181
+ reject(new MacOsNativeKeychainTimeoutError(`macOS Keychain did not respond within ${formatTimeout(timeoutMs)}`));
182
+ }, timeoutMs);
183
+ child.stdout.setEncoding("utf8");
184
+ child.stderr.setEncoding("utf8");
185
+ child.stdout.on("data", (chunk) => {
186
+ stdout += String(chunk);
187
+ if (Buffer.byteLength(stdout, "utf8") > HELPER_OUTPUT_MAX_BYTES) {
188
+ child.kill("SIGKILL");
189
+ rejectOnce(/* @__PURE__ */ new Error("macOS Keychain helper output was too large"));
190
+ }
191
+ });
192
+ child.stderr.on("data", (chunk) => {
193
+ stderr += String(chunk);
194
+ if (Buffer.byteLength(stderr, "utf8") > HELPER_OUTPUT_MAX_BYTES) stderr = stderr.slice(-131072);
195
+ });
196
+ child.once("error", (error) => {
197
+ rejectOnce(/* @__PURE__ */ new Error(`macOS Keychain helper could not start: ${toErrorMessage$1(error)}`));
198
+ });
199
+ child.stdin.once("error", (error) => {
200
+ rejectOnce(/* @__PURE__ */ new Error(`macOS Keychain helper input failed: ${toErrorMessage$1(error)}`));
201
+ });
202
+ child.once("close", (code) => {
203
+ if (settled) return;
204
+ clearDeadline();
205
+ settled = true;
206
+ try {
207
+ resolve(parseMacOsKeychainHelperResult({
208
+ code,
209
+ operation: request.operation,
210
+ stderr,
211
+ stdout
212
+ }));
213
+ } catch (error) {
214
+ reject(toError(error));
215
+ }
216
+ });
217
+ child.stdin.end(JSON.stringify(request), "utf8");
218
+ });
219
+ }
220
+ async function runMacOsNativeKeychainHelperIfRequested(argv = process.argv) {
221
+ if (!argv.includes(MAC_OS_KEYCHAIN_HELPER_ARG)) return false;
222
+ if (!(isBinaryDistribution() && process.platform === "darwin")) throw new Error("the internal macOS Keychain helper is only available in the macOS binary");
223
+ const rawRequest = await readHelperStdin();
224
+ let json;
225
+ try {
226
+ json = JSON.parse(rawRequest);
227
+ } catch {
228
+ throw new Error("invalid macOS Keychain helper request");
229
+ }
230
+ const request = macOsKeychainHelperRequestSchema.safeParse(json);
231
+ if (!request.success) throw new Error("invalid macOS Keychain helper request");
232
+ const response = await executeHelperRequest(request.data).catch((error) => ({
233
+ schemaVersion: 2,
234
+ ok: false,
235
+ operation: request.data.operation,
236
+ errorMessage: truncateErrorMessage(toErrorMessage$1(error))
237
+ }));
238
+ process.stdout.write(JSON.stringify(response));
239
+ return true;
240
+ }
241
+ async function runBoundedMacOsNativeKeychainRequest(input) {
242
+ if (unresponsiveKeychainError) throw unresponsiveKeychainError;
243
+ try {
244
+ if (input.operation === "read") return await runMacOsNativeKeychainRequestInChild(input);
245
+ await runMacOsNativeKeychainRequestInChild(input);
246
+ } catch (error) {
247
+ if (error instanceof MacOsNativeKeychainTimeoutError) unresponsiveKeychainError = error;
248
+ throw error;
249
+ }
250
+ }
251
+ function parseMacOsKeychainHelperResult(input) {
252
+ if (input.code !== 0) throw new Error(`macOS Keychain helper exited with code ${input.code ?? "unknown"}${input.stderr.trim() ? `: ${input.stderr.trim()}` : ""}`);
253
+ let rawResponse;
254
+ try {
255
+ rawResponse = JSON.parse(input.stdout);
256
+ } catch {
257
+ throw new Error("macOS Keychain helper returned an invalid response");
258
+ }
259
+ const parsed = macOsKeychainHelperResponseSchema.safeParse(rawResponse);
260
+ if (!(parsed.success && parsed.data.operation === input.operation)) throw new Error("macOS Keychain helper returned an invalid response");
261
+ if (!parsed.data.ok) throw new Error(parsed.data.errorMessage);
262
+ return parsed.data.operation === "read" ? parsed.data.accessToken : void 0;
263
+ }
264
+ async function executeHelperRequest(input) {
265
+ const addon = await loadAddon();
266
+ if (input.operation === "store") {
267
+ addon.store(input.service, input.account, input.accessToken);
268
+ return {
269
+ schemaVersion: 2,
270
+ ok: true,
271
+ operation: "store"
272
+ };
273
+ }
274
+ if (input.operation === "delete") {
275
+ addon.remove(input.service, input.account);
276
+ return {
277
+ schemaVersion: 2,
278
+ ok: true,
279
+ operation: "delete"
280
+ };
281
+ }
282
+ return {
283
+ schemaVersion: 2,
284
+ ok: true,
285
+ operation: "read",
286
+ accessToken: addon.read(input.service, input.account)
287
+ };
288
+ }
289
+ async function readHelperStdin() {
290
+ let raw = "";
291
+ process.stdin.setEncoding("utf8");
292
+ for await (const chunk of process.stdin) {
293
+ raw += String(chunk);
294
+ if (Buffer.byteLength(raw, "utf8") > HELPER_OUTPUT_MAX_BYTES) throw new Error("macOS Keychain helper request was too large");
295
+ }
296
+ return raw;
297
+ }
298
+ function truncateErrorMessage(message) {
299
+ return (message.trim() || "macOS Keychain operation failed").slice(0, 2048);
300
+ }
301
+ function formatTimeout(timeoutMs) {
302
+ return timeoutMs % 1e3 === 0 ? `${timeoutMs / 1e3} seconds` : `${timeoutMs} ms`;
303
+ }
304
+ function toErrorMessage$1(error) {
305
+ return error instanceof Error ? error.message : String(error);
306
+ }
307
+ function toError(error) {
308
+ return error instanceof Error ? error : new Error(String(error));
309
+ }
310
+ var MacOsNativeKeychainTimeoutError = class extends Error {
311
+ name = "MacOsNativeKeychainTimeoutError";
312
+ };
62
313
  async function loadAddon() {
63
314
  if (loadedAddon) return loadedAddon;
64
315
  if (process.platform !== "darwin") throw new Error("macOS Keychain is only available on macOS");
@@ -74,6 +325,7 @@ async function loadAddon() {
74
325
  const TOKEN_STORE_KEYCHAIN_SERVICE = "sh.openmeld.auth.token";
75
326
  const INSECURE_FALLBACK_ENV_KEY = "OPENMELD_AUTH_ALLOW_INSECURE_FILE_TOKEN";
76
327
  const FORCE_INSECURE_STORE_ENV_KEY = "OPENMELD_AUTH_FORCE_INSECURE_FILE_TOKEN";
328
+ const MAC_OS_KEYCHAIN_NONINTERACTIVE_UNAVAILABLE_MESSAGE = "macOS Keychain access is unavailable in this OpenMeld distribution. OpenMeld will not open an authorization window from an unattended process. Run setup or login with the current packaged OpenMeld CLI.";
77
329
  const COMMAND_MAX_BUFFER_BYTES = 1024 * 1024;
78
330
  const COMMAND_TIMEOUT_MS = 3e4;
79
331
  const TOKEN_FILE_KEY_PATTERN = /^[a-f0-9]{64}$/u;
@@ -106,11 +358,7 @@ async function storeAccessToken(input) {
106
358
  service: TOKEN_STORE_KEYCHAIN_SERVICE,
107
359
  accessToken: input.accessToken
108
360
  });
109
- else await setMacOsKeychainToken({
110
- service: TOKEN_STORE_KEYCHAIN_SERVICE,
111
- account,
112
- accessToken: input.accessToken
113
- });
361
+ else throw new Error(MAC_OS_KEYCHAIN_NONINTERACTIVE_UNAVAILABLE_MESSAGE);
114
362
  return {
115
363
  provider: "macos-keychain",
116
364
  service: TOKEN_STORE_KEYCHAIN_SERVICE,
@@ -174,7 +422,10 @@ async function storeAccessToken(input) {
174
422
  }
175
423
  async function readAccessToken(ref) {
176
424
  try {
177
- if (ref.provider === "macos-keychain") return toAccessTokenReadResult(shouldUseNativeMacOsKeychain() ? await readMacOsNativeKeychainToken(ref) : await getMacOsKeychainToken(ref));
425
+ if (ref.provider === "macos-keychain") {
426
+ if (!shouldUseNativeMacOsKeychain()) throw new Error(MAC_OS_KEYCHAIN_NONINTERACTIVE_UNAVAILABLE_MESSAGE);
427
+ return toAccessTokenReadResult(await readMacOsNativeKeychainToken(ref));
428
+ }
178
429
  if (ref.provider === "windows-dpapi") return toAccessTokenReadResult(await getWindowsDpapiToken(ref));
179
430
  if (ref.provider === "insecure-file") return toAccessTokenReadResult(await getInsecureFileToken(ref));
180
431
  return { status: "missing" };
@@ -187,7 +438,8 @@ async function readAccessToken(ref) {
187
438
  }
188
439
  async function deleteAccessToken(ref) {
189
440
  if (ref.provider === "macos-keychain") {
190
- await (shouldUseNativeMacOsKeychain() ? deleteMacOsNativeKeychainToken(ref) : deleteMacOsKeychainToken(ref)).catch(() => void 0);
441
+ if (!shouldUseNativeMacOsKeychain()) return;
442
+ await deleteMacOsNativeKeychainToken(ref).catch(() => void 0);
191
443
  return;
192
444
  }
193
445
  if (ref.provider === "windows-dpapi") {
@@ -217,47 +469,6 @@ function buildUniqueTokenFileKey(key) {
217
469
  function shouldUseNativeMacOsKeychain() {
218
470
  return isBinaryDistribution();
219
471
  }
220
- async function setMacOsKeychainToken(input) {
221
- await runCommand("security", [
222
- "add-generic-password",
223
- "-U",
224
- "-a",
225
- input.account,
226
- "-s",
227
- input.service,
228
- "-w",
229
- input.accessToken
230
- ]);
231
- }
232
- async function getMacOsKeychainToken(input) {
233
- try {
234
- return (await runCommand("security", [
235
- "find-generic-password",
236
- "-a",
237
- input.account,
238
- "-s",
239
- input.service,
240
- "-w"
241
- ])).stdout.trim();
242
- } catch (error) {
243
- if (isMacOsNotFoundError(error)) return null;
244
- throw error;
245
- }
246
- }
247
- async function deleteMacOsKeychainToken(input) {
248
- try {
249
- await runCommand("security", [
250
- "delete-generic-password",
251
- "-a",
252
- input.account,
253
- "-s",
254
- input.service
255
- ]);
256
- } catch (error) {
257
- if (isMacOsNotFoundError(error)) return;
258
- throw error;
259
- }
260
- }
261
472
  async function setWindowsDpapiToken(input) {
262
473
  const encrypted = await runPowerShellScript(WINDOWS_DPAPI_ENCRYPT_SCRIPT, input.accessToken, input.key);
263
474
  await mkdir(tokenDirectoryPath(), { recursive: true });
@@ -355,7 +566,6 @@ async function runPowerShellScript(script, token, entropy) {
355
566
  }
356
567
  async function runCommand(command, args, stdinPayload) {
357
568
  try {
358
- if (stdinPayload === void 0) return await runExecFile(command, args);
359
569
  const { execFile } = await import("node:child_process");
360
570
  return await new Promise((resolve, reject) => {
361
571
  let stdout = "";
@@ -389,24 +599,6 @@ async function runCommand(command, args, stdinPayload) {
389
599
  throw toCommandError(error, command);
390
600
  }
391
601
  }
392
- async function runExecFile(command, args) {
393
- const { execFile } = await import("node:child_process");
394
- return await new Promise((resolve, reject) => {
395
- execFile(command, args, {
396
- ...EXEC_FILE_BASE_OPTIONS,
397
- encoding: "utf8"
398
- }, (error, stdout, stderr) => {
399
- if (error) {
400
- reject(toCommandError(error, command));
401
- return;
402
- }
403
- resolve({
404
- stdout: String(stdout ?? ""),
405
- stderr: String(stderr ?? "")
406
- });
407
- });
408
- });
409
- }
410
602
  function toCommandError(error, command) {
411
603
  if (!(error && typeof error === "object")) return /* @__PURE__ */ new Error(`command failed (${command}): ${String(error)}`);
412
604
  const e = error;
@@ -420,12 +612,6 @@ function toCommandError(error, command) {
420
612
  wrapped.stderr = e.stderr;
421
613
  return wrapped;
422
614
  }
423
- function isMacOsNotFoundError(error) {
424
- if (!(error && typeof error === "object")) return false;
425
- const record = error;
426
- const text = `${record.stderr ?? ""} ${record.message ?? ""}`.toLowerCase();
427
- return record.code === 44 || text.includes("could not be found in the keychain") || text.includes("the specified item could not be found");
428
- }
429
615
  function normalizeString(value) {
430
616
  return String(value ?? "").trim();
431
617
  }
@@ -882,6 +1068,6 @@ async function removeSessionFileBestEffort() {
882
1068
  await rm(authSessionPath(), { force: true }).catch(() => void 0);
883
1069
  }
884
1070
  //#endregion
885
- export { ROUTE_CATALOG_LOAD_TIMEOUT_MS as A, MAX_SPACE_REQUEST_TIMEOUT_MS as C, PROVIDER_CONVERSATION_PROOF_SYNC_INTERVAL_MS as D, OPENCLAW_CLI_TIMEOUT_MS as E, RUNTIME_AGENT_CONTROLLER_REPORT_SYNC_RETRY_INTERVAL_MS as M, RUNTIME_STATE_PERSIST_MIN_INTERVAL_MS as N, PROVIDER_CONVERSATION_PROOF_SYNC_RETRY_INTERVAL_MS as O, MAX_HEARTBEAT_INTERVAL_MS as S, MIN_SPACE_REQUEST_TIMEOUT_MS as T, DAEMON_STREAM_KEEPALIVE_PONG_TIMEOUT_MS as _, getAuthSessionState as a, DEFAULT_SPACE_REQUEST_TIMEOUT_MS as b, setAuthSession as c, resolveOpenMeldDistribution as d, CATALOG_SYNC_RETRY_INTERVAL_MS as f, DAEMON_STREAM_KEEPALIVE_INTERVAL_MS as g, DAEMON_STREAM_CONNECT_TIMEOUT_MS as h, getAuthSessionMetadata as i, RUNTIME_AGENT_CONTROLLER_REPORT_SYNC_INTERVAL_MS as j, REGISTER_RESPONSE_TIMEOUT_MS as k, updateAuthSessionActiveOrganization as l, DAEMON_RUNTIME_CONTRACT_EPOCH as m, clearAuthSession as n, getCurrentAuthOwnerUserId as o, CATALOG_SYNC_SIGNAL_POLL_INTERVAL_MS as p, getAuthSession as r, normalizeStoredActiveOrganization as s, auth_session_exports as t, isBinaryDistribution as u, DEFAULT_GATEWAY_CHAIN_TIMEOUT_MS as v, MIN_HEARTBEAT_INTERVAL_MS as w, HEARTBEAT_RESPONSE_TIMEOUT_MS as x, DEFAULT_HEARTBEAT_INTERVAL_MS as y };
1071
+ export { REGISTER_RESPONSE_TIMEOUT_MS as A, MAX_HEARTBEAT_INTERVAL_MS as C, OPENCLAW_CLI_TIMEOUT_MS as D, MIN_SPACE_REQUEST_TIMEOUT_MS as E, RUNTIME_AGENT_CONTROLLER_REPORT_SYNC_INTERVAL_MS as M, RUNTIME_AGENT_CONTROLLER_REPORT_SYNC_RETRY_INTERVAL_MS as N, PROVIDER_CONVERSATION_PROOF_SYNC_INTERVAL_MS as O, RUNTIME_STATE_PERSIST_MIN_INTERVAL_MS as P, HEARTBEAT_RESPONSE_TIMEOUT_MS as S, MIN_HEARTBEAT_INTERVAL_MS as T, DAEMON_STREAM_KEEPALIVE_INTERVAL_MS as _, getAuthSessionState as a, DEFAULT_HEARTBEAT_INTERVAL_MS as b, setAuthSession as c, isBinaryDistribution as d, resolveOpenMeldDistribution as f, DAEMON_STREAM_CONNECT_TIMEOUT_MS as g, DAEMON_RUNTIME_CONTRACT_EPOCH as h, getAuthSessionMetadata as i, ROUTE_CATALOG_LOAD_TIMEOUT_MS as j, PROVIDER_CONVERSATION_PROOF_SYNC_RETRY_INTERVAL_MS as k, updateAuthSessionActiveOrganization as l, CATALOG_SYNC_SIGNAL_POLL_INTERVAL_MS as m, clearAuthSession as n, getCurrentAuthOwnerUserId as o, CATALOG_SYNC_RETRY_INTERVAL_MS as p, getAuthSession as r, normalizeStoredActiveOrganization as s, auth_session_exports as t, runMacOsNativeKeychainHelperIfRequested as u, DAEMON_STREAM_KEEPALIVE_PONG_TIMEOUT_MS as v, MAX_SPACE_REQUEST_TIMEOUT_MS as w, DEFAULT_SPACE_REQUEST_TIMEOUT_MS as x, DEFAULT_GATEWAY_CHAIN_TIMEOUT_MS as y };
886
1072
 
887
- //# sourceMappingURL=auth-session-CTkKQOEP.js.map
1073
+ //# sourceMappingURL=auth-session-BcT7IOfJ.js.map