@opentray/spec 0.14.4 → 0.15.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.
package/README.md CHANGED
@@ -11,6 +11,12 @@ Shared TypeScript protocol and contract package for OpenTray.
11
11
 
12
12
  This package is platform-neutral and must not import native implementation packages.
13
13
 
14
+ ## Broker Artifact Identity
15
+
16
+ `BrokerArtifactIdentity` identifies the exact broker executable selected by the SDK. It combines the caller package version, native target, executable SHA-256, and build identity. `BrokerReadyMetadata` persists that identity beside the caller-scoped endpoint, while the protocol `ready` frame carries the same identity to the connected SDK.
17
+
18
+ Use `isBrokerArtifactIdentity()` at untyped storage or transport boundaries and `brokerArtifactIdentityEquals()` when deciding whether a live broker can be reused. PID liveness, endpoint name, and package version alone are not compatibility evidence.
19
+
14
20
  ## Tray Contract
15
21
 
16
22
  `TrayOptions` uses `id` as the tray atom identity. Visible tray text belongs to the unified `icon` field:
package/dist/index.d.mts CHANGED
@@ -213,6 +213,40 @@ interface ExtensionEnvelope<TData = unknown> {
213
213
  scope: ExtensionScope;
214
214
  data: TData;
215
215
  }
