release: 2.4.0 — agent-experience overhaul + device history#16
Merged
chenliuyun merged 2 commits intomainfrom Apr 20, 2026
Merged
release: 2.4.0 — agent-experience overhaul + device history#16chenliuyun merged 2 commits intomainfrom
chenliuyun merged 2 commits intomainfrom
Conversation
added 2 commits
April 20, 2026 12:19
Bundles 19 OpenClaw/Claude feedback items (P0-P3) plus a new device-history
subsystem into a single minor release. All schema changes are additive; no
existing fields were removed or renamed.
Highlights:
- P0: IR verification flag on device commands; set-token argv scrubbing
- P1: --name subcommand scope, fuzzy name resolution w/ ambiguity contract,
compact schema/capabilities, leaf-level agent safety metadata
- D : JSONL device-history storage + rotation, history range/stats,
MCP query_device_history tool
- P2: stable doctor --json contract, events mqtt-tail control events,
batch stagger/concurrency, idempotency replayed + conflict contract,
profile label/daily-cap, verbose header redaction + --trace-unsafe
- P3: quota show alias, tree-wide did-you-mean, schema cliAddedFields,
agent-bootstrap aggregate command, --table-style, audit-log versioning
+ docs/audit-log.md + history verify
832/832 tests pass.
- ci.yml: new `offline-smoke` job seeds a fixture cache and asserts `agent-bootstrap --compact` < 20 KB and `schema export --compact --used` < 15 KB on every push/PR. Runs only after the test matrix passes. - smoke.yml: new workflow_dispatch-only job covering the three manual test-plan items that need a real account — IR verification flag, idempotency replay + conflict, and history range end-to-end. Reads SWITCHBOT_TOKEN/SWITCHBOT_SECRET from repo secrets; physical and IR device IDs are workflow inputs so operators pick which hardware to touch. Each destructive step is individually gated by its input.
chenliuyun
pushed a commit
that referenced
this pull request
Apr 20, 2026
C1 (#14): update --idempotency-key / --idempotency-key-prefix help text in devices.ts and batch.ts to mention process-local scope, per-process cache semantics, and that independent CLI invocations do not share cache. C2 (#15): mcp --help "eight tools" → "eleven tools"; list all 11 by name including get_device_history, query_device_history, aggregate_device_history. C3 (#17): add `scenes describe <sceneId>` subcommand. Returns sceneId, sceneName, stepCount:null, and a note explaining v1.1 API limitation. Exits 2 with scene_not_found + candidate list on unknown sceneId. Adds 'scenes describe' to COMMAND_META in capabilities.ts. Adds 2 tests (known + unknown scene). C4 (#13): add JSDoc comment on hints field in agent-bootstrap.ts clarifying empty array semantics. Add 'hints' field to cliAddedFields in schema.ts. C5 (#16): create docs/verbose-redaction.md documenting masked headers (authorization, token, sign, nonce, x-api-key, cookie, set-cookie, x-auth-token, t) and the --trace-unsafe opt-out flag. C6 (#18): plan schema output now includes agentNotes.deviceNameStrategy documenting that deviceName uses require-unique resolution and plans should pin deviceId for determinism. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
chenliuyun
pushed a commit
that referenced
this pull request
Apr 20, 2026
Document every fix landed in this branch beyond the history-aggregate feature: bugs #1, #4, #5, #6, #8, #9, #10, #11, #12, #13, #14, #15, #16, #17, #18 from the OpenClaw v2.4.0 smoke-test report. Call out the deferred items (#2, #7) explicitly so readers don't assume they were overlooked. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
4 tasks
chenliuyun
pushed a commit
that referenced
this pull request
Apr 20, 2026
C1 (#14): update --idempotency-key / --idempotency-key-prefix help text in devices.ts and batch.ts to mention process-local scope, per-process cache semantics, and that independent CLI invocations do not share cache. C2 (#15): mcp --help "eight tools" → "eleven tools"; list all 11 by name including get_device_history, query_device_history, aggregate_device_history. C3 (#17): add `scenes describe <sceneId>` subcommand. Returns sceneId, sceneName, stepCount:null, and a note explaining v1.1 API limitation. Exits 2 with scene_not_found + candidate list on unknown sceneId. Adds 'scenes describe' to COMMAND_META in capabilities.ts. Adds 2 tests (known + unknown scene). C4 (#13): add JSDoc comment on hints field in agent-bootstrap.ts clarifying empty array semantics. Add 'hints' field to cliAddedFields in schema.ts. C5 (#16): create docs/verbose-redaction.md documenting masked headers (authorization, token, sign, nonce, x-api-key, cookie, set-cookie, x-auth-token, t) and the --trace-unsafe opt-out flag. C6 (#18): plan schema output now includes agentNotes.deviceNameStrategy documenting that deviceName uses require-unique resolution and plans should pin deviceId for determinism.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Consolidates 19 OpenClaw/Claude integration feedback items (P0-P3) plus a new device-history subsystem into a single minor release. All schema changes are additive-only; no fields were removed or renamed, so existing CLI and MCP integrations keep working unchanged.
P0 — Correctness & security
devices commandresponses carryverification: { verifiable: false, reason, suggestedFollowup }; MCPsend_commandmirrors the field.config set-tokenpositional form scrubs token/secret fromprocess.argvbefore any hook, audit log, or verbose trace can observe them. Interactive hidden-echo mode is now the primary path.P1 — Agent hardening
devices status/devices commandaccept--namedirectly on the subcommand.src/devices/resolve-name.tswith six strategies (exact | prefix | substring | fuzzy | first | require-unique). Reads default tofuzzy; writes default torequire-uniqueand fail with exit 2 +ambiguous_name_match+ candidate list.schema export/capabilitiesgained--compact,--types,--used,--fields,--surface. Banners/tips go to stderr; stdout is exactly one JSON document.capabilitiescarries{ mutating, consumesQuota, idempotencySupported, agentSafetyTier, verifiability, typicalLatencyMs }.D — Device history (new subsystem)
~/.switchbot/device-history/<id>.jsonlwith 50 MB rotation (.jsonl.1 → .2 → .3). Writes best-effort,0o600.history range <deviceId>with--since,--from,--to,--field,--limit(streamingreadline, safe on 50 MB files).history stats <deviceId>reports file count, bytes, record count, earliest/latest timestamp.query_device_historytool mirrors the CLI with a 1000-record default cap.P2 — DX & stability
doctor --jsonshape ({ ok, generatedAt, checks[], summary });clockcheck probes the API and reportsskewMs.events mqtt-tailsynthesizes__connect/__reconnect/__disconnect/__heartbeatcontrol events; every record carries a UUIDv4eventId.devices batch --stagger/--max-concurrent/--planwith per-step telemetry.replayed: true; conflicting-shape reuse within 60 s exits 2 withidempotency_conflict. Keys are SHA-256 hashed on disk.--label,--description,--daily-cap,--default-flags; pre-flight quota refusal.--verbosemid-masks sensitive headers;--trace-unsafeopts into raw output.P3 — Polish
quota showalias; tree-wideshowSuggestionAfterError;schema exportdeclarescliAddedFields;agent-bootstrap --compactaggregate (< 20 KB);--table-style unicode|ascii|simple|markdown; audit-logauditVersion: 1+docs/audit-log.md+history verify.Test plan
npm test— 832/832 pass locallynpm run build— clean compileswitchbot agent-bootstrap --compact | wc -c< 20 KB on a real accountswitchbot devices command <ir-id> turnOn --json | jq -e '.verification.verifiable == false'switchbot schema export --compact --used | wc -c< 15 KB--nameon a write command → exit 2 +ambiguous_name_matchidempotency_conflictswitchbot history range <id> --since 5mafter lettingevents mqtt-tailcollect data