@switchbot/openapi-cli 3.3.3 โ†’ 3.4.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
@@ -93,7 +93,7 @@ Under the hood every surface shares the same catalog, cache, and HMAC client โ€”
93
93
  - ๐ŸŽจ **Dual output modes** โ€” colorized tables by default; `--json` passthrough for `jq` and scripting
94
94
  - ๐Ÿ” **Secure credentials** โ€” HMAC-SHA256 signed requests; config file written with `0600`; env-var override for CI
95
95
  - ๐Ÿ” **Dry-run mode** โ€” preview every mutating request before it hits the API
96
- - ๐Ÿงช **Fully tested** โ€” 1959 Vitest tests, mocked axios, zero network in CI
96
+ - ๐Ÿงช **Fully tested** โ€” 2204 Vitest tests, mocked axios, zero network in CI
97
97
  - โšก **Shell completion** โ€” Bash / Zsh / Fish / PowerShell
98
98
 
99
99
  ## Requirements
@@ -273,9 +273,9 @@ Five annotated starter files covering common setups live in
273
273
  With a policy.yaml (v0.2) you can declare automations that the CLI
274
274
  executes for you. Supported triggers: **MQTT** (device events),
275
275
  **cron** (schedule-driven), and **webhook** (local HTTP POST).
276
- Supported conditions: `time_between` (quiet hours) and `device_state`
277
- (live API check with per-tick dedup). Every fire is recorded in
278
- `~/.switchbot/audit.log`. `rules run` is long-running; use
276
+ Supported conditions: `time_between` (quiet hours), `device_state`
277
+ (live API check with per-tick dedup), and `llm` (AI decision โ€” see
278
+ below). Every fire is recorded in `~/.switchbot/audit.log`. `rules run` is long-running; use
279
279
  `daemon start` / `daemon reload` for the managed background mode.
280
280
 
281
281
  **Actions** โ€” each rule's `then` array accepts two action types:
@@ -296,6 +296,35 @@ then:
296
296
  template: '{"rule":"{{ rule.name }}","fired":"{{ rule.fired_at }}"}'
297
297
  ```
298
298
 
299
+ **LLM condition** โ€” add an AI judgement step before actions fire. The engine calls the
300
+ configured LLM provider, passes the prompt plus recent event context, and gates execution
301
+ on the model's yes/no answer:
302
+
303
+ ```yaml
304
+ conditions:
305
+ - llm:
306
+ prompt: "Is the temperature above normal comfort range?"
307
+ provider: auto # auto | openai | anthropic
308
+ cache_ttl: 5m # skip redundant calls for identical context
309
+ budget:
310
+ max_calls_per_hour: 20
311
+ on_error: pass # fail | pass | skip
312
+ ```
313
+
314
+ Set `OPENAI_API_KEY` or `ANTHROPIC_API_KEY` (provider `auto` tries Anthropic first).
315
+ `rules lint` flags misconfigured LLM conditions (no provider key, cache TTL too high for
316
+ the trigger frequency, budget zero). Evaluation decisions are recorded in the trace log.
317
+
318
+ **Decision trace** โ€” enable `automation.audit.evaluate_trace` in `policy.yaml` to record
319
+ every evaluation decision (why a rule fired or was blocked):
320
+
321
+ ```yaml
322
+ automation:
323
+ audit:
324
+ evaluate_trace: sampled # full | sampled | off (default: sampled)
325
+ evaluate_retention_days: 7
326
+ ```
327
+
299
328
  ```bash
300
329
  # 1. Author rules under `automation.rules`. See examples/policies/automation.yaml
301
330
  # for a walkthrough covering the three trigger sources.
@@ -333,6 +362,16 @@ switchbot rules suggest --intent "if door opens and temp below 20 turn on heater
333
362
  --llm auto # routes complex intents to LLM automatically
334
363
  switchbot rules suggest --intent "..." --llm openai # explicit backend
335
364
  # Set OPENAI_API_KEY or ANTHROPIC_API_KEY; auto mode falls back to heuristic on failure
