Upgrade buttplug from v3 to v4#83
Conversation
📝 WalkthroughWalkthroughBumps buttplug to ^5.0.1; migrates device I/O to feature-based InputType/OutputType (doRefresh/runInput, setAttribute/runOutput with DeviceOutputCommand); replaces custom websocket connector with ButtplugNodeWebsocketClientConnector; rewrites attribute factory; updates unit tests; makes StopScriptController.execute async. ChangesButtplug v5 API Migration
Sequence DiagramsequenceDiagram
participant App as Application
participant Dev as ButtplugIoDevice
participant F as Feature
App->>Dev: doRefresh()
Dev->>F: runInput(InputCommandType.Read)
F-->>Dev: input result
Dev->>Dev: update attribute (InputType-index)
App->>Dev: setAttribute(OutputType-index, value)
Dev->>Dev: createOutputCommand(OutputType, value)
Dev->>F: runOutput(DeviceOutputCommand)
F-->>Dev: output complete
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related issues
Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 3❌ Failed checks (2 warnings, 1 inconclusive)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/device/protocol/buttplugIo/buttplugIoDeviceFactory.ts`:
- Around line 65-99: The DeviceAttributeModifier values are flipped: in the
outputs loop (for (const [outputType, output] of feature.outputs) ...) replace
DeviceAttributeModifier.readOnly with DeviceAttributeModifier.writeOnly when
calling IntRangeDeviceAttribute.createInitialized for attrName, and in the
inputs loop (for (const [inputType, input] of feature.inputs) ...) replace
DeviceAttributeModifier.writeOnly with DeviceAttributeModifier.readOnly so
actuators created by IntRangeDeviceAttribute.createInitialized are writable and
sensors are readable; keep the rest of the attribute initialization (attrName,
feature.featureDescriptor, valueRange, step, default) unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 663ff87a-a8c1-4aef-a151-49973aa4c527
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (2)
package.jsonsrc/device/protocol/buttplugIo/buttplugIoDeviceFactory.ts
- Replace ActuatorType/SensorType enums with OutputType/InputType - Replace messageAttributes API with new features Map API - Use DeviceOutput.X.percent() for sending actuator commands - Delete SlvCtrlPlusButtplugWebsocketClientConnector workaround (fixed upstream in v4) Closes #69 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
820b8b0 to
f7895e7
Compare
There was a problem hiding this comment.
♻️ Duplicate comments (1)
src/device/protocol/buttplugIo/buttplugIoDeviceFactory.ts (1)
97-100:⚠️ Potential issue | 🟠 Major | ⚡ Quick winPass the requested modifier through for boolean features.
This helper hardcodes
DeviceAttributeModifier.writeOnlyfor every[0, 1]range, so boolean inputs created from Line 82 are modeled as write-only again. That breaks any binary sensor feature even though the caller already classified it asreadOnly.Proposed fix
if (valueRangeMin === 0 && valueRangeMax === 1) { return BoolDeviceAttribute.createInitialized( - attrName, featureDescriptor, DeviceAttributeModifier.writeOnly, false + attrName, featureDescriptor || undefined, attributeModifier, false ); }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/device/protocol/buttplugIo/buttplugIoDeviceFactory.ts` around lines 97 - 100, The boolean-attribute branch hardcodes DeviceAttributeModifier.writeOnly when valueRangeMin === 0 && valueRangeMax === 1; change the call to BoolDeviceAttribute.createInitialized to pass the incoming/requested modifier (the variable used earlier to represent the attribute modifier) instead of always using writeOnly so callers that classified the feature as readOnly are preserved; update the invocation that currently supplies DeviceAttributeModifier.writeOnly to use that modifier variable along with attrName, featureDescriptor and the default value.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Duplicate comments:
In `@src/device/protocol/buttplugIo/buttplugIoDeviceFactory.ts`:
- Around line 97-100: The boolean-attribute branch hardcodes
DeviceAttributeModifier.writeOnly when valueRangeMin === 0 && valueRangeMax ===
1; change the call to BoolDeviceAttribute.createInitialized to pass the
incoming/requested modifier (the variable used earlier to represent the
attribute modifier) instead of always using writeOnly so callers that classified
the feature as readOnly are preserved; update the invocation that currently
supplies DeviceAttributeModifier.writeOnly to use that modifier variable along
with attrName, featureDescriptor and the default value.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: e3815912-9398-4d83-99bf-df36f1c8f4ff
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (7)
package.jsonsrc/controller/automation/stopScriptController.tssrc/device/protocol/buttplugIo/buttplugIoDevice.tssrc/device/protocol/buttplugIo/buttplugIoDeviceFactory.tssrc/device/protocol/buttplugIo/buttplugIoWebsocketDeviceProvider.tssrc/device/protocol/buttplugIo/slvCtrlPlusButtplugWebsocketClientConnector.tstests/unit/device/protocol/buttplugIo/buttplugIoDevice.spec.ts
💤 Files with no reviewable changes (1)
- src/device/protocol/buttplugIo/slvCtrlPlusButtplugWebsocketClientConnector.ts
🚧 Files skipped from review as they are similar to previous changes (4)
- src/device/protocol/buttplugIo/buttplugIoWebsocketDeviceProvider.ts
- package.json
- src/device/protocol/buttplugIo/buttplugIoDevice.ts
- tests/unit/device/protocol/buttplugIo/buttplugIoDevice.spec.ts
Summary
buttplugfrom^3.2.1to^4.0.2messageAttributesAPI with the newfeaturesMap API (ButtplugClientDevice.features)ActuatorType/SensorTypeenums withOutputType/InputTypeDeviceOutput.X.percent(value)for sending actuator commands viaButtplugClientDeviceFeature.runOutput()SlvCtrlPlusButtplugWebsocketClientConnector— the workaround was already marked with a comment "until upgraded to buttplug@4.0.0"; the upstreamconnect()error handling is fixed in v4Notes
The v4
ButtplugClientDeviceFeaturepublic API does not exposeFeatureDescriptoror device-specific step counts, so attribute labels default toundefinedand actuator range attributes use a standard 0–100 step count (percent-based sending means the library handles the conversion to device-specific steps internally).Test plan
npm run typecheckpassesnpm test— all 72 tests passCloses #69
🤖 Generated with Claude Code
Summary by CodeRabbit
Dependencies
Improvements
Tests