@switchbot/openapi-cli 2.6.2 → 2.6.3
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 +6 -3
- package/dist/commands/mcp.js +28 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -184,7 +184,10 @@ switchbot devices command --help
|
|
|
184
184
|
|
|
185
185
|
Intercepts every non-GET request: the CLI prints the URL/body it would have
|
|
186
186
|
sent, then exits `0` without contacting the API. `GET` requests (list, status,
|
|
187
|
-
query) are still executed so you can preview the state involved.
|
|
187
|
+
query) are still executed so you can preview the state involved. Dry-run also
|
|
188
|
+
validates command names against the device catalog and rejects unknown commands
|
|
189
|
+
(exit 2) when the device type has a known catalog entry. Commands sent to
|
|
190
|
+
read-only sensors (e.g. Meter) are likewise rejected.
|
|
188
191
|
|
|
189
192
|
```bash
|
|
190
193
|
switchbot devices command ABC123 turnOn --dry-run
|
|
@@ -305,7 +308,7 @@ Generic parameter shapes (which one applies is decided by the device — see the
|
|
|
305
308
|
|
|
306
309
|
Parameters for `setAll` (Air Conditioner), `setPosition` (Curtain / Blind Tilt), `setMode` (Relay Switch), `setBrightness` (dimmable lights), and `setColor` (Color Bulb / Strip Light / Ceiling Light) are validated client-side before the request — malformed shapes, out-of-range values, and JSON for CSV fields all fail fast with exit 2. `setColor` accepts `R:G:B`, `R,G,B`, `#RRGGBB`, `#RGB`, and CSS named colors (`red`, `blue`, …); all normalize to `R:G:B` before hitting the API. Pass `--skip-param-validation` to bypass (escape hatch — prefer fixing the argument). Command names are also case-normalized against the catalog (e.g. `turnon` is auto-corrected to `turnOn` with a stderr warning); unknown names still exit 2 with the supported-commands list.
|
|
307
310
|
|
|
308
|
-
Unknown deviceIds (not in the local cache) exit 2 by default so `--dry-run` is a reliable pre-flight gate. Run `switchbot devices list` first, or pass `--allow-unknown-device` for scripted pass-through.
|
|
311
|
+
Unknown deviceIds (not in the local cache) exit 2 by default so `--dry-run` is a reliable pre-flight gate. Unknown command names and commands on read-only sensors are also rejected during dry-run when the device type has a catalog entry. Run `switchbot devices list` first, or pass `--allow-unknown-device` for scripted pass-through.
|
|
309
312
|
|
|
310
313
|
Negative numeric parameters (e.g. `setBrightness -1` for a probe) are passed through to the command validator instead of being swallowed by the flag parser as an unknown option.
|
|
311
314
|
|
|
@@ -717,7 +720,7 @@ switchbot cache clear --key status
|
|
|
717
720
|
|
|
718
721
|
| Code | Meaning |
|
|
719
722
|
| ---- | ------------------------------------------------------------------------------------------------------------------------- |
|
|
720
|
-
| `0` | Success (including `--dry-run` intercept)
|
|
723
|
+
| `0` | Success (including `--dry-run` intercept when validation passes) |
|
|
721
724
|
| `1` | Runtime error — API error, network failure, missing credentials |
|
|
722
725
|
| `2` | Usage error — bad flag, missing/invalid argument, unknown subcommand, unknown device type, invalid URL, conflicting flags |
|
|
723
726
|
|
package/dist/commands/mcp.js
CHANGED
|
@@ -305,12 +305,34 @@ API docs: https://github.com/OpenWonderLabs/SwitchBotAPI`,
|
|
|
305
305
|
effectiveParameter = pv.normalized;
|
|
306
306
|
}
|
|
307
307
|
}
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
308
|
+
// Bug #55: validateCommand is lenient by design (passes unknown device
|
|
309
|
+
// types, ambiguous catalog matches). For dry-run we need stricter
|
|
310
|
+
// checking — query the catalog directly and reject unknown commands
|
|
311
|
+
// when the catalog has a definitive match.
|
|
312
|
+
if (effectiveType !== 'customize') {
|
|
313
|
+
const catalogMatch = findCatalogEntry(cached.type);
|
|
314
|
+
if (catalogMatch && !Array.isArray(catalogMatch)) {
|
|
315
|
+
const builtinCmds = catalogMatch.commands.filter((c) => c.commandType !== 'customize');
|
|
316
|
+
if (builtinCmds.length > 0) {
|
|
317
|
+
const exactMatch = builtinCmds.find((c) => c.command === command);
|
|
318
|
+
const caseMatch = !exactMatch
|
|
319
|
+
? builtinCmds.find((c) => c.command.toLowerCase() === command.toLowerCase())
|
|
320
|
+
: null;
|
|
321
|
+
if (!exactMatch && !caseMatch) {
|
|
322
|
+
const supported = [...new Set(builtinCmds.map((c) => c.command))].join(', ');
|
|
323
|
+
return mcpError('usage', 2, `"${command}" is not a supported command for ${cached.name} (${cached.type}).`, {
|
|
324
|
+
hint: `Supported commands: ${supported}`,
|
|
325
|
+
context: { validationKind: 'unknown-command', deviceType: cached.type, command },
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
else if (catalogMatch.readOnly) {
|
|
330
|
+
return mcpError('usage', 2, `${cached.name} (${cached.type}) is a read-only sensor — it has no control commands.`, {
|
|
331
|
+
hint: "Use 'get_device_status' to read this device instead.",
|
|
332
|
+
context: { validationKind: 'read-only-device', deviceType: cached.type, command },
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
}
|
|
314
336
|
}
|
|
315
337
|
const wouldSend = {
|
|
316
338
|
deviceId,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@switchbot/openapi-cli",
|
|
3
|
-
"version": "2.6.
|
|
3
|
+
"version": "2.6.3",
|
|
4
4
|
"description": "SwitchBot smart home CLI — control devices, run scenes, stream real-time events, and integrate AI agents via MCP. Full API v1.1 coverage.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"switchbot",
|