365
+
366
+ # 9. Explain why a specific evaluation fired or was blocked (requires evaluate_trace).
367
+ switchbot rules trace-explain --rule "motion on" --last
368
+ switchbot rules trace-explain --rule "motion on" --since 1h --json
369
+ switchbot rules trace-explain <fireId> # single evaluation by ID
370
+
371
+ # 10. Simulate a rule against historical events without running the engine.
372
+ switchbot rules simulate "motion on" # replay last 24h from audit log
373
+ switchbot rules simulate "motion on" --since 7d --json
374
+ switchbot rules simulate policy.yaml --rule "night AC" --against events.jsonl
336
375
  ```
337
376
 
338
377
  `rules suggest` enforces several guardrails on LLM output so a model can't quietly arm
@@ -881,12 +920,16 @@ Exposes MCP tools (`list_devices`, `describe_device`, `get_device_status`,
881
920
  `send_command`, `list_scenes`, `run_scene`, `search_catalog`,
882
921
  `account_overview`, `plan_suggest`, `plan_run`, `audit_query`,
883
922
  `audit_stats`, `policy_diff`, `policy_validate`, `policy_new`,
884
- `policy_migrate`, `rules_suggest`, `rule_notifications`) plus a
923
+ `policy_migrate`, `rules_suggest`, `rule_notifications`,
924
+ `rules_explain`, `rules_simulate`) plus a
885
925
  `switchbot://events` resource for real-time shadow updates.
886
926
  `rules_suggest` accepts an optional `llm` parameter (`openai | anthropic | auto`)
887
927
  to generate YAML for complex intents via an LLM backend.
888
928
  `rule_notifications` returns `rule-notify` audit entries, filterable by rule
889
929
  name, time range, channel, and result.
930
+ `rules_explain` returns the decision trace for a specific evaluation (why a rule
931
+ fired or was blocked); `rules_simulate` replays historical events against a rule
932
+ and reports would-fire / blocked / throttled outcomes.
890
933
  See [`docs/agent-guide.md`](./docs/agent-guide.md) for the full tool reference and safety rules (destructive-command guard).
891
934
 
892
935
  ### `doctor` โ€” self-check
@@ -1166,7 +1209,7 @@ npm install
1166
1209
 
1167
1210
  npm run dev -- <args> # Run from TypeScript sources via tsx
1168
1211
  npm run build # Compile to dist/
1169
- npm test # Run the Vitest suite (1959 tests)
1212
+ npm test # Run the Vitest suite (2204 tests)
1170
1213
  npm run test:watch # Watch mode
1171
1214
  npm run test:coverage # Coverage report (v8, HTML + text)
1172
1215
  ```
@@ -1232,7 +1275,8 @@ src/
1232
1275
  โ”‚ โ”œโ”€โ”€ install.ts # `switchbot install` / `uninstall`
1233
1276
  โ”‚ โ”œโ”€โ”€ policy.ts # `policy validate/new/migrate/diff/add-rule/backup/restore`
1234
1277
  โ”‚ โ”œโ”€โ”€ rules.ts # `rules suggest/lint/list/explain/run/reload/tail/replay/
1235
- โ”‚ โ”‚ # conflicts/doctor/summary/last-fired/webhook-*`
1278
+ โ”‚ โ”‚ # conflicts/doctor/summary/last-fired/webhook-*/
1279
+ โ”‚ โ”‚ # trace-explain/simulate`
1236
1280
  โ”‚ โ”œโ”€โ”€ scenes.ts
1237
1281
  โ”‚ โ”œโ”€โ”€ health.ts # `health check/serve` โ€” report + HTTP endpoints
1238
1282
  โ”‚ โ”œโ”€โ”€ upgrade-check.ts # `upgrade-check` โ€” npm registry version check
@@ -1256,7 +1300,7 @@ src/
1256
1300
  โ”œโ”€โ”€ format.ts # renderRows / filterFields / output-format dispatch
1257
1301
  โ”œโ”€โ”€ audit.ts # JSONL audit log writer
1258
1302
  โ””โ”€โ”€ quota.ts # Local daily-quota counter
1259
- tests/ # Vitest suite (1959 tests, mocked axios, no network)
1303
+ tests/ # Vitest suite (2204 tests, mocked axios, no network)
1260
1304
  ```
1261
1305
 
1262
1306
  ### Release flow