216
+ interface ExtensionArtifactTarget {
217
+ os: string;
218
+ arch: string;
219
+ }
220
+ interface ExpectedExtensionIdentity {
221
+ extensionName: string;
222
+ artifactSetVersion: string;
223
+ contractFingerprint: string;
224
+ target: ExtensionArtifactTarget;
225
+ }
226
+ /** Operating-system and architecture identity for one broker executable. */
227
+ interface BrokerArtifactTarget {
228
+ os: "darwin" | "linux" | "win32";
229
+ arch: "arm64" | "x64";
230
+ }
231
+ /** Content-derived identity used to decide whether a live broker may be reused. */
232
+ interface BrokerArtifactIdentity {
233
+ packageVersion: string;
234
+ target: BrokerArtifactTarget;
235
+ executableHash: string;
236
+ buildIdentity: string;
237
+ }
238
+ /** Caller-scoped readiness evidence written by a successfully initialized broker. */
239
+ interface BrokerReadyMetadata {
240
+ pid: number;
241
+ endpoint: string;
242
+ packageVersion: string;
243
+ protocolVersion: number;
244
+ appId: AppId;
245
+ appName: string;
246
+ callerLabel: string;
247
+ executablePath: string;
248
+ brokerArtifactIdentity: BrokerArtifactIdentity;
249
+ }
216
250
  interface RuntimeHostSessionHealth {
217
251
  sessionId: number;
218
252
  internalSessionId?: SessionId;
@@ -281,6 +315,7 @@ type ClientRequestFrame = ({
281
315
  appId: AppId;
282
316
  name: string;
283
317
  path: string;
318
+ expectedIdentity: ExpectedExtensionIdentity;
284
319
  mountId?: string;
285
320
  } | {
286
321
  type: "ext-command";
@@ -302,6 +337,7 @@ type ServerFrame = {
302
337
  type: "ready";
303
338
  protocolVersion: number;
304
339
  brokerVersion: string;
340
+ brokerArtifactIdentity: BrokerArtifactIdentity;
305
341
  sessionId: SessionId;
306
342
  } | {
307
343
  type: "app-created";
@@ -354,7 +390,11 @@ interface ParseResult<T> {
354
390
  error?: string;
355
391
  }
356
392
  declare const parseServerFrame: (line: string) => ParseResult<ServerFrame>;
393
+ /** Returns true when an unknown value is a complete broker artifact identity. */
394
+ declare const isBrokerArtifactIdentity: (value: unknown) => value is BrokerArtifactIdentity;
395
+ /** Compares every compatibility-bearing broker artifact identity field. */
396
+ declare const brokerArtifactIdentityEquals: (left: BrokerArtifactIdentity, right: BrokerArtifactIdentity) => boolean;
357
397
  declare const isServerFrame: (value: unknown) => value is ServerFrame;
358
398
  //#endregion
359
- export { AppId, AppIdentity, AppOptions, AppRef, BrokerEndpointIdentity, BrokerEndpointIdentityOptions, CALLER_LABEL_MAX_LENGTH, ClientFrame, ClientRequestFrame, DEFAULT_CALLER_LABEL, DarwinIcon, DarwinIconText, ExtensionEnvelope, ExtensionScope, Icon, IconCandidates, IconImage, IconText, LinuxIcon, Menu, MenuItem, MenuItemId, MouseButton, OPENTRAY_PROTOCOL_FAMILY, OPENTRAY_PROTOCOL_LINE, OPENTRAY_PROTOCOL_LINE_MAJOR, OPENTRAY_PROTOCOL_LINE_MINOR, OpenTrayProtocolLine, PROTOCOL_VERSION, ParseResult, ProtocolDistTag, ProtocolDistTagOptions, ProtocolLineReleaseChannel, Rect, RequestId, RuntimeHostHealth, RuntimeHostSessionHealth, ServerFrame, SessionId, SimpleIcon, Tooltip, TrayBoundsKind, TrayBoundsResult, TrayEvent, TrayId, TrayOptions, Win32Icon, compareOpenTrayProtocolLine, createBrokerEndpointIdentity, formatBrokerEndpointName, formatBrokerProcessTitle, formatBrokerStateRoot, formatOpenTrayProtocolLine, formatProtocolDistTag, formatUnixSocketPath, formatWindowsPipeName, isOpenTrayProtocolLineCompatible, isProtocolLineReleaseChannel, isServerFrame, isSupportedProtocolVersion, parseProtocolDistTag, parseServerFrame, protocolLineReleaseChannels, sanitizeCallerLabel };
399
+ export { AppId, AppIdentity, AppOptions, AppRef, BrokerArtifactIdentity, BrokerArtifactTarget, BrokerEndpointIdentity, BrokerEndpointIdentityOptions, BrokerReadyMetadata, CALLER_LABEL_MAX_LENGTH, ClientFrame, ClientRequestFrame, DEFAULT_CALLER_LABEL, DarwinIcon, DarwinIconText, ExpectedExtensionIdentity, ExtensionArtifactTarget, ExtensionEnvelope, ExtensionScope, Icon, IconCandidates, IconImage, IconText, LinuxIcon, Menu, MenuItem, MenuItemId, MouseButton, OPENTRAY_PROTOCOL_FAMILY, OPENTRAY_PROTOCOL_LINE, OPENTRAY_PROTOCOL_LINE_MAJOR, OPENTRAY_PROTOCOL_LINE_MINOR, OpenTrayProtocolLine, PROTOCOL_VERSION, ParseResult, ProtocolDistTag, ProtocolDistTagOptions, ProtocolLineReleaseChannel, Rect, RequestId, RuntimeHostHealth, RuntimeHostSessionHealth, ServerFrame, SessionId, SimpleIcon, Tooltip, TrayBoundsKind, TrayBoundsResult, TrayEvent, TrayId, TrayOptions, Win32Icon, brokerArtifactIdentityEquals, compareOpenTrayProtocolLine, createBrokerEndpointIdentity, formatBrokerEndpointName, formatBrokerProcessTitle, formatBrokerStateRoot, formatOpenTrayProtocolLine, formatProtocolDistTag, formatUnixSocketPath, formatWindowsPipeName, isBrokerArtifactIdentity, isOpenTrayProtocolLineCompatible, isProtocolLineReleaseChannel, isServerFrame, isSupportedProtocolVersion, parseProtocolDistTag, parseServerFrame, protocolLineReleaseChannels, sanitizeCallerLabel };
360
400
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"mappings":"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"}
package/dist/index.mjs CHANGED
@@ -133,10 +133,14 @@ const parseServerFrame = (line) => {
133
133
  }
134
134
  };
135
135
  const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
136
+ /** Returns true when an unknown value is a complete broker artifact identity. */
137
+ const isBrokerArtifactIdentity = (value) => isRecord(value) && typeof value.packageVersion === "string" && isRecord(value.target) && (value.target.os === "darwin" || value.target.os === "linux" || value.target.os === "win32") && (value.target.arch === "arm64" || value.target.arch === "x64") && typeof value.executableHash === "string" && /^[a-f0-9]{64}$/u.test(value.executableHash) && typeof value.buildIdentity === "string" && value.buildIdentity.length > 0;
138
+ /** Compares every compatibility-bearing broker artifact identity field. */
139
+ const brokerArtifactIdentityEquals = (left, right) => left.packageVersion === right.packageVersion && left.target.os === right.target.os && left.target.arch === right.target.arch && left.executableHash === right.executableHash && left.buildIdentity === right.buildIdentity;
136
140
  const isServerFrame = (value) => {
137
141
  if (!isRecord(value) || typeof value.type !== "string") return false;
138
142
  switch (value.type) {
139
- case "ready": return typeof value.protocolVersion === "number" && typeof value.brokerVersion === "string" && typeof value.sessionId === "string";
143
+ case "ready": return typeof value.protocolVersion === "number" && typeof value.brokerVersion === "string" && isBrokerArtifactIdentity(value.brokerArtifactIdentity) && typeof value.sessionId === "string";
140
144
  case "app-created": return typeof value.requestId === "string" && isRecord(value.app);
141
145
  case "default-app": return typeof value.requestId === "string" && isRecord(value.app);
142
146
  case "tray-created": return typeof value.requestId === "string" && typeof value.appId === "string" && typeof value.trayId === "string";
@@ -174,6 +178,6 @@ const isTrayEvent = (value) => {
174
178
  };
175
179
  const isMouseButton = (value) => value === "left" || value === "right" || value === "middle";
176
180
  //#endregion
177
- export { CALLER_LABEL_MAX_LENGTH, DEFAULT_CALLER_LABEL, OPENTRAY_PROTOCOL_FAMILY, OPENTRAY_PROTOCOL_LINE, OPENTRAY_PROTOCOL_LINE_MAJOR, OPENTRAY_PROTOCOL_LINE_MINOR, PROTOCOL_VERSION, compareOpenTrayProtocolLine, createBrokerEndpointIdentity, formatBrokerEndpointName, formatBrokerProcessTitle, formatBrokerStateRoot, formatOpenTrayProtocolLine, formatProtocolDistTag, formatUnixSocketPath, formatWindowsPipeName, isOpenTrayProtocolLineCompatible, isProtocolLineReleaseChannel, isServerFrame, isSupportedProtocolVersion, parseProtocolDistTag, parseServerFrame, protocolLineReleaseChannels, sanitizeCallerLabel };
181
+ export { CALLER_LABEL_MAX_LENGTH, DEFAULT_CALLER_LABEL, OPENTRAY_PROTOCOL_FAMILY, OPENTRAY_PROTOCOL_LINE, OPENTRAY_PROTOCOL_LINE_MAJOR, OPENTRAY_PROTOCOL_LINE_MINOR, PROTOCOL_VERSION, brokerArtifactIdentityEquals, compareOpenTrayProtocolLine, createBrokerEndpointIdentity, formatBrokerEndpointName, formatBrokerProcessTitle, formatBrokerStateRoot, formatOpenTrayProtocolLine, formatProtocolDistTag, formatUnixSocketPath, formatWindowsPipeName, isBrokerArtifactIdentity, isOpenTrayProtocolLineCompatible, isProtocolLineReleaseChannel, isServerFrame, isSupportedProtocolVersion, parseProtocolDistTag, parseServerFrame, protocolLineReleaseChannels, sanitizeCallerLabel };
178
182
 
179
183
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["export type SessionId = string;\nexport type RequestId = string;\nexport type AppId = string;\nexport type TrayId = string;\nexport type MenuItemId = number;\n\nexport const PROTOCOL_VERSION = 1;\nexport const OPENTRAY_PROTOCOL_FAMILY = \"opentray-protocol\";\nexport const OPENTRAY_PROTOCOL_LINE_MAJOR = 1;\nexport const OPENTRAY_PROTOCOL_LINE_MINOR = 1;\n\nexport const protocolLineReleaseChannels = [\"stable\", \"alpha\"] as const;\nexport type ProtocolLineReleaseChannel =\n (typeof protocolLineReleaseChannels)[number];\n\nexport interface OpenTrayProtocolLine {\n family: typeof OPENTRAY_PROTOCOL_FAMILY;\n major: number;\n minor: number;\n}\n\nexport interface ProtocolDistTagOptions {\n channel: ProtocolLineReleaseChannel;\n major?: number;\n minor?: number;\n}\n\nexport interface ProtocolDistTag {\n channel: ProtocolLineReleaseChannel;\n major: number;\n minor: number;\n}\n\nexport const OPENTRAY_PROTOCOL_LINE: OpenTrayProtocolLine = {\n family: OPENTRAY_PROTOCOL_FAMILY,\n major: OPENTRAY_PROTOCOL_LINE_MAJOR,\n minor: OPENTRAY_PROTOCOL_LINE_MINOR,\n};\n\n// Install-time protocol lines can advance by minor version while runtime authority stays numeric.\nexport const compareOpenTrayProtocolLine = (\n left: OpenTrayProtocolLine,\n right: OpenTrayProtocolLine\n): number => {\n assertOpenTrayProtocolLine(left, \"left\");\n assertOpenTrayProtocolLine(right, \"right\");\n if (left.major !== right.major) {\n return left.major - right.major;\n }\n return left.minor - right.minor;\n};\n\nexport const isOpenTrayProtocolLineCompatible = (\n supported: OpenTrayProtocolLine,\n required: OpenTrayProtocolLine\n): boolean => {\n assertOpenTrayProtocolLine(supported, \"supported\");\n assertOpenTrayProtocolLine(required, \"required\");\n return (\n supported.major === required.major && supported.minor >= required.minor\n );\n};\n\nexport const formatOpenTrayProtocolLine = ({\n family,\n major,\n minor,\n}: OpenTrayProtocolLine = OPENTRAY_PROTOCOL_LINE): string => {\n assertProtocolLineVersion(major, \"major\");\n assertProtocolLineVersion(minor, \"minor\");\n return `${family}/${major}.${minor}`;\n};\n\nexport const isProtocolLineReleaseChannel = (\n value: string\n): value is ProtocolLineReleaseChannel =>\n protocolLineReleaseChannels.includes(value as ProtocolLineReleaseChannel);\n\nexport const formatProtocolDistTag = ({\n channel,\n major = OPENTRAY_PROTOCOL_LINE_MAJOR,\n minor = OPENTRAY_PROTOCOL_LINE_MINOR,\n}: ProtocolDistTagOptions): string => {\n assertProtocolLineReleaseChannel(channel);\n assertProtocolLineVersion(major, \"major\");\n assertProtocolLineVersion(minor, \"minor\");\n return `${channel}-${major}-${minor}`;\n};\n\nexport const parseProtocolDistTag = (tag: string): ProtocolDistTag => {\n const match = /^(?<channel>[a-z]+)-(?<major>\\d+)-(?<minor>\\d+)$/u.exec(tag);\n const groups = match?.groups;\n if (groups === undefined) {\n throw new Error(`invalid OpenTray protocol dist-tag: ${tag}`);\n }\n const channel = groups.channel;\n if (channel === undefined || !isProtocolLineReleaseChannel(channel)) {\n throw new Error(\n `unsupported OpenTray protocol dist-tag channel: ${channel ?? \"\"}`\n );\n }\n const major = Number(groups.major);\n const minor = Number(groups.minor);\n assertProtocolLineVersion(major, \"major\");\n assertProtocolLineVersion(minor, \"minor\");\n return { channel, major, minor };\n};\n\n/**\n * Neutral caller label used when no usable caller identity can be derived.\n * Keeps the broker honest instead of impersonating an unrelated application.\n */\nexport const DEFAULT_CALLER_LABEL = \"opentray\";\n\n/**\n * Maximum length of a sanitized caller label. Keeps socket paths, runtime\n * directory names, and process titles within platform limits.\n */\nexport const CALLER_LABEL_MAX_LENGTH = 48;\n\nconst callerLabelAllowedPattern = /[a-z0-9-]+/g;\n\nexport interface BrokerEndpointIdentity {\n packageVersion: string;\n protocolVersion: number;\n callerLabel: string;\n}\n\nexport interface BrokerEndpointIdentityOptions {\n packageVersion: string;\n protocolVersion?: number;\n callerLabel?: string;\n}\n\nexport const sanitizeCallerLabel = (value: string | undefined): string => {\n if (value !== undefined && typeof value !== \"string\") {\n throw new Error(`callerLabel must be a string: ${String(value)}`);\n }\n const raw = value ?? \"\";\n const lowered = raw.toLowerCase();\n const segments = lowered.match(callerLabelAllowedPattern);\n if (segments === null || segments.length === 0) {\n return DEFAULT_CALLER_LABEL;\n }\n const joined = segments.join(\"-\");\n const trimmed = joined.replace(/^-+|-+$/gu, \"\");\n if (trimmed.length === 0) {\n return DEFAULT_CALLER_LABEL;\n }\n return trimmed.slice(0, CALLER_LABEL_MAX_LENGTH);\n};\n\nexport const createBrokerEndpointIdentity = ({\n packageVersion,\n protocolVersion = PROTOCOL_VERSION,\n callerLabel,\n}: BrokerEndpointIdentityOptions): BrokerEndpointIdentity => {\n assertEndpointComponent(packageVersion, \"packageVersion\");\n if (!Number.isInteger(protocolVersion) || protocolVersion <= 0) {\n throw new Error(\n `protocolVersion must be a positive integer: ${protocolVersion}`\n );\n }\n\n return {\n packageVersion,\n protocolVersion,\n callerLabel: sanitizeCallerLabel(callerLabel),\n };\n};\n\nexport const isSupportedProtocolVersion = (protocolVersion: number): boolean =>\n protocolVersion === PROTOCOL_VERSION;\n\nexport const formatBrokerEndpointName = (\n identity: BrokerEndpointIdentity\n): string => {\n assertEndpointIdentity(identity);\n return `opentray-${identity.packageVersion}-p${identity.protocolVersion}-${identity.callerLabel}`;\n};\n\nexport const formatBrokerStateRoot = (\n homeDir: string,\n identity: BrokerEndpointIdentity\n): string => {\n assertEndpointIdentity(identity);\n if (homeDir.length === 0) {\n throw new Error(\"homeDir must not be empty\");\n }\n\n const normalizedHome = homeDir.replace(/[\\\\/]+$/u, \"\");\n return `${normalizedHome}/.opentray/${identity.packageVersion}/${identity.callerLabel}`;\n};\n\nexport const formatUnixSocketPath = (\n homeDir: string,\n identity: BrokerEndpointIdentity\n): string =>\n `${formatBrokerStateRoot(homeDir, identity)}/opentray-p${\n identity.protocolVersion\n }.sock`;\n\nexport const formatWindowsPipeName = (\n identity: BrokerEndpointIdentity\n): string => `\\\\\\\\.\\\\pipe\\\\${formatBrokerEndpointName(identity)}`;\n\n/**\n * Human-readable process title for a broker pinned to a caller. Used by the SDK\n * spawn path so task managers show the owning application, not a generic name.\n */\nexport const formatBrokerProcessTitle = (\n identity: BrokerEndpointIdentity\n): string => {\n assertEndpointIdentity(identity);\n return `opentray · ${identity.callerLabel}`;\n};\n\nconst endpointComponentPattern = /^[0-9A-Za-z._+-]+$/u;\n\nconst assertOpenTrayProtocolLine = (\n line: OpenTrayProtocolLine,\n name: string\n): void => {\n assertProtocolLineVersion(line.major, `${name}.major`);\n assertProtocolLineVersion(line.minor, `${name}.minor`);\n};\n\nconst assertProtocolLineReleaseChannel = (channel: string): void => {\n if (!isProtocolLineReleaseChannel(channel)) {\n throw new Error(\n `unsupported OpenTray protocol release channel: ${channel}`\n );\n }\n};\n\nconst assertProtocolLineVersion = (value: number, name: string): void => {\n if (!Number.isInteger(value) || value < 0) {\n throw new Error(\n `protocol line ${name} must be a non-negative integer: ${value}`\n );\n }\n};\n\nconst assertEndpointIdentity = (identity: BrokerEndpointIdentity): void => {\n assertEndpointComponent(identity.packageVersion, \"packageVersion\");\n if (\n !Number.isInteger(identity.protocolVersion) ||\n identity.protocolVersion <= 0\n ) {\n throw new Error(\n `protocolVersion must be a positive integer: ${identity.protocolVersion}`\n );\n }\n};\n\nconst assertEndpointComponent = (value: string, name: string): void => {\n if (value.length === 0) {\n throw new Error(`${name} must not be empty`);\n }\n if (!endpointComponentPattern.test(value)) {\n throw new Error(`${name} contains invalid endpoint characters: ${value}`);\n }\n};\n\nexport interface AppOptions {\n id?: AppId;\n name?: string;\n icon?: Icon;\n default?: boolean;\n}\n\nexport interface AppRef {\n appId: AppId;\n}\n\nexport interface AppIdentity {\n appId: AppId;\n appName: string;\n}\n\nexport interface TrayOptions {\n id: string;\n tooltip?: Tooltip;\n icon?: Icon;\n menu?: Menu;\n}\n\nexport interface Tooltip {\n title: string;\n description: string;\n}\n\nexport interface Menu {\n items: MenuItem[];\n}\n\nexport type MenuItem =\n | {\n type: \"item\";\n id: MenuItemId;\n title: string;\n primaryEvent?: boolean;\n enabled?: boolean;\n shortcut?: string;\n }\n | {\n type: \"check\";\n id: MenuItemId;\n title: string;\n enabled?: boolean;\n checked?: boolean;\n }\n | {\n type: \"radio\";\n id: MenuItemId;\n title: string;\n enabled?: boolean;\n checked?: boolean;\n group: number;\n }\n | {\n type: \"separator\";\n }\n | {\n type: \"submenu\";\n title: string;\n enabled?: boolean;\n items: MenuItem[];\n };\n\nexport type IconImage =\n | { type: \"rgba\"; data: Uint8Array | number[]; width: number; height: number }\n | { type: \"encoded\"; data: Uint8Array | number[] }\n | { type: \"file\"; path: string };\n\nexport type SimpleIcon = IconImage & { text?: string };\n\nexport type IconText = IconImage & { text: string };\n\nexport type DarwinIcon = IconImage & { isTemplate?: boolean };\n\nexport type Win32Icon = IconImage;\n\nexport type LinuxIcon = IconImage;\n\nexport type DarwinIconText = DarwinIcon & { text: string };\n\nexport interface IconCandidates {\n \"icon-only\"?: IconImage;\n \"text-only\"?: string;\n \"icon-text\"?: IconText;\n \"darwin-icon-only\"?: DarwinIcon;\n \"darwin-icon-text\"?: DarwinIconText;\n \"win32-icon-only\"?: Win32Icon;\n \"win32-icon-text\"?: IconText;\n \"linux-icon-only\"?: LinuxIcon;\n \"linux-icon-text\"?: IconText;\n}\n\nexport type Icon = IconCandidates & Partial<SimpleIcon>;\n\nexport interface Rect {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\nexport type TrayBoundsKind = \"native\" | \"inferred\" | \"unavailable\";\n\nexport interface TrayBoundsResult {\n kind: TrayBoundsKind;\n source: string;\n rect: Rect | null;\n}\n\nexport type MouseButton = \"left\" | \"right\" | \"middle\";\n\nexport type TrayEvent =\n | { type: \"ready\"; appId: AppId }\n | { type: \"menuClick\"; appId: AppId; trayId: TrayId; itemId: MenuItemId }\n | {\n type: \"trayClick\";\n appId: AppId;\n trayId: TrayId;\n button: MouseButton;\n x: number;\n y: number;\n }\n | {\n type: \"trayDoubleClick\";\n appId: AppId;\n trayId: TrayId;\n button: MouseButton;\n x: number;\n y: number;\n };\n\nexport interface ExtensionScope {\n appId: AppId;\n trayId?: TrayId;\n ext: string;\n}\n\nexport interface ExtensionEnvelope<TData = unknown> {\n scope: ExtensionScope;\n data: TData;\n}\n\nexport interface RuntimeHostSessionHealth {\n sessionId: number;\n internalSessionId?: SessionId;\n initialized: boolean;\n}\n\nexport interface RuntimeHostHealth {\n pid: number;\n packageVersion: string;\n protocolVersion: number;\n endpoint: string;\n appId: AppId;\n appName: string;\n callerLabel: string;\n sessionCount: number;\n sessions: RuntimeHostSessionHealth[];\n}\n\nexport type ClientFrame =\n | { type: \"init\"; protocolVersion: number; clientVersion: string }\n | ClientRequestFrame\n | { type: \"exit\" };\n\nexport type ClientRequestFrame =\n | ({ type: \"create-app\"; requestId: RequestId } & AppOptions)\n | { type: \"resolve-default-app\"; requestId: RequestId }\n | {\n type: \"create-tray\";\n requestId: RequestId;\n app: AppRef;\n tray: TrayOptions;\n }\n | { type: \"destroy-tray\"; requestId: RequestId; appId: AppId; trayId: TrayId }\n | {\n type: \"get-tray-bounds\";\n requestId: RequestId;\n appId: AppId;\n trayId: TrayId;\n }\n | {\n type: \"set-tray-menu\";\n requestId: RequestId;\n appId: AppId;\n trayId: TrayId;\n menu: Menu;\n }\n | {\n type: \"set-tray-icon\";\n requestId: RequestId;\n appId: AppId;\n trayId: TrayId;\n icon: Icon;\n }\n | {\n type: \"set-tray-tooltip\";\n requestId: RequestId;\n appId: AppId;\n trayId: TrayId;\n tooltip: Tooltip;\n }\n | {\n type: \"load-ext\";\n requestId: RequestId;\n appId: AppId;\n name: string;\n path: string;\n mountId?: string;\n }\n | {\n type: \"ext-command\";\n requestId: RequestId;\n appId: AppId;\n trayId: TrayId;\n ext: string;\n data: unknown;\n }\n | { type: \"unload-ext\"; requestId: RequestId; appId: AppId; name: string }\n | { type: \"health\"; requestId: RequestId };\n\nexport type ServerFrame =\n | {\n type: \"ready\";\n protocolVersion: number;\n brokerVersion: string;\n sessionId: SessionId;\n }\n | { type: \"app-created\"; requestId: RequestId; app: AppRef }\n | { type: \"default-app\"; requestId: RequestId; app: AppRef }\n | { type: \"tray-created\"; requestId: RequestId; appId: AppId; trayId: TrayId }\n | {\n type: \"tray-bounds\";\n requestId: RequestId;\n appId: AppId;\n trayId: TrayId;\n bounds: TrayBoundsResult;\n }\n | { type: \"ack\"; requestId: RequestId }\n | {\n type: \"ext-command-result\";\n requestId: RequestId;\n events: ExtensionEnvelope[];\n }\n | {\n type: \"runtime-host-health\";\n requestId: RequestId;\n health: RuntimeHostHealth;\n }\n | { type: \"event\"; event: TrayEvent }\n | {\n type: \"ext-event\";\n appId: AppId;\n trayId: TrayId;\n ext: string;\n data: unknown;\n }\n | { type: \"error\"; requestId?: RequestId; code: string; message: string };\n\nexport interface ParseResult<T> {\n ok: boolean;\n frame?: T;\n error?: string;\n}\n\nexport const parseServerFrame = (line: string): ParseResult<ServerFrame> => {\n try {\n const value: unknown = JSON.parse(line);\n if (!isServerFrame(value)) {\n return { ok: false, error: \"invalid server frame\" };\n }\n return { ok: true, frame: value };\n } catch (error) {\n return {\n ok: false,\n error: error instanceof Error ? error.message : \"unknown parse error\",\n };\n }\n};\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nexport const isServerFrame = (value: unknown): value is ServerFrame => {\n if (!isRecord(value) || typeof value.type !== \"string\") {\n return false;\n }\n\n switch (value.type) {\n case \"ready\":\n return (\n typeof value.protocolVersion === \"number\" &&\n typeof value.brokerVersion === \"string\" &&\n typeof value.sessionId === \"string\"\n );\n case \"app-created\":\n return typeof value.requestId === \"string\" && isRecord(value.app);\n case \"default-app\":\n return typeof value.requestId === \"string\" && isRecord(value.app);\n case \"tray-created\":\n return (\n typeof value.requestId === \"string\" &&\n typeof value.appId === \"string\" &&\n typeof value.trayId === \"string\"\n );\n case \"tray-bounds\":\n return (\n typeof value.requestId === \"string\" &&\n typeof value.appId === \"string\" &&\n typeof value.trayId === \"string\" &&\n isTrayBoundsResult(value.bounds)\n );\n case \"ack\":\n return typeof value.requestId === \"string\";\n case \"ext-command-result\":\n return (\n typeof value.requestId === \"string\" &&\n Array.isArray(value.events) &&\n value.events.every(isExtensionEnvelope)\n );\n case \"runtime-host-health\":\n return (\n typeof value.requestId === \"string\" && isRuntimeHostHealth(value.health)\n );\n case \"event\":\n return isTrayEvent(value.event);\n case \"ext-event\":\n return (\n typeof value.appId === \"string\" &&\n typeof value.trayId === \"string\" &&\n typeof value.ext === \"string\"\n );\n case \"error\":\n return (\n (value.requestId === undefined ||\n typeof value.requestId === \"string\") &&\n typeof value.code === \"string\" &&\n typeof value.message === \"string\"\n );\n default:\n return false;\n }\n};\n\nconst isExtensionEnvelope = (value: unknown): value is ExtensionEnvelope => {\n if (!isRecord(value) || !isRecord(value.scope)) {\n return false;\n }\n const scope = value.scope as Record<string, unknown>;\n return (\n typeof scope.appId === \"string\" &&\n (scope.trayId === undefined || typeof scope.trayId === \"string\") &&\n typeof scope.ext === \"string\" &&\n \"data\" in value\n );\n};\n\nconst isRuntimeHostHealth = (value: unknown): value is RuntimeHostHealth => {\n if (!isRecord(value)) {\n return false;\n }\n\n return (\n typeof value.pid === \"number\" &&\n typeof value.packageVersion === \"string\" &&\n typeof value.protocolVersion === \"number\" &&\n typeof value.endpoint === \"string\" &&\n typeof value.appId === \"string\" &&\n typeof value.appName === \"string\" &&\n typeof value.callerLabel === \"string\" &&\n typeof value.sessionCount === \"number\" &&\n Array.isArray(value.sessions) &&\n value.sessions.every(isRuntimeHostSessionHealth)\n );\n};\n\nconst isRuntimeHostSessionHealth = (\n value: unknown\n): value is RuntimeHostSessionHealth =>\n isRecord(value) &&\n typeof value.sessionId === \"number\" &&\n (value.internalSessionId === undefined ||\n typeof value.internalSessionId === \"string\") &&\n typeof value.initialized === \"boolean\";\n\nconst isRect = (value: unknown): value is Rect =>\n isRecord(value) &&\n typeof value.x === \"number\" &&\n typeof value.y === \"number\" &&\n typeof value.width === \"number\" &&\n typeof value.height === \"number\";\n\nconst isTrayBoundsResult = (value: unknown): value is TrayBoundsResult =>\n isRecord(value) &&\n (value.kind === \"native\" ||\n value.kind === \"inferred\" ||\n value.kind === \"unavailable\") &&\n typeof value.source === \"string\" &&\n (value.rect === null || isRect(value.rect));\n\nconst isTrayEvent = (value: unknown): value is TrayEvent => {\n if (!isRecord(value) || typeof value.type !== \"string\") {\n return false;\n }\n\n switch (value.type) {\n case \"ready\":\n return typeof value.appId === \"string\";\n case \"menuClick\":\n return (\n typeof value.appId === \"string\" &&\n typeof value.trayId === \"string\" &&\n typeof value.itemId === \"number\"\n );\n case \"trayClick\":\n case \"trayDoubleClick\":\n return (\n typeof value.appId === \"string\" &&\n typeof value.trayId === \"string\" &&\n isMouseButton(value.button) &&\n typeof value.x === \"number\" &&\n typeof value.y === \"number\"\n );\n default:\n return false;\n }\n};\n\nconst isMouseButton = (value: unknown): value is MouseButton =>\n value === \"left\" || value === \"right\" || value === \"middle\";\n"],"mappings":";AAMA,MAAa,mBAAmB;AAChC,MAAa,2BAA2B;AACxC,MAAa,+BAA+B;AAC5C,MAAa,+BAA+B;AAE5C,MAAa,8BAA8B,CAAC,UAAU,OAAO;AAsB7D,MAAa,yBAA+C;CAC1D,QAAQ;CACR,OAAA;CACA,OAAA;AACF;AAGA,MAAa,+BACX,MACA,UACW;CACX,2BAA2B,MAAM,MAAM;CACvC,2BAA2B,OAAO,OAAO;CACzC,IAAI,KAAK,UAAU,MAAM,OACvB,OAAO,KAAK,QAAQ,MAAM;CAE5B,OAAO,KAAK,QAAQ,MAAM;AAC5B;AAEA,MAAa,oCACX,WACA,aACY;CACZ,2BAA2B,WAAW,WAAW;CACjD,2BAA2B,UAAU,UAAU;CAC/C,OACE,UAAU,UAAU,SAAS,SAAS,UAAU,SAAS,SAAS;AAEtE;AAEA,MAAa,8BAA8B,EACzC,QACA,OACA,UACwB,2BAAmC;CAC3D,0BAA0B,OAAO,OAAO;CACxC,0BAA0B,OAAO,OAAO;CACxC,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG;AAC/B;AAEA,MAAa,gCACX,UAEA,4BAA4B,SAAS,KAAmC;AAE1E,MAAa,yBAAyB,EACpC,SACA,QAAA,GACA,QAAA,QACoC;CACpC,iCAAiC,OAAO;CACxC,0BAA0B,OAAO,OAAO;CACxC,0BAA0B,OAAO,OAAO;CACxC,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG;AAChC;AAEA,MAAa,wBAAwB,QAAiC;CAEpE,MAAM,SADQ,oDAAoD,KAAK,GACpD,GAAG;CACtB,IAAI,WAAW,KAAA,GACb,MAAM,IAAI,MAAM,uCAAuC,KAAK;CAE9D,MAAM,UAAU,OAAO;CACvB,IAAI,YAAY,KAAA,KAAa,CAAC,6BAA6B,OAAO,GAChE,MAAM,IAAI,MACR,mDAAmD,WAAW,IAChE;CAEF,MAAM,QAAQ,OAAO,OAAO,KAAK;CACjC,MAAM,QAAQ,OAAO,OAAO,KAAK;CACjC,0BAA0B,OAAO,OAAO;CACxC,0BAA0B,OAAO,OAAO;CACxC,OAAO;EAAE;EAAS;EAAO;CAAM;AACjC;;;;;AAMA,MAAa,uBAAuB;;;;;AAMpC,MAAa,0BAA0B;AAEvC,MAAM,4BAA4B;AAclC,MAAa,uBAAuB,UAAsC;CACxE,IAAI,UAAU,KAAA,KAAa,OAAO,UAAU,UAC1C,MAAM,IAAI,MAAM,iCAAiC,OAAO,KAAK,GAAG;CAIlE,MAAM,YAFM,SAAS,IACD,YACG,EAAE,MAAM,yBAAyB;CACxD,IAAI,aAAa,QAAQ,SAAS,WAAW,GAC3C,OAAO;CAGT,MAAM,UADS,SAAS,KAAK,GACR,EAAE,QAAQ,aAAa,EAAE;CAC9C,IAAI,QAAQ,WAAW,GACrB,OAAO;CAET,OAAO,QAAQ,MAAM,GAAA,EAA0B;AACjD;AAEA,MAAa,gCAAgC,EAC3C,gBACA,kBAAA,GACA,kBAC2D;CAC3D,wBAAwB,gBAAgB,gBAAgB;CACxD,IAAI,CAAC,OAAO,UAAU,eAAe,KAAK,mBAAmB,GAC3D,MAAM,IAAI,MACR,+CAA+C,iBACjD;CAGF,OAAO;EACL;EACA;EACA,aAAa,oBAAoB,WAAW;CAC9C;AACF;AAEA,MAAa,8BAA8B,oBACzC,oBAAA;AAEF,MAAa,4BACX,aACW;CACX,uBAAuB,QAAQ;CAC/B,OAAO,YAAY,SAAS,eAAe,IAAI,SAAS,gBAAgB,GAAG,SAAS;AACtF;AAEA,MAAa,yBACX,SACA,aACW;CACX,uBAAuB,QAAQ;CAC/B,IAAI,QAAQ,WAAW,GACrB,MAAM,IAAI,MAAM,2BAA2B;CAI7C,OAAO,GADgB,QAAQ,QAAQ,YAAY,EAC5B,EAAE,aAAa,SAAS,eAAe,GAAG,SAAS;AAC5E;AAEA,MAAa,wBACX,SACA,aAEA,GAAG,sBAAsB,SAAS,QAAQ,EAAE,aAC1C,SAAS,gBACV;AAEH,MAAa,yBACX,aACW,gBAAgB,yBAAyB,QAAQ;;;;;AAM9D,MAAa,4BACX,aACW;CACX,uBAAuB,QAAQ;CAC/B,OAAO,cAAc,SAAS;AAChC;AAEA,MAAM,2BAA2B;AAEjC,MAAM,8BACJ,MACA,SACS;CACT,0BAA0B,KAAK,OAAO,GAAG,KAAK,OAAO;CACrD,0BAA0B,KAAK,OAAO,GAAG,KAAK,OAAO;AACvD;AAEA,MAAM,oCAAoC,YAA0B;CAClE,IAAI,CAAC,6BAA6B,OAAO,GACvC,MAAM,IAAI,MACR,kDAAkD,SACpD;AAEJ;AAEA,MAAM,6BAA6B,OAAe,SAAuB;CACvE,IAAI,CAAC,OAAO,UAAU,KAAK,KAAK,QAAQ,GACtC,MAAM,IAAI,MACR,iBAAiB,KAAK,mCAAmC,OAC3D;AAEJ;AAEA,MAAM,0BAA0B,aAA2C;CACzE,wBAAwB,SAAS,gBAAgB,gBAAgB;CACjE,IACE,CAAC,OAAO,UAAU,SAAS,eAAe,KAC1C,SAAS,mBAAmB,GAE5B,MAAM,IAAI,MACR,+CAA+C,SAAS,iBAC1D;AAEJ;AAEA,MAAM,2BAA2B,OAAe,SAAuB;CACrE,IAAI,MAAM,WAAW,GACnB,MAAM,IAAI,MAAM,GAAG,KAAK,mBAAmB;CAE7C,IAAI,CAAC,yBAAyB,KAAK,KAAK,GACtC,MAAM,IAAI,MAAM,GAAG,KAAK,yCAAyC,OAAO;AAE5E;AA8QA,MAAa,oBAAoB,SAA2C;CAC1E,IAAI;EACF,MAAM,QAAiB,KAAK,MAAM,IAAI;EACtC,IAAI,CAAC,cAAc,KAAK,GACtB,OAAO;GAAE,IAAI;GAAO,OAAO;EAAuB;EAEpD,OAAO;GAAE,IAAI;GAAM,OAAO;EAAM;CAClC,SAAS,OAAO;EACd,OAAO;GACL,IAAI;GACJ,OAAO,iBAAiB,QAAQ,MAAM,UAAU;EAClD;CACF;AACF;AAEA,MAAM,YAAY,UAChB,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAErE,MAAa,iBAAiB,UAAyC;CACrE,IAAI,CAAC,SAAS,KAAK,KAAK,OAAO,MAAM,SAAS,UAC5C,OAAO;CAGT,QAAQ,MAAM,MAAd;EACE,KAAK,SACH,OACE,OAAO,MAAM,oBAAoB,YACjC,OAAO,MAAM,kBAAkB,YAC/B,OAAO,MAAM,cAAc;EAE/B,KAAK,eACH,OAAO,OAAO,MAAM,cAAc,YAAY,SAAS,MAAM,GAAG;EAClE,KAAK,eACH,OAAO,OAAO,MAAM,cAAc,YAAY,SAAS,MAAM,GAAG;EAClE,KAAK,gBACH,OACE,OAAO,MAAM,cAAc,YAC3B,OAAO,MAAM,UAAU,YACvB,OAAO,MAAM,WAAW;EAE5B,KAAK,eACH,OACE,OAAO,MAAM,cAAc,YAC3B,OAAO,MAAM,UAAU,YACvB,OAAO,MAAM,WAAW,YACxB,mBAAmB,MAAM,MAAM;EAEnC,KAAK,OACH,OAAO,OAAO,MAAM,cAAc;EACpC,KAAK,sBACH,OACE,OAAO,MAAM,cAAc,YAC3B,MAAM,QAAQ,MAAM,MAAM,KAC1B,MAAM,OAAO,MAAM,mBAAmB;EAE1C,KAAK,uBACH,OACE,OAAO,MAAM,cAAc,YAAY,oBAAoB,MAAM,MAAM;EAE3E,KAAK,SACH,OAAO,YAAY,MAAM,KAAK;EAChC,KAAK,aACH,OACE,OAAO,MAAM,UAAU,YACvB,OAAO,MAAM,WAAW,YACxB,OAAO,MAAM,QAAQ;EAEzB,KAAK,SACH,QACG,MAAM,cAAc,KAAA,KACnB,OAAO,MAAM,cAAc,aAC7B,OAAO,MAAM,SAAS,YACtB,OAAO,MAAM,YAAY;EAE7B,SACE,OAAO;CACX;AACF;AAEA,MAAM,uBAAuB,UAA+C;CAC1E,IAAI,CAAC,SAAS,KAAK,KAAK,CAAC,SAAS,MAAM,KAAK,GAC3C,OAAO;CAET,MAAM,QAAQ,MAAM;CACpB,OACE,OAAO,MAAM,UAAU,aACtB,MAAM,WAAW,KAAA,KAAa,OAAO,MAAM,WAAW,aACvD,OAAO,MAAM,QAAQ,YACrB,UAAU;AAEd;AAEA,MAAM,uBAAuB,UAA+C;CAC1E,IAAI,CAAC,SAAS,KAAK,GACjB,OAAO;CAGT,OACE,OAAO,MAAM,QAAQ,YACrB,OAAO,MAAM,mBAAmB,YAChC,OAAO,MAAM,oBAAoB,YACjC,OAAO,MAAM,aAAa,YAC1B,OAAO,MAAM,UAAU,YACvB,OAAO,MAAM,YAAY,YACzB,OAAO,MAAM,gBAAgB,YAC7B,OAAO,MAAM,iBAAiB,YAC9B,MAAM,QAAQ,MAAM,QAAQ,KAC5B,MAAM,SAAS,MAAM,0BAA0B;AAEnD;AAEA,MAAM,8BACJ,UAEA,SAAS,KAAK,KACd,OAAO,MAAM,cAAc,aAC1B,MAAM,sBAAsB,KAAA,KAC3B,OAAO,MAAM,sBAAsB,aACrC,OAAO,MAAM,gBAAgB;AAE/B,MAAM,UAAU,UACd,SAAS,KAAK,KACd,OAAO,MAAM,MAAM,YACnB,OAAO,MAAM,MAAM,YACnB,OAAO,MAAM,UAAU,YACvB,OAAO,MAAM,WAAW;AAE1B,MAAM,sBAAsB,UAC1B,SAAS,KAAK,MACb,MAAM,SAAS,YACd,MAAM,SAAS,cACf,MAAM,SAAS,kBACjB,OAAO,MAAM,WAAW,aACvB,MAAM,SAAS,QAAQ,OAAO,MAAM,IAAI;AAE3C,MAAM,eAAe,UAAuC;CAC1D,IAAI,CAAC,SAAS,KAAK,KAAK,OAAO,MAAM,SAAS,UAC5C,OAAO;CAGT,QAAQ,MAAM,MAAd;EACE,KAAK,SACH,OAAO,OAAO,MAAM,UAAU;EAChC,KAAK,aACH,OACE,OAAO,MAAM,UAAU,YACvB,OAAO,MAAM,WAAW,YACxB,OAAO,MAAM,WAAW;EAE5B,KAAK;EACL,KAAK,mBACH,OACE,OAAO,MAAM,UAAU,YACvB,OAAO,MAAM,WAAW,YACxB,cAAc,MAAM,MAAM,KAC1B,OAAO,MAAM,MAAM,YACnB,OAAO,MAAM,MAAM;EAEvB,SACE,OAAO;CACX;AACF;AAEA,MAAM,iBAAiB,UACrB,UAAU,UAAU,UAAU,WAAW,UAAU"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["export type SessionId = string;\nexport type RequestId = string;\nexport type AppId = string;\nexport type TrayId = string;\nexport type MenuItemId = number;\n\nexport const PROTOCOL_VERSION = 1;\nexport const OPENTRAY_PROTOCOL_FAMILY = \"opentray-protocol\";\nexport const OPENTRAY_PROTOCOL_LINE_MAJOR = 1;\nexport const OPENTRAY_PROTOCOL_LINE_MINOR = 1;\n\nexport const protocolLineReleaseChannels = [\"stable\", \"alpha\"] as const;\nexport type ProtocolLineReleaseChannel = (typeof protocolLineReleaseChannels)[number];\n\nexport interface OpenTrayProtocolLine {\n family: typeof OPENTRAY_PROTOCOL_FAMILY;\n major: number;\n minor: number;\n}\n\nexport interface ProtocolDistTagOptions {\n channel: ProtocolLineReleaseChannel;\n major?: number;\n minor?: number;\n}\n\nexport interface ProtocolDistTag {\n channel: ProtocolLineReleaseChannel;\n major: number;\n minor: number;\n}\n\nexport const OPENTRAY_PROTOCOL_LINE: OpenTrayProtocolLine = {\n family: OPENTRAY_PROTOCOL_FAMILY,\n major: OPENTRAY_PROTOCOL_LINE_MAJOR,\n minor: OPENTRAY_PROTOCOL_LINE_MINOR,\n};\n\n// Install-time protocol lines can advance by minor version while runtime authority stays numeric.\nexport const compareOpenTrayProtocolLine = (\n left: OpenTrayProtocolLine,\n right: OpenTrayProtocolLine,\n): number => {\n assertOpenTrayProtocolLine(left, \"left\");\n assertOpenTrayProtocolLine(right, \"right\");\n if (left.major !== right.major) {\n return left.major - right.major;\n }\n return left.minor - right.minor;\n};\n\nexport const isOpenTrayProtocolLineCompatible = (\n supported: OpenTrayProtocolLine,\n required: OpenTrayProtocolLine,\n): boolean => {\n assertOpenTrayProtocolLine(supported, \"supported\");\n assertOpenTrayProtocolLine(required, \"required\");\n return supported.major === required.major && supported.minor >= required.minor;\n};\n\nexport const formatOpenTrayProtocolLine = ({\n family,\n major,\n minor,\n}: OpenTrayProtocolLine = OPENTRAY_PROTOCOL_LINE): string => {\n assertProtocolLineVersion(major, \"major\");\n assertProtocolLineVersion(minor, \"minor\");\n return `${family}/${major}.${minor}`;\n};\n\nexport const isProtocolLineReleaseChannel = (value: string): value is ProtocolLineReleaseChannel =>\n protocolLineReleaseChannels.includes(value as ProtocolLineReleaseChannel);\n\nexport const formatProtocolDistTag = ({\n channel,\n major = OPENTRAY_PROTOCOL_LINE_MAJOR,\n minor = OPENTRAY_PROTOCOL_LINE_MINOR,\n}: ProtocolDistTagOptions): string => {\n assertProtocolLineReleaseChannel(channel);\n assertProtocolLineVersion(major, \"major\");\n assertProtocolLineVersion(minor, \"minor\");\n return `${channel}-${major}-${minor}`;\n};\n\nexport const parseProtocolDistTag = (tag: string): ProtocolDistTag => {\n const match = /^(?<channel>[a-z]+)-(?<major>\\d+)-(?<minor>\\d+)$/u.exec(tag);\n const groups = match?.groups;\n if (groups === undefined) {\n throw new Error(`invalid OpenTray protocol dist-tag: ${tag}`);\n }\n const channel = groups.channel;\n if (channel === undefined || !isProtocolLineReleaseChannel(channel)) {\n throw new Error(`unsupported OpenTray protocol dist-tag channel: ${channel ?? \"\"}`);\n }\n const major = Number(groups.major);\n const minor = Number(groups.minor);\n assertProtocolLineVersion(major, \"major\");\n assertProtocolLineVersion(minor, \"minor\");\n return { channel, major, minor };\n};\n\n/**\n * Neutral caller label used when no usable caller identity can be derived.\n * Keeps the broker honest instead of impersonating an unrelated application.\n */\nexport const DEFAULT_CALLER_LABEL = \"opentray\";\n\n/**\n * Maximum length of a sanitized caller label. Keeps socket paths, runtime\n * directory names, and process titles within platform limits.\n */\nexport const CALLER_LABEL_MAX_LENGTH = 48;\n\nconst callerLabelAllowedPattern = /[a-z0-9-]+/g;\n\nexport interface BrokerEndpointIdentity {\n packageVersion: string;\n protocolVersion: number;\n callerLabel: string;\n}\n\nexport interface BrokerEndpointIdentityOptions {\n packageVersion: string;\n protocolVersion?: number;\n callerLabel?: string;\n}\n\nexport const sanitizeCallerLabel = (value: string | undefined): string => {\n if (value !== undefined && typeof value !== \"string\") {\n throw new Error(`callerLabel must be a string: ${String(value)}`);\n }\n const raw = value ?? \"\";\n const lowered = raw.toLowerCase();\n const segments = lowered.match(callerLabelAllowedPattern);\n if (segments === null || segments.length === 0) {\n return DEFAULT_CALLER_LABEL;\n }\n const joined = segments.join(\"-\");\n const trimmed = joined.replace(/^-+|-+$/gu, \"\");\n if (trimmed.length === 0) {\n return DEFAULT_CALLER_LABEL;\n }\n return trimmed.slice(0, CALLER_LABEL_MAX_LENGTH);\n};\n\nexport const createBrokerEndpointIdentity = ({\n packageVersion,\n protocolVersion = PROTOCOL_VERSION,\n callerLabel,\n}: BrokerEndpointIdentityOptions): BrokerEndpointIdentity => {\n assertEndpointComponent(packageVersion, \"packageVersion\");\n if (!Number.isInteger(protocolVersion) || protocolVersion <= 0) {\n throw new Error(`protocolVersion must be a positive integer: ${protocolVersion}`);\n }\n\n return {\n packageVersion,\n protocolVersion,\n callerLabel: sanitizeCallerLabel(callerLabel),\n };\n};\n\nexport const isSupportedProtocolVersion = (protocolVersion: number): boolean =>\n protocolVersion === PROTOCOL_VERSION;\n\nexport const formatBrokerEndpointName = (identity: BrokerEndpointIdentity): string => {\n assertEndpointIdentity(identity);\n return `opentray-${identity.packageVersion}-p${identity.protocolVersion}-${identity.callerLabel}`;\n};\n\nexport const formatBrokerStateRoot = (\n homeDir: string,\n identity: BrokerEndpointIdentity,\n): string => {\n assertEndpointIdentity(identity);\n if (homeDir.length === 0) {\n throw new Error(\"homeDir must not be empty\");\n }\n\n const normalizedHome = homeDir.replace(/[\\\\/]+$/u, \"\");\n return `${normalizedHome}/.opentray/${identity.packageVersion}/${identity.callerLabel}`;\n};\n\nexport const formatUnixSocketPath = (homeDir: string, identity: BrokerEndpointIdentity): string =>\n `${formatBrokerStateRoot(homeDir, identity)}/opentray-p${identity.protocolVersion}.sock`;\n\nexport const formatWindowsPipeName = (identity: BrokerEndpointIdentity): string =>\n `\\\\\\\\.\\\\pipe\\\\${formatBrokerEndpointName(identity)}`;\n\n/**\n * Human-readable process title for a broker pinned to a caller. Used by the SDK\n * spawn path so task managers show the owning application, not a generic name.\n */\nexport const formatBrokerProcessTitle = (identity: BrokerEndpointIdentity): string => {\n assertEndpointIdentity(identity);\n return `opentray · ${identity.callerLabel}`;\n};\n\nconst endpointComponentPattern = /^[0-9A-Za-z._+-]+$/u;\n\nconst assertOpenTrayProtocolLine = (line: OpenTrayProtocolLine, name: string): void => {\n assertProtocolLineVersion(line.major, `${name}.major`);\n assertProtocolLineVersion(line.minor, `${name}.minor`);\n};\n\nconst assertProtocolLineReleaseChannel = (channel: string): void => {\n if (!isProtocolLineReleaseChannel(channel)) {\n throw new Error(`unsupported OpenTray protocol release channel: ${channel}`);\n }\n};\n\nconst assertProtocolLineVersion = (value: number, name: string): void => {\n if (!Number.isInteger(value) || value < 0) {\n throw new Error(`protocol line ${name} must be a non-negative integer: ${value}`);\n }\n};\n\nconst assertEndpointIdentity = (identity: BrokerEndpointIdentity): void => {\n assertEndpointComponent(identity.packageVersion, \"packageVersion\");\n if (!Number.isInteger(identity.protocolVersion) || identity.protocolVersion <= 0) {\n throw new Error(`protocolVersion must be a positive integer: ${identity.protocolVersion}`);\n }\n};\n\nconst assertEndpointComponent = (value: string, name: string): void => {\n if (value.length === 0) {\n throw new Error(`${name} must not be empty`);\n }\n if (!endpointComponentPattern.test(value)) {\n throw new Error(`${name} contains invalid endpoint characters: ${value}`);\n }\n};\n\nexport interface AppOptions {\n id?: AppId;\n name?: string;\n icon?: Icon;\n default?: boolean;\n}\n\nexport interface AppRef {\n appId: AppId;\n}\n\nexport interface AppIdentity {\n appId: AppId;\n appName: string;\n}\n\nexport interface TrayOptions {\n id: string;\n tooltip?: Tooltip;\n icon?: Icon;\n menu?: Menu;\n}\n\nexport interface Tooltip {\n title: string;\n description: string;\n}\n\nexport interface Menu {\n items: MenuItem[];\n}\n\nexport type MenuItem =\n | {\n type: \"item\";\n id: MenuItemId;\n title: string;\n primaryEvent?: boolean;\n enabled?: boolean;\n shortcut?: string;\n }\n | {\n type: \"check\";\n id: MenuItemId;\n title: string;\n enabled?: boolean;\n checked?: boolean;\n }\n | {\n type: \"radio\";\n id: MenuItemId;\n title: string;\n enabled?: boolean;\n checked?: boolean;\n group: number;\n }\n | {\n type: \"separator\";\n }\n | {\n type: \"submenu\";\n title: string;\n enabled?: boolean;\n items: MenuItem[];\n };\n\nexport type IconImage =\n | { type: \"rgba\"; data: Uint8Array | number[]; width: number; height: number }\n | { type: \"encoded\"; data: Uint8Array | number[] }\n | { type: \"file\"; path: string };\n\nexport type SimpleIcon = IconImage & { text?: string };\n\nexport type IconText = IconImage & { text: string };\n\nexport type DarwinIcon = IconImage & { isTemplate?: boolean };\n\nexport type Win32Icon = IconImage;\n\nexport type LinuxIcon = IconImage;\n\nexport type DarwinIconText = DarwinIcon & { text: string };\n\nexport interface IconCandidates {\n \"icon-only\"?: IconImage;\n \"text-only\"?: string;\n \"icon-text\"?: IconText;\n \"darwin-icon-only\"?: DarwinIcon;\n \"darwin-icon-text\"?: DarwinIconText;\n \"win32-icon-only\"?: Win32Icon;\n \"win32-icon-text\"?: IconText;\n \"linux-icon-only\"?: LinuxIcon;\n \"linux-icon-text\"?: IconText;\n}\n\nexport type Icon = IconCandidates & Partial<SimpleIcon>;\n\nexport interface Rect {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\nexport type TrayBoundsKind = \"native\" | \"inferred\" | \"unavailable\";\n\nexport interface TrayBoundsResult {\n kind: TrayBoundsKind;\n source: string;\n rect: Rect | null;\n}\n\nexport type MouseButton = \"left\" | \"right\" | \"middle\";\n\nexport type TrayEvent =\n | { type: \"ready\"; appId: AppId }\n | { type: \"menuClick\"; appId: AppId; trayId: TrayId; itemId: MenuItemId }\n | {\n type: \"trayClick\";\n appId: AppId;\n trayId: TrayId;\n button: MouseButton;\n x: number;\n y: number;\n }\n | {\n type: \"trayDoubleClick\";\n appId: AppId;\n trayId: TrayId;\n button: MouseButton;\n x: number;\n y: number;\n };\n\nexport interface ExtensionScope {\n appId: AppId;\n trayId?: TrayId;\n ext: string;\n}\n\nexport interface ExtensionEnvelope<TData = unknown> {\n scope: ExtensionScope;\n data: TData;\n}\n\nexport interface ExtensionArtifactTarget {\n os: string;\n arch: string;\n}\n\nexport interface ExpectedExtensionIdentity {\n extensionName: string;\n artifactSetVersion: string;\n contractFingerprint: string;\n target: ExtensionArtifactTarget;\n}\n\n/** Operating-system and architecture identity for one broker executable. */\nexport interface BrokerArtifactTarget {\n os: \"darwin\" | \"linux\" | \"win32\";\n arch: \"arm64\" | \"x64\";\n}\n\n/** Content-derived identity used to decide whether a live broker may be reused. */\nexport interface BrokerArtifactIdentity {\n packageVersion: string;\n target: BrokerArtifactTarget;\n executableHash: string;\n buildIdentity: string;\n}\n\n/** Caller-scoped readiness evidence written by a successfully initialized broker. */\nexport interface BrokerReadyMetadata {\n pid: number;\n endpoint: string;\n packageVersion: string;\n protocolVersion: number;\n appId: AppId;\n appName: string;\n callerLabel: string;\n executablePath: string;\n brokerArtifactIdentity: BrokerArtifactIdentity;\n}\n\nexport interface RuntimeHostSessionHealth {\n sessionId: number;\n internalSessionId?: SessionId;\n initialized: boolean;\n}\n\nexport interface RuntimeHostHealth {\n pid: number;\n packageVersion: string;\n protocolVersion: number;\n endpoint: string;\n appId: AppId;\n appName: string;\n callerLabel: string;\n sessionCount: number;\n sessions: RuntimeHostSessionHealth[];\n}\n\nexport type ClientFrame =\n | { type: \"init\"; protocolVersion: number; clientVersion: string }\n | ClientRequestFrame\n | { type: \"exit\" };\n\nexport type ClientRequestFrame =\n | ({ type: \"create-app\"; requestId: RequestId } & AppOptions)\n | { type: \"resolve-default-app\"; requestId: RequestId }\n | {\n type: \"create-tray\";\n requestId: RequestId;\n app: AppRef;\n tray: TrayOptions;\n }\n | { type: \"destroy-tray\"; requestId: RequestId; appId: AppId; trayId: TrayId }\n | {\n type: \"get-tray-bounds\";\n requestId: RequestId;\n appId: AppId;\n trayId: TrayId;\n }\n | {\n type: \"set-tray-menu\";\n requestId: RequestId;\n appId: AppId;\n trayId: TrayId;\n menu: Menu;\n }\n | {\n type: \"set-tray-icon\";\n requestId: RequestId;\n appId: AppId;\n trayId: TrayId;\n icon: Icon;\n }\n | {\n type: \"set-tray-tooltip\";\n requestId: RequestId;\n appId: AppId;\n trayId: TrayId;\n tooltip: Tooltip;\n }\n | {\n type: \"load-ext\";\n requestId: RequestId;\n appId: AppId;\n name: string;\n path: string;\n expectedIdentity: ExpectedExtensionIdentity;\n mountId?: string;\n }\n | {\n type: \"ext-command\";\n requestId: RequestId;\n appId: AppId;\n trayId: TrayId;\n ext: string;\n data: unknown;\n }\n | { type: \"unload-ext\"; requestId: RequestId; appId: AppId; name: string }\n | { type: \"health\"; requestId: RequestId };\n\nexport type ServerFrame =\n | {\n type: \"ready\";\n protocolVersion: number;\n brokerVersion: string;\n brokerArtifactIdentity: BrokerArtifactIdentity;\n sessionId: SessionId;\n }\n | { type: \"app-created\"; requestId: RequestId; app: AppRef }\n | { type: \"default-app\"; requestId: RequestId; app: AppRef }\n | { type: \"tray-created\"; requestId: RequestId; appId: AppId; trayId: TrayId }\n | {\n type: \"tray-bounds\";\n requestId: RequestId;\n appId: AppId;\n trayId: TrayId;\n bounds: TrayBoundsResult;\n }\n | { type: \"ack\"; requestId: RequestId }\n | {\n type: \"ext-command-result\";\n requestId: RequestId;\n events: ExtensionEnvelope[];\n }\n | {\n type: \"runtime-host-health\";\n requestId: RequestId;\n health: RuntimeHostHealth;\n }\n | { type: \"event\"; event: TrayEvent }\n | {\n type: \"ext-event\";\n appId: AppId;\n trayId: TrayId;\n ext: string;\n data: unknown;\n }\n | { type: \"error\"; requestId?: RequestId; code: string; message: string };\n\nexport interface ParseResult<T> {\n ok: boolean;\n frame?: T;\n error?: string;\n}\n\nexport const parseServerFrame = (line: string): ParseResult<ServerFrame> => {\n try {\n const value: unknown = JSON.parse(line);\n if (!isServerFrame(value)) {\n return { ok: false, error: \"invalid server frame\" };\n }\n return { ok: true, frame: value };\n } catch (error) {\n return {\n ok: false,\n error: error instanceof Error ? error.message : \"unknown parse error\",\n };\n }\n};\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\n/** Returns true when an unknown value is a complete broker artifact identity. */\nexport const isBrokerArtifactIdentity = (value: unknown): value is BrokerArtifactIdentity =>\n isRecord(value) &&\n typeof value.packageVersion === \"string\" &&\n isRecord(value.target) &&\n (value.target.os === \"darwin\" || value.target.os === \"linux\" || value.target.os === \"win32\") &&\n (value.target.arch === \"arm64\" || value.target.arch === \"x64\") &&\n typeof value.executableHash === \"string\" &&\n /^[a-f0-9]{64}$/u.test(value.executableHash) &&\n typeof value.buildIdentity === \"string\" &&\n value.buildIdentity.length > 0;\n\n/** Compares every compatibility-bearing broker artifact identity field. */\nexport const brokerArtifactIdentityEquals = (\n left: BrokerArtifactIdentity,\n right: BrokerArtifactIdentity,\n): boolean =>\n left.packageVersion === right.packageVersion &&\n left.target.os === right.target.os &&\n left.target.arch === right.target.arch &&\n left.executableHash === right.executableHash &&\n left.buildIdentity === right.buildIdentity;\n\nexport const isServerFrame = (value: unknown): value is ServerFrame => {\n if (!isRecord(value) || typeof value.type !== \"string\") {\n return false;\n }\n\n switch (value.type) {\n case \"ready\":\n return (\n typeof value.protocolVersion === \"number\" &&\n typeof value.brokerVersion === \"string\" &&\n isBrokerArtifactIdentity(value.brokerArtifactIdentity) &&\n typeof value.sessionId === \"string\"\n );\n case \"app-created\":\n return typeof value.requestId === \"string\" && isRecord(value.app);\n case \"default-app\":\n return typeof value.requestId === \"string\" && isRecord(value.app);\n case \"tray-created\":\n return (\n typeof value.requestId === \"string\" &&\n typeof value.appId === \"string\" &&\n typeof value.trayId === \"string\"\n );\n case \"tray-bounds\":\n return (\n typeof value.requestId === \"string\" &&\n typeof value.appId === \"string\" &&\n typeof value.trayId === \"string\" &&\n isTrayBoundsResult(value.bounds)\n );\n case \"ack\":\n return typeof value.requestId === \"string\";\n case \"ext-command-result\":\n return (\n typeof value.requestId === \"string\" &&\n Array.isArray(value.events) &&\n value.events.every(isExtensionEnvelope)\n );\n case \"runtime-host-health\":\n return typeof value.requestId === \"string\" && isRuntimeHostHealth(value.health);\n case \"event\":\n return isTrayEvent(value.event);\n case \"ext-event\":\n return (\n typeof value.appId === \"string\" &&\n typeof value.trayId === \"string\" &&\n typeof value.ext === \"string\"\n );\n case \"error\":\n return (\n (value.requestId === undefined || typeof value.requestId === \"string\") &&\n typeof value.code === \"string\" &&\n typeof value.message === \"string\"\n );\n default:\n return false;\n }\n};\n\nconst isExtensionEnvelope = (value: unknown): value is ExtensionEnvelope => {\n if (!isRecord(value) || !isRecord(value.scope)) {\n return false;\n }\n const scope = value.scope as Record<string, unknown>;\n return (\n typeof scope.appId === \"string\" &&\n (scope.trayId === undefined || typeof scope.trayId === \"string\") &&\n typeof scope.ext === \"string\" &&\n \"data\" in value\n );\n};\n\nconst isRuntimeHostHealth = (value: unknown): value is RuntimeHostHealth => {\n if (!isRecord(value)) {\n return false;\n }\n\n return (\n typeof value.pid === \"number\" &&\n typeof value.packageVersion === \"string\" &&\n typeof value.protocolVersion === \"number\" &&\n typeof value.endpoint === \"string\" &&\n typeof value.appId === \"string\" &&\n typeof value.appName === \"string\" &&\n typeof value.callerLabel === \"string\" &&\n typeof value.sessionCount === \"number\" &&\n Array.isArray(value.sessions) &&\n value.sessions.every(isRuntimeHostSessionHealth)\n );\n};\n\nconst isRuntimeHostSessionHealth = (value: unknown): value is RuntimeHostSessionHealth =>\n isRecord(value) &&\n typeof value.sessionId === \"number\" &&\n (value.internalSessionId === undefined || typeof value.internalSessionId === \"string\") &&\n typeof value.initialized === \"boolean\";\n\nconst isRect = (value: unknown): value is Rect =>\n isRecord(value) &&\n typeof value.x === \"number\" &&\n typeof value.y === \"number\" &&\n typeof value.width === \"number\" &&\n typeof value.height === \"number\";\n\nconst isTrayBoundsResult = (value: unknown): value is TrayBoundsResult =>\n isRecord(value) &&\n (value.kind === \"native\" || value.kind === \"inferred\" || value.kind === \"unavailable\") &&\n typeof value.source === \"string\" &&\n (value.rect === null || isRect(value.rect));\n\nconst isTrayEvent = (value: unknown): value is TrayEvent => {\n if (!isRecord(value) || typeof value.type !== \"string\") {\n return false;\n }\n\n switch (value.type) {\n case \"ready\":\n return typeof value.appId === \"string\";\n case \"menuClick\":\n return (\n typeof value.appId === \"string\" &&\n typeof value.trayId === \"string\" &&\n typeof value.itemId === \"number\"\n );\n case \"trayClick\":\n case \"trayDoubleClick\":\n return (\n typeof value.appId === \"string\" &&\n typeof value.trayId === \"string\" &&\n isMouseButton(value.button) &&\n typeof value.x === \"number\" &&\n typeof value.y === \"number\"\n );\n default:\n return false;\n }\n};\n\nconst isMouseButton = (value: unknown): value is MouseButton =>\n value === \"left\" || value === \"right\" || value === \"middle\";\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opentray/spec",
3
- "version": "0.14.4",
3
+ "version": "0.15.0",
4
4
  "description": "Shared TypeScript protocol and contract types for OpenTray.",
5
5
  "type": "module",
6
6
  "license": "MIT",