Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
c6071df
docs: add device-history-aggregation design spec
Apr 20, 2026
3774305
docs: add device-history-aggregation implementation plan
Apr 20, 2026
e461e80
refactor(history-query): export resolveRange for reuse in aggregation
Apr 20, 2026
d738e55
feat(history-agg): add module skeleton with public types
Apr 20, 2026
b4abed2
feat(history-agg): fold samples into a single bucket (count/min/max/a…
Apr 20, 2026
aee2f52
refactor(history-agg): avoid redundant resolveRange call in finalize
Apr 20, 2026
a94e13d
feat(history-agg): bucket samples by UTC-aligned --bucket duration
Apr 20, 2026
8bbe114
feat(history-agg): compute p50/p95 with nearest-rank and sample cap
Apr 20, 2026
e823509
feat(history-agg): mtime-prune rotated files, handle non-numeric + un…
Apr 20, 2026
cd9629c
fix(history-agg): make mtime-prune test genuinely depend on mtime
Apr 20, 2026
6ddaa8e
feat(history): add 'aggregate' subcommand wired to aggregateDeviceHis…
Apr 20, 2026
9ccc066
feat(mcp): add aggregate_device_history tool with _meta.agentSafetyTier
Apr 20, 2026
ba82ec7
feat(capabilities): advertise history aggregate + aggregate_device_hi…
Apr 20, 2026
15748df
chore(release): 2.5.0 — history aggregate + aggregate_device_history
Apr 20, 2026
618e506
fix(mcp): strict schemas + dryRun support on mutating tools (security…
Apr 20, 2026
0d3d268
fix(mcp): wire serverInfo.version to package.json (bug #5)
Apr 20, 2026
c8dc457
fix(mcp): expose _meta.agentSafetyTier on every tool (bug #6)
Apr 20, 2026
b636ed6
fix(name-resolver): require-unique must not short-circuit on exact ma…
Apr 20, 2026
49fa5e3
fix(cache): add 'status' alias for 'show' parity with quota (bug #9)
Apr 20, 2026
d94fac7
feat(format): accept --format markdown as alias for table+markdown st…
Apr 20, 2026
99f9158
fix(history): 'verify' exits 0 with warn when audit.log missing (bug …
Apr 20, 2026
2c27227
feat(cli): --no-color flag + NO_COLOR env support (bug #12)
Apr 20, 2026
9a602ae
feat(history): bucket mqtt control events into __control.jsonl (bug #10)
Apr 20, 2026
f04af54
docs(2.5.0): polish items C1-C6 (bugs #13,#14,#15,#17,#18)
Apr 20, 2026
90f07be
docs(changelog): describe 2.5.0 bug fixes from v2.4.0 report
Apr 20, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 98 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,104 @@ All notable changes to `@switchbot/openapi-cli` are documented in this file.
The format is loosely based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
This project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [2.5.0] - 2026-04-20

### Added

- **`history aggregate <deviceId>`** — on-demand bucketed statistics
(`count / min / max / avg / sum / p50 / p95`) over the append-only JSONL
device history. Flags: `--since` / `--from` / `--to`, repeatable
`--metric`, `--agg <csv>`, `--bucket <dur>`,
`--max-bucket-samples <n>`. Non-numeric samples are skipped; empty
metrics are omitted from their bucket.
- **MCP `aggregate_device_history`** — same contract as the CLI, exposed
as a read-tier tool (`_meta.agentSafetyTier: "read"`) with a strict
Zod input schema (unknown keys reject with JSON-RPC `-32602`).
- **Capabilities manifest** — new `history aggregate` entry in
`COMMAND_META`; new `aggregate_device_history` entry in
`surfaces.mcp.tools`.
- **`scenes describe <sceneId>`** — returns `{sceneId, sceneName,
stepCount:null, note}`; SwitchBot API v1.1 does not expose scene
steps. Unknown sceneId returns structured `scene_not_found` with a
candidate list. (bug #17)
- **`--no-color` flag + `NO_COLOR` env var** — honors the standard
https://no-color.org/ contract; disables chalk colors globally before
any subcommand runs. (bug #12)
- **`--format markdown`** — accepted as an alias for `--format table`
with `--table-style markdown` forced at render time, independent of
the user's `--table-style` flag. (bug #8)
- **`cache status`** — alias for `cache show`, matching the `quota`
subcommand's status/show parity. (bug #9)

### Fixed (security & correctness — v2.4.0 report)

- **MCP strict input schemas on all 11 tools** — unknown keys now
reject with JSON-RPC `-32602`. Fixes the v2.4.0 hole where
`send_command {dryRun:true}` silently fired the command anyway —
particularly dangerous for Smart Lock / Garage. (bug #4)
- **MCP `dryRun` on mutating tools** — `send_command` and `run_scene`
accept `dryRun:true`; when set, no API call is made and the response
is `{ok:true, dryRun:true, wouldSend:{...}}`. (bug #4)
- **MCP `serverInfo.version`** — wired to `package.json#version`; was
hardcoded `"2.0.0"` despite the CLI reporting the real version
everywhere else. (bug #5)
- **MCP `_meta.agentSafetyTier`** — every tool now emits its tier
(`read` / `action` / `destructive`). Release notes already claimed
this but no tool was actually emitting it. (bug #6)
- **`--name` require-unique + exact-match** — exact-name short-circuit
in `name-resolver` was returning the exact hit even when substring
matches existed, defeating the write-path `require-unique` default.
Exact hits now enter the candidate list under `require-unique` and
go through the ambiguity check like any other match. (bug #1)
- **`history verify` on missing audit.log** — exits 0 with `status:"warn"`
and `fileMissing:true` rather than exit 1. Malformed/unversioned
content still exits 1 as before. (bug #11)
- **`events mqtt-tail` control events** — `__connect` / `__reconnect` /
`__disconnect` / `__heartbeat` now append to
`~/.switchbot/device-history/__control.jsonl` alongside per-device
files, honoring the v2.4.0 "every event is persisted" claim. (bug #10)

### Changed (docs)

- `--idempotency-key` help text on `devices command`, `devices batch`,
`plan run`, `history replay` now explicitly mentions the process-local
60s scope — independent CLI invocations do NOT share the cache. (bug #14)
- `mcp --help` now says "eleven tools" and lists all 11 names. (bug #15)
- New `docs/verbose-redaction.md` — documents the nine masked headers
(`authorization`, `token`, `sign`, `nonce`, `x-api-key`, `cookie`,
`set-cookie`, `x-auth-token`, `t`) and the `--trace-unsafe` opt-out. (bug #16)
- `plan schema` now includes `agentNotes.deviceNameStrategy` declaring
that plan steps using `deviceName` resolve with `require-unique`. (bug #18)
- `agent-bootstrap` `hints` field carries JSDoc + `schema export`
declares it in `cliAddedFields` — empty array means "no hints",
never null. (bug #13)

### Notes

- Storage format unchanged. Aggregation streams the existing JSONL
rotation files via `readline` — zero memory blow-up for large
windows, with a hard ceiling of `--max-bucket-samples` × 8 bytes per
`(bucket × metric)` for quantile computation.
- Quantiles use nearest-rank on sorted per-bucket samples; if the cap
is reached the result carries `partial: true` and a per-bucket
`notes[]` entry. `count / min / max / avg / sum` remain exact.
- All bug-fix items bundled into 2.5.0 rather than shipping a separate
2.4.1. Source of bug numbers: the v2.4.0 smoke-test report at
`D:/servicdata/openclaw/workspace/switchbot-cli-v2.4.0-report.md`.

### Not included (deferred)

- Cross-device aggregation (agents merge locally).
- Trend / rate-of-change helpers (derivable from bucket series).
- `--fill-empty` for missing buckets.
- Disk-persisted idempotency cache for cross-invocation replay
(report bug #2). Process-local is the documented 2.4.0 contract;
the `--help` text now states this plainly — no code change. Revisit
only if a concrete use case forces it.
- `capabilities --types` / `--fields` / `--used` (report bug #7).
`schema export` already offers these for the agent bootstrap path;
`capabilities --compact --surface <s>` covers the payload-size story.

## [2.4.0] - 2026-04-20

Large agent-experience overhaul driven by the OpenClaw + Claude integration
Expand Down
Loading
Loading