@opentray/ext-badge 0.18.0 → 0.19.1

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 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../src/native-artifact.ts","../src/shared.ts","../src/index.ts"],"sourcesContent":["// Orthogonal intents (2026-07-19; original user request: pnpm install must be sufficient):\n// 1. Declare the official Badge platform package closure as platform-neutral data.\n// 2. Keep native package selection relative to this facade instead of consumer cwd.\n\nimport type { NativeExtensionPackageArtifact } from \"opentray\";\n\nexport const BADGE_NATIVE_ARTIFACT = {\n kind: \"package\",\n packageJsonUrl: new URL(\"../package.json\", import.meta.url).href,\n contractManifestUrl: new URL(\"../contract.json\", import.meta.url).href,\n targets: {\n \"darwin-arm64\": {\n packageName: \"@opentray/ext-badge-darwin-arm64\",\n libraryPath: \"lib/libopentray_ext_badge.dylib\",\n },\n \"darwin-x64\": {\n packageName: \"@opentray/ext-badge-darwin-x64\",\n libraryPath: \"lib/libopentray_ext_badge.dylib\",\n },\n \"win32-arm64\": {\n packageName: \"@opentray/ext-badge-windows-arm64\",\n libraryPath: \"bin/opentray_ext_badge.dll\",\n },\n \"win32-x64\": {\n packageName: \"@opentray/ext-badge-windows-x64\",\n libraryPath: \"bin/opentray_ext_badge.dll\",\n },\n },\n} satisfies NativeExtensionPackageArtifact;\n","export type BadgeCapabilityLevel = \"native\" | \"reduced\" | \"unsupported\";\n\nexport type BadgePlatform = \"darwin\" | \"win32\" | \"linux\";\n\nexport interface BadgeState {\n badgeText: string;\n badgeCount: number | null;\n progressValue: number;\n progressMax: number;\n progressState: \"none\" | \"indeterminate\" | \"normal\" | \"paused\" | \"error\";\n overlayIcon: \"none\" | \"dot\" | \"alert\";\n attention: boolean;\n}\n\nexport interface BadgeCapabilityFamily {\n badgeText: BadgeCapabilityLevel;\n progress: BadgeCapabilityLevel;\n overlayIcon: BadgeCapabilityLevel;\n attention: BadgeCapabilityLevel;\n}\n\nexport interface BadgeCapabilities {\n platform: BadgePlatform;\n mode: \"native\" | \"reduced\" | \"unsupported\";\n capabilities: BadgeCapabilityFamily;\n state: BadgeState;\n reason?: string;\n}\n\nexport type BadgeCommand =\n | { type: \"getCapabilities\" }\n | { type: \"setBadge\"; value: string }\n | { type: \"clearBadge\" }\n | { type: \"setProgress\"; value: number; max?: number }\n | { type: \"setProgressState\"; value: BadgeState[\"progressState\"] }\n | { type: \"setOverlayIcon\"; value: BadgeState[\"overlayIcon\"] }\n | { type: \"setAttention\"; value: boolean }\n | { type: \"showPanel\" }\n | { type: \"hidePanel\" }\n | { type: \"reset\" }\n ;\n\nexport type BadgeEvent =\n | { type: \"capabilities\"; snapshot: BadgeCapabilities }\n | { type: \"state\"; snapshot: BadgeCapabilities }\n | { type: \"result\"; op: string; ok: true; snapshot: BadgeCapabilities }\n | { type: \"result\"; op: string; ok: false; error: string; snapshot: BadgeCapabilities };\n\nexport interface BadgeHandle {\n getCapabilities(): Promise<BadgeCapabilities>;\n setBadge(value: string): Promise<BadgeCapabilities>;\n clearBadge(): Promise<BadgeCapabilities>;\n setProgress(value: number, max?: number): Promise<BadgeCapabilities>;\n setProgressState(value: BadgeState[\"progressState\"]): Promise<BadgeCapabilities>;\n setOverlayIcon(value: BadgeState[\"overlayIcon\"]): Promise<BadgeCapabilities>;\n setAttention(value: boolean): Promise<BadgeCapabilities>;\n showPanel(): Promise<BadgeCapabilities>;\n hidePanel(): Promise<BadgeCapabilities>;\n reset(): Promise<BadgeCapabilities>;\n}\n\nexport interface BadgePanelEnvelope {\n platform: BadgePlatform;\n mode: \"native\" | \"reduced\" | \"unsupported\";\n capabilities: BadgeCapabilityFamily;\n state: BadgeState;\n log: string[];\n reason?: string;\n}\n\nexport const defaultBadgeState = (): BadgeState => ({\n badgeText: \"12\",\n badgeCount: 12,\n progressValue: 0,\n progressMax: 100,\n progressState: \"none\",\n overlayIcon: \"dot\",\n attention: false,\n});\n\nexport const defaultBadgeCapabilities = (platform: BadgePlatform): BadgeCapabilities => {\n const common = {\n badgeText: \"reduced\",\n progress: \"unsupported\",\n overlayIcon: \"reduced\",\n attention: \"reduced\",\n } satisfies BadgeCapabilityFamily;\n return {\n platform,\n mode: \"reduced\",\n capabilities: common,\n state: defaultBadgeState(),\n reason: \"badge projection is currently reduced to a local proof surface\",\n };\n};\n\nexport const normalizeProgress = (value: number, max?: number): { value: number; max: number } => {\n const normalizedMax = Number.isFinite(max ?? 100) ? Math.max(1, Math.round(max ?? 100)) : 100;\n const normalizedValue = Number.isFinite(value) ? Math.max(0, Math.min(normalizedMax, Math.round(value))) : 0;\n return { value: normalizedValue, max: normalizedMax };\n};\n\nexport const normalizeBadgeText = (value: string): { badgeText: string; badgeCount: number | null } => {\n const badgeText = value.trim();\n const parsed = Number.parseInt(badgeText, 10);\n return {\n badgeText,\n badgeCount: Number.isFinite(parsed) ? parsed : null,\n };\n};\n\nexport const badgePanelEnvelopeFromCapabilities = (\n snapshot: BadgeCapabilities,\n): BadgePanelEnvelope => ({\n platform: snapshot.platform,\n mode: snapshot.mode,\n capabilities: snapshot.capabilities,\n state: snapshot.state,\n log: [],\n ...(snapshot.reason === undefined ? {} : { reason: snapshot.reason }),\n});\n","import type { ExtensionEnvelope } from \"@opentray/spec\";\nimport type { NativeExtensionArtifact, TrayHandle } from \"opentray\";\n\nimport { BADGE_NATIVE_ARTIFACT } from \"./native-artifact\";\n\nimport {\n badgePanelEnvelopeFromCapabilities,\n defaultBadgeCapabilities,\n normalizeBadgeText,\n normalizeProgress,\n type BadgeCapabilities,\n type BadgeCapabilityFamily,\n type BadgeEvent,\n type BadgeHandle,\n type BadgePanelEnvelope,\n type BadgePlatform,\n type BadgeState,\n} from \"./shared\";\n\nexport type * from \"./shared\";\nexport { badgePanelEnvelopeFromCapabilities } from \"./shared\";\n\nconst BADGE_EXTENSION_NAME = \"badge\";\nexport interface BadgeExtensionOptions {\n mountId?: string;\n artifact?: NativeExtensionArtifact;\n platform?: BadgePlatform;\n}\n\nexport interface BadgeExtensionCapability extends BadgeHandle {\n readonly platform: BadgePlatform;\n readonly getPanelEnvelope: () => Promise<BadgePanelEnvelope>;\n}\n\nexport const attachBadge = (tray: TrayHandle, options: BadgeExtensionOptions = {}): BadgeExtensionCapability => {\n const platform = options.platform ?? process.platform as BadgePlatform;\n const extension = tray.extend(BadgeExt, options);\n return {\n ...extension,\n platform,\n getPanelEnvelope: async () => badgePanelEnvelopeFromCapabilities(await extension.getCapabilities()),\n };\n};\n\nexport const BadgeExt = {\n name: BADGE_EXTENSION_NAME,\n artifact: BADGE_NATIVE_ARTIFACT,\n resolveMount(options: BadgeExtensionOptions | undefined) {\n return {\n ...(options?.mountId === undefined ? {} : { mountId: options.mountId }),\n ...(options?.artifact === undefined ? {} : { artifact: options.artifact }),\n };\n },\n extend(tray: TrayHandle, context, options: BadgeExtensionOptions | undefined): BadgeHandle {\n const requestedPlatform = options?.platform ?? (process.platform as BadgePlatform);\n const snapshot = defaultBadgeCapabilities(requestedPlatform);\n return createBadgeHandle(() => context.ensureLoaded(), tray, context.mountId, snapshot);\n },\n} satisfies import(\"opentray\").TrayExtension<BadgeHandle, BadgeExtensionOptions>;\n\nexport const isBadgeEvent = (event: ExtensionEnvelope): event is ExtensionEnvelope<BadgeEvent> =>\n event.scope.ext === BADGE_EXTENSION_NAME &&\n typeof event.data === \"object\" &&\n event.data !== null &&\n \"type\" in event.data;\n\nfunction createBadgeHandle(\n ensureLoaded: () => Promise<void>,\n tray: TrayHandle,\n mountId: string,\n seed: BadgeCapabilities,\n): BadgeHandle {\n const state: BadgeState = structuredClone(seed.state);\n const capabilities: BadgeCapabilityFamily = { ...seed.capabilities };\n const platform = seed.platform;\n const mode = seed.mode;\n const reason = seed.reason;\n\n const snapshot = (): BadgeCapabilities => ({\n platform,\n mode,\n capabilities: { ...capabilities },\n state: structuredClone(state),\n ...(reason === undefined ? {} : { reason }),\n });\n\n const rejectUnsupported = (family: keyof BadgeCapabilityFamily, op: string): never => {\n const support = capabilities[family];\n throw new Error(`${op} is ${support} on ${platform}`);\n };\n\n return {\n getCapabilities: async () => {\n await ensureLoaded();\n await tray.requestExtension(mountId, { type: \"getCapabilities\" });\n return snapshot();\n },\n setBadge: async (value: string) => {\n await ensureLoaded();\n const normalized = normalizeBadgeText(value);\n state.badgeText = normalized.badgeText;\n state.badgeCount = normalized.badgeCount;\n await tray.commandExtension(mountId, { type: \"setBadge\", value: normalized.badgeText });\n return snapshot();\n },\n clearBadge: async () => {\n await ensureLoaded();\n state.badgeText = \"\";\n state.badgeCount = null;\n await tray.commandExtension(mountId, { type: \"clearBadge\" });\n return snapshot();\n },\n setProgress: async (value: number, max?: number) => {\n await ensureLoaded();\n if (capabilities.progress === \"unsupported\") {\n rejectUnsupported(\"progress\", \"setProgress\");\n }\n const normalized = normalizeProgress(value, max);\n state.progressValue = normalized.value;\n state.progressMax = normalized.max;\n await tray.commandExtension(mountId, { type: \"setProgress\", value: normalized.value, max: normalized.max });\n return snapshot();\n },\n setProgressState: async (value: BadgeState[\"progressState\"]) => {\n await ensureLoaded();\n if (capabilities.progress === \"unsupported\") {\n rejectUnsupported(\"progress\", \"setProgressState\");\n }\n state.progressState = value;\n await tray.commandExtension(mountId, { type: \"setProgressState\", value });\n return snapshot();\n },\n setOverlayIcon: async (value: BadgeState[\"overlayIcon\"]) => {\n await ensureLoaded();\n state.overlayIcon = value;\n await tray.commandExtension(mountId, { type: \"setOverlayIcon\", value });\n return snapshot();\n },\n setAttention: async (value: boolean) => {\n await ensureLoaded();\n state.attention = Boolean(value);\n await tray.commandExtension(mountId, { type: \"setAttention\", value: Boolean(value) });\n return snapshot();\n },\n showPanel: async () => {\n await ensureLoaded();\n await tray.commandExtension(mountId, { type: \"showPanel\" });\n return snapshot();\n },\n hidePanel: async () => {\n await ensureLoaded();\n await tray.commandExtension(mountId, { type: \"hidePanel\" });\n return snapshot();\n },\n reset: async () => {\n await ensureLoaded();\n Object.assign(state, seed.state);\n await tray.commandExtension(mountId, { type: \"reset\" });\n return snapshot();\n },\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/native-artifact.ts","../src/shared.ts","../src/index.ts"],"sourcesContent":["// Orthogonal intents (2026-07-19; original user request: pnpm install must be sufficient):\n// 1. Declare the official Badge platform package closure as platform-neutral data.\n// 2. Keep native package selection relative to this facade instead of consumer cwd.\n\nimport type { NativeExtensionPackageArtifact } from \"opentray\";\n\nexport const BADGE_NATIVE_ARTIFACT = {\n kind: \"package\",\n packageJsonUrl: new URL(\"../package.json\", import.meta.url).href,\n contractManifestUrl: new URL(\"../contract.json\", import.meta.url).href,\n targets: {\n \"darwin-arm64\": {\n packageName: \"@opentray/ext-badge-darwin-arm64\",\n libraryPath: \"lib/libopentray_ext_badge.dylib\",\n },\n \"darwin-x64\": {\n packageName: \"@opentray/ext-badge-darwin-x64\",\n libraryPath: \"lib/libopentray_ext_badge.dylib\",\n },\n \"win32-arm64\": {\n packageName: \"@opentray/ext-badge-windows-arm64\",\n libraryPath: \"bin/opentray_ext_badge.dll\",\n },\n \"win32-x64\": {\n packageName: \"@opentray/ext-badge-windows-x64\",\n libraryPath: \"bin/opentray_ext_badge.dll\",\n },\n },\n} satisfies NativeExtensionPackageArtifact;\n","export type BadgeCapabilityLevel = \"native\" | \"reduced\" | \"unsupported\";\n\nexport type BadgePlatform = \"darwin\" | \"win32\" | \"linux\";\n\nexport interface BadgeState {\n badgeText: string;\n badgeCount: number | null;\n progressValue: number;\n progressMax: number;\n progressState: \"none\" | \"indeterminate\" | \"normal\" | \"paused\" | \"error\";\n overlayIcon: \"none\" | \"dot\" | \"alert\";\n attention: boolean;\n}\n\nexport interface BadgeCapabilityFamily {\n badgeText: BadgeCapabilityLevel;\n progress: BadgeCapabilityLevel;\n overlayIcon: BadgeCapabilityLevel;\n attention: BadgeCapabilityLevel;\n}\n\nexport interface BadgeCapabilities {\n platform: BadgePlatform;\n mode: \"native\" | \"reduced\" | \"unsupported\";\n capabilities: BadgeCapabilityFamily;\n state: BadgeState;\n reason?: string;\n}\n\nexport type BadgeCommand =\n | { type: \"getCapabilities\" }\n | { type: \"setBadge\"; value: string }\n | { type: \"clearBadge\" }\n | { type: \"setProgress\"; value: number; max?: number }\n | { type: \"setProgressState\"; value: BadgeState[\"progressState\"] }\n | { type: \"setOverlayIcon\"; value: BadgeState[\"overlayIcon\"] }\n | { type: \"setAttention\"; value: boolean }\n | { type: \"showPanel\" }\n | { type: \"hidePanel\" }\n | { type: \"reset\" }\n ;\n\nexport type BadgeEvent =\n | { type: \"capabilities\"; snapshot: BadgeCapabilities }\n | { type: \"state\"; snapshot: BadgeCapabilities }\n | { type: \"result\"; op: string; ok: true; snapshot: BadgeCapabilities }\n | { type: \"result\"; op: string; ok: false; error: string; snapshot: BadgeCapabilities };\n\nexport interface BadgeHandle {\n getCapabilities(): Promise<BadgeCapabilities>;\n setBadge(value: string): Promise<BadgeCapabilities>;\n clearBadge(): Promise<BadgeCapabilities>;\n setProgress(value: number, max?: number): Promise<BadgeCapabilities>;\n setProgressState(value: BadgeState[\"progressState\"]): Promise<BadgeCapabilities>;\n setOverlayIcon(value: BadgeState[\"overlayIcon\"]): Promise<BadgeCapabilities>;\n setAttention(value: boolean): Promise<BadgeCapabilities>;\n showPanel(): Promise<BadgeCapabilities>;\n hidePanel(): Promise<BadgeCapabilities>;\n reset(): Promise<BadgeCapabilities>;\n}\n\nexport interface BadgePanelEnvelope {\n platform: BadgePlatform;\n mode: \"native\" | \"reduced\" | \"unsupported\";\n capabilities: BadgeCapabilityFamily;\n state: BadgeState;\n log: string[];\n reason?: string;\n}\n\nexport const defaultBadgeState = (): BadgeState => ({\n badgeText: \"12\",\n badgeCount: 12,\n progressValue: 0,\n progressMax: 100,\n progressState: \"none\",\n overlayIcon: \"dot\",\n attention: false,\n});\n\nexport const defaultBadgeCapabilities = (platform: BadgePlatform): BadgeCapabilities => {\n const common = {\n badgeText: \"reduced\",\n progress: \"unsupported\",\n overlayIcon: \"reduced\",\n attention: \"reduced\",\n } satisfies BadgeCapabilityFamily;\n return {\n platform,\n mode: \"reduced\",\n capabilities: common,\n state: defaultBadgeState(),\n reason: \"badge projection is currently reduced to a local proof surface\",\n };\n};\n\nexport const normalizeProgress = (value: number, max?: number): { value: number; max: number } => {\n const normalizedMax = Number.isFinite(max ?? 100) ? Math.max(1, Math.round(max ?? 100)) : 100;\n const normalizedValue = Number.isFinite(value) ? Math.max(0, Math.min(normalizedMax, Math.round(value))) : 0;\n return { value: normalizedValue, max: normalizedMax };\n};\n\nexport const normalizeBadgeText = (value: string): { badgeText: string; badgeCount: number | null } => {\n const badgeText = value.trim();\n const parsed = Number.parseInt(badgeText, 10);\n return {\n badgeText,\n badgeCount: Number.isFinite(parsed) ? parsed : null,\n };\n};\n\nexport const badgePanelEnvelopeFromCapabilities = (\n snapshot: BadgeCapabilities,\n): BadgePanelEnvelope => ({\n platform: snapshot.platform,\n mode: snapshot.mode,\n capabilities: snapshot.capabilities,\n state: snapshot.state,\n log: [],\n ...(snapshot.reason === undefined ? {} : { reason: snapshot.reason }),\n});\n","import type { ExtensionEnvelope } from \"@opentray/spec\";\nimport type { NativeExtensionArtifact, TrayHandle } from \"opentray\";\n\nimport { BADGE_NATIVE_ARTIFACT } from \"./native-artifact\";\n\nimport {\n badgePanelEnvelopeFromCapabilities,\n defaultBadgeCapabilities,\n normalizeBadgeText,\n normalizeProgress,\n type BadgeCapabilities,\n type BadgeCapabilityFamily,\n type BadgeEvent,\n type BadgeHandle,\n type BadgePanelEnvelope,\n type BadgePlatform,\n type BadgeState,\n} from \"./shared\";\n\nexport type * from \"./shared\";\nexport { badgePanelEnvelopeFromCapabilities } from \"./shared\";\n\nconst BADGE_EXTENSION_NAME = \"badge\";\nexport interface BadgeExtensionOptions {\n mountId?: string;\n artifact?: NativeExtensionArtifact;\n platform?: BadgePlatform;\n}\n\nexport interface BadgeExtensionCapability extends BadgeHandle {\n readonly platform: BadgePlatform;\n readonly getPanelEnvelope: () => Promise<BadgePanelEnvelope>;\n}\n\nexport const attachBadge = (tray: TrayHandle, options: BadgeExtensionOptions = {}): BadgeExtensionCapability => {\n const platform = options.platform ?? process.platform as BadgePlatform;\n const extension = tray.extend(BadgeExt, options);\n return {\n ...extension,\n platform,\n getPanelEnvelope: async () => badgePanelEnvelopeFromCapabilities(await extension.getCapabilities()),\n };\n};\n\nexport const BadgeExt = {\n name: BADGE_EXTENSION_NAME,\n artifact: BADGE_NATIVE_ARTIFACT,\n resolveMount(options: BadgeExtensionOptions | undefined) {\n return {\n ...(options?.mountId === undefined ? {} : { mountId: options.mountId }),\n ...(options?.artifact === undefined ? {} : { artifact: options.artifact }),\n };\n },\n extend(tray: TrayHandle, context, options: BadgeExtensionOptions | undefined): BadgeHandle {\n const requestedPlatform = options?.platform ?? (process.platform as BadgePlatform);\n const snapshot = defaultBadgeCapabilities(requestedPlatform);\n return createBadgeHandle(() => context.ensureLoaded(), tray, context.mountId, snapshot);\n },\n} satisfies import(\"opentray\").TrayExtension<BadgeHandle, BadgeExtensionOptions>;\n\nexport const isBadgeEvent = (event: ExtensionEnvelope): event is ExtensionEnvelope<BadgeEvent> =>\n event.scope.ext === BADGE_EXTENSION_NAME &&\n typeof event.data === \"object\" &&\n event.data !== null &&\n \"type\" in event.data;\n\nfunction createBadgeHandle(\n ensureLoaded: () => Promise<void>,\n tray: TrayHandle,\n mountId: string,\n seed: BadgeCapabilities,\n): BadgeHandle {\n const state: BadgeState = structuredClone(seed.state);\n const capabilities: BadgeCapabilityFamily = { ...seed.capabilities };\n const platform = seed.platform;\n const mode = seed.mode;\n const reason = seed.reason;\n\n const snapshot = (): BadgeCapabilities => ({\n platform,\n mode,\n capabilities: { ...capabilities },\n state: structuredClone(state),\n ...(reason === undefined ? {} : { reason }),\n });\n\n const rejectUnsupported = (family: keyof BadgeCapabilityFamily, op: string): never => {\n const support = capabilities[family];\n throw new Error(`${op} is ${support} on ${platform}`);\n };\n\n return {\n getCapabilities: async () => {\n await ensureLoaded();\n await tray.requestExtension(mountId, { type: \"getCapabilities\" });\n return snapshot();\n },\n setBadge: async (value: string) => {\n await ensureLoaded();\n const normalized = normalizeBadgeText(value);\n state.badgeText = normalized.badgeText;\n state.badgeCount = normalized.badgeCount;\n await tray.commandExtension(mountId, { type: \"setBadge\", value: normalized.badgeText });\n return snapshot();\n },\n clearBadge: async () => {\n await ensureLoaded();\n state.badgeText = \"\";\n state.badgeCount = null;\n await tray.commandExtension(mountId, { type: \"clearBadge\" });\n return snapshot();\n },\n setProgress: async (value: number, max?: number) => {\n await ensureLoaded();\n if (capabilities.progress === \"unsupported\") {\n rejectUnsupported(\"progress\", \"setProgress\");\n }\n const normalized = normalizeProgress(value, max);\n state.progressValue = normalized.value;\n state.progressMax = normalized.max;\n await tray.commandExtension(mountId, { type: \"setProgress\", value: normalized.value, max: normalized.max });\n return snapshot();\n },\n setProgressState: async (value: BadgeState[\"progressState\"]) => {\n await ensureLoaded();\n if (capabilities.progress === \"unsupported\") {\n rejectUnsupported(\"progress\", \"setProgressState\");\n }\n state.progressState = value;\n await tray.commandExtension(mountId, { type: \"setProgressState\", value });\n return snapshot();\n },\n setOverlayIcon: async (value: BadgeState[\"overlayIcon\"]) => {\n await ensureLoaded();\n state.overlayIcon = value;\n await tray.commandExtension(mountId, { type: \"setOverlayIcon\", value });\n return snapshot();\n },\n setAttention: async (value: boolean) => {\n await ensureLoaded();\n state.attention = Boolean(value);\n await tray.commandExtension(mountId, { type: \"setAttention\", value: Boolean(value) });\n return snapshot();\n },\n showPanel: async () => {\n await ensureLoaded();\n await tray.commandExtension(mountId, { type: \"showPanel\" });\n return snapshot();\n },\n hidePanel: async () => {\n await ensureLoaded();\n await tray.commandExtension(mountId, { type: \"hidePanel\" });\n return snapshot();\n },\n reset: async () => {\n await ensureLoaded();\n Object.assign(state, seed.state);\n await tray.commandExtension(mountId, { type: \"reset\" });\n return snapshot();\n },\n };\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opentray/ext-badge",
3
- "version": "0.18.0",
3
+ "version": "0.19.1",
4
4
  "description": "Official OpenTray status extension backed by the OpenTray extension ABI.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -25,17 +25,17 @@
25
25
  "opentray": ">=0.0.0"
26
26
  },
27
27
  "optionalDependencies": {
28
- "@opentray/ext-badge-darwin-arm64": "0.18.0",
29
- "@opentray/ext-badge-darwin-x64": "0.18.0",
30
- "@opentray/ext-badge-windows-arm64": "0.18.0",
31
- "@opentray/ext-badge-windows-x64": "0.18.0"
28
+ "@opentray/ext-badge-darwin-arm64": "0.19.1",
29
+ "@opentray/ext-badge-darwin-x64": "0.19.1",
30
+ "@opentray/ext-badge-windows-arm64": "0.19.1",
31
+ "@opentray/ext-badge-windows-x64": "0.19.1"
32
32
  },
33
33
  "devDependencies": {
34
34
  "tsdown": "^0.22.1",
35
35
  "typescript": "^6.0.3",
36
36
  "vitest": "^4.1.7",
37
- "@opentray/spec": "0.18.0",
38
- "opentray": "0.18.0"
37
+ "@opentray/spec": "0.19.1",
38
+ "opentray": "0.19.1"
39
39
  },
40
40
  "scripts": {
41
41
  "build": "tsdown src/index.ts --format esm --dts",