diff --git a/.npmrc b/.npmrc index 51ddce0d..4ba08b07 100644 --- a/.npmrc +++ b/.npmrc @@ -1 +1 @@ -allow-git=root +allow-git=all diff --git a/build/check-bundle-size.ts b/build/check-bundle-size.ts index e8248fd2..6b4e27cb 100644 --- a/build/check-bundle-size.ts +++ b/build/check-bundle-size.ts @@ -24,8 +24,11 @@ const BUDGET_BYTES: Record = { // binding, canvas-drawn SV/hue surfaces, and hex/swatch sync. // Raised from 427 kB for the second, dedicated Lighting-tab card: the // render path now drives both the Advanced-tab card and the new tab. + // Raised from 429 kB for the dedicated Razer Cobra driver: the protocol + // registry now bundles the Cobra HID client, its extended-matrix lighting + // payloads, and the Cobra picker filter alongside the other Razer drivers. // Protocol tests and preview fixtures remain unbundled. - ".js": 429_000, + ".js": 435_000, }; const ASSETS = join("dist", "assets"); diff --git a/package-lock.json b/package-lock.json index fc1be66a..936773b7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,7 +8,7 @@ "name": "openmouse", "version": "0.1.0", "dependencies": { - "@openmouse/protocol": "github:OpenMouse-Project/mouse-protocol" + "@openmouse/protocol": "https://github.com/OpenMouse-Project/mouse-protocol.git" }, "devDependencies": { "typescript": "^5.8.3", @@ -459,7 +459,7 @@ }, "node_modules/@openmouse/protocol": { "version": "0.1.0", - "resolved": "git+ssh://git@github.com/OpenMouse-Project/mouse-protocol.git#fd991408703042a0965225a04e63206c5adbb62e", + "resolved": "git+ssh://git@github.com/OpenMouse-Project/mouse-protocol.git#88cd1cb25cafa3a041530e2423dfe1d82af4c000", "engines": { "node": ">=20" } diff --git a/public/devices/razer-cobra.webp b/public/devices/razer-cobra.webp new file mode 100644 index 00000000..e5012cdf Binary files /dev/null and b/public/devices/razer-cobra.webp differ diff --git a/src/control.ts b/src/control.ts index f4c814fc..5a3ff801 100644 --- a/src/control.ts +++ b/src/control.ts @@ -90,6 +90,7 @@ import { PulsarProHidClient } from "@openmouse/protocol/drivers/pulsar/pulsar-pr import { OrbitalHidClient } from "@openmouse/protocol/drivers/orbital/hid"; import { RazerHidClient } from "@openmouse/protocol/drivers/razer/hid"; import { RazerViperMiniHidClient } from "@openmouse/protocol/drivers/razer/viper-mini-hid"; +import { RazerCobraHidClient } from "@openmouse/protocol/drivers/razer/cobra-hid"; import { RazerViperHidClient } from "@openmouse/protocol/drivers/razer/viper-hid" import { RazerViperV4ProHidClient } from "@openmouse/protocol/drivers/razer/viper-v4-pro-hid"; import { RAZER_PRODUCTS } from "@openmouse/protocol/razer-devices"; @@ -129,7 +130,7 @@ let activeEggClient: EggOp1HidClient | null = null; let activeEggWeClient: EggWeHidClient | null = null; let activeDmClient: WLMouseHidClient | LamzuHidClient | AtkHidClient | NinjutsoHidClient | null = null; let activeOrbitalClient: OrbitalHidClient | null = null; -let activeRazerClient: RazerHidClient | RazerViperMiniHidClient | RazerViperHidClient | null = null; +let activeRazerClient: RazerHidClient | RazerViperMiniHidClient | RazerViperHidClient | RazerCobraHidClient | null = null; let activeTeevolutionClient: TeevolutionHidClient | null = null; let activeVgnClient: VgnF2HidClient | null = null; let activeViperClient: RazerViperV4ProHidClient | null = null; @@ -1949,7 +1950,7 @@ async function activateClient(client: SupportedClient): Promise { dpiOptions = client.getDpiOptions(); configureDpiControl(status.dpi); showStatus(status); - } else if (client instanceof RazerHidClient || client instanceof RazerViperMiniHidClient || client instanceof RazerViperHidClient) { + } else if (client instanceof RazerHidClient || client instanceof RazerViperMiniHidClient || client instanceof RazerViperHidClient || client instanceof RazerCobraHidClient) { activeRazerClient = client; const status = await client.readStatus(); deviceStatuses.set(client.device, status); diff --git a/src/preview-fixtures.ts b/src/preview-fixtures.ts index 13d4caa8..56476962 100644 --- a/src/preview-fixtures.ts +++ b/src/preview-fixtures.ts @@ -260,6 +260,22 @@ const RAZER_VIPER_MINI: MouseStatus = { firmware: ["Mouse 1.01"], }; +const RAZER_COBRA: MouseStatus = { + ...RAZER_VIPER_MINI, + name: "Cobra", + dpi: 1600, + dpiY: 1600, + ui: { + family: "razer", + settingsReady: true, + valuesVerified: true, + hideUnsupportedPollingRates: true, + hideProcessingCard: true, + defaultDisplayName: "Cobra", + }, + firmware: ["Mouse 1.00"], +}; + const TEEVOLUTION: MouseStatus = { brand: "Teevolution", name: "Terra Pro", @@ -415,6 +431,7 @@ export const PREVIEW_FIXTURES: Record = { orbital: { label: "Orbital One", status: ORBITAL }, razer: { label: "Razer Viper V3 Pro", status: RAZER }, "razer-viper-mini": { label: "Razer Viper Mini", status: RAZER_VIPER_MINI }, + "razer-cobra": { label: "Razer Cobra", status: RAZER_COBRA }, "razer-viper-v4": { label: "Razer Viper V4 Pro", status: RAZER_VIPER_V4 }, teevolution: { label: "Teevolution Terra Pro", status: TEEVOLUTION }, vgn: { label: "VGN F2 Master Plus", status: VGN }, diff --git a/src/preview-modes.ts b/src/preview-modes.ts index ee1a7266..0b5f9d00 100644 --- a/src/preview-modes.ts +++ b/src/preview-modes.ts @@ -18,6 +18,7 @@ export const PREVIEW_KEYS = [ "orbital", "razer", "razer-viper-mini", + "razer-cobra", "razer-viper-v4", "teevolution", "vgn", @@ -45,6 +46,7 @@ export function parsePreviewMode(value: string | null): PreviewMode | null { case "orbital": return "orbital"; case "razer": return "razer"; case "razer-viper-mini": return "razer-viper-mini"; + case "razer-cobra": return "razer-cobra"; case "razer-viper-v4": return "razer-viper-v4"; case "teevolution": return "teevolution"; case "vgn": return "vgn"; diff --git a/src/ui/device-images.ts b/src/ui/device-images.ts index d13e3ce8..49d60239 100644 --- a/src/ui/device-images.ts +++ b/src/ui/device-images.ts @@ -13,6 +13,7 @@ const DEVICE_IMAGES: ReadonlyMap = new Map([ ["1532:00c0", "/devices/razer-viper-v3-pro.png"], ["1532:00c1", "/devices/razer-viper-v3-pro.png"], ["1532:008a", "/devices/razer-viper-mini.webp"], + ["1532:00a3", "/devices/razer-cobra.webp"], // OP1 8K, Purple Frost, and v2. XM2 models use different shells. ["3367:1964", "/devices/endgame-gear-op1-8k.png"], ["3367:1976", "/devices/endgame-gear-op1-8k.png"],