feat: UX improvements and sink system (v2.2.0)#12
Merged
chenliuyun merged 2 commits intomainfrom Apr 19, 2026
Merged
Conversation
added 2 commits
April 19, 2026 20:51
- Use random instanceId per session so each CLI run gets its own clientId, preventing conflicts with the SwitchBot cloud service that shares the same account credentials and causes an immediate session-kicking loop - Remove stale listeners from old mqtt.js client before replacing it in connect(), preventing the old client's close event from triggering a spurious extra reconnect cycle - Add onStateChange logging in events mqtt-tail so connection state transitions (connected/reconnecting/failed) are visible on stderr - Add onStateChange to test mock to avoid unsubState() TypeError
Sink system:
- Add src/sinks/ — stdout, file, webhook, openclaw, telegram, homeassistant
- Add DeviceHistoryStore (src/mcp/device-history.ts) and get_device_history MCP tool
- Add --sink, --sink-file, --webhook-url, --openclaw-*, --telegram-*, --ha-* to events mqtt-tail
CLI UX fixes (P0/P1/P2):
- BUG-1: --audit-log now boolean; add --audit-log-path for explicit path
- BUG-2/3: devices command outer try/catch; --name positional shift fix
- BUG-7/P1-04: case-insensitive command name suggestion ("Did you mean getStatus?")
- P0-05: field aliases in devices list (type, room, hub, cloud short names)
- P0-06/07: capabilities --minimal flag; explicit help entry in manifest
- P0-08: --timeout minimum 100ms with warning
- P0-09: --filter expr for devices list (type, name, category, room)
- P1-02: missing-parameter validation for commands requiring a param
- P1-03: IR command shows "→ IR signal sent" (not fake ✓)
- P1-05: scenes list --fields accepts id/name aliases
- P1-06: devices status --ids for batch status
- P1-08: --yes warning when passed to non-destructive commands
- P1-11: devices list --json returns { ok: true, deviceList, infraredRemoteList }
- P1-13: devices status --ids now supports --fields and --format jsonl
- P1-14: plan validate warns when plan has 0 steps
- P1-15: --name added to devices expand and devices watch
- P1-16: devices status --json includes _fetchedAt timestamp
- P2: devices list --json now respects --filter
- P2: devices types table includes role column
- P2: devices commands output shows example params when available
Tests: 697 passing (added 5 new tests for --filter JSON, expand --name, watch no-args)
chenliuyun
pushed a commit
that referenced
this pull request
Apr 20, 2026
Add --no-color as a root-level option to suppress ANSI colors in output. Also respect the NO_COLOR environment variable per https://no-color.org/. Early initialization sets chalk.level=0 when either flag or env is set, ensuring colors are disabled globally before any commands execute. 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
Add --no-color as a root-level option to suppress ANSI colors in output. Also respect the NO_COLOR environment variable per https://no-color.org/. Early initialization sets chalk.level=0 when either flag or env is set, ensuring colors are disabled globally before any commands execute.
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
events mqtt-tailoutput routing — stdout, file, webhook, OpenClaw, Telegram, Home Assistantget_device_historytool: New 9th MCP tool backed byDeviceHistoryStore(persists shadow snapshots per device)Changes
Sink system (
src/sinks/)types.ts,format.ts,dispatcher.ts— shared infrastructurestdout.ts,file.ts,webhook.ts,openclaw.ts,telegram.ts,homeassistant.ts— individual sinksevents mqtt-tailgains--sink,--sink-file,--webhook-url,--openclaw-*,--telegram-*,--ha-*flagsMCP
src/mcp/device-history.ts— DeviceHistoryStore persists shadow snapshots to~/.switchbot/device-history/src/commands/mcp.ts—get_device_historytool (9th tool)UX fixes
--audit-logis now a boolean flag; add separate--audit-log-pathdevices commandouter try/catch +--namepositional shift fixgetStatus?")devices list(type,room,hub,cloud)capabilities --minimalflag--timeoutminimum 100 ms with warning--filterfordevices list(type, name, category, room)scenes list --fieldsacceptsid/namealiasesdevices status --idsfor batch status--yeswarns when used on non-destructive commandsdevices list --jsonreturns{ ok: true, deviceList, infraredRemoteList }devices status --idssupports--fieldsand--format jsonlplan validatewarns when plan has 0 steps--nameadded todevices expandanddevices watchdevices status --jsonincludes_fetchedAttimestampdevices list --jsonnow respects--filterdevices typestable includesrolecolumndevices commandsshows example params when availableTest plan
npm run build && npm test— 697 tests passingswitchbot devices list --filter category=physical --json— verifies filter in JSON modeswitchbot devices status --ids <id1>,<id2> --fields power,battery— verifies batch fieldsswitchbot devices expand --name "device-name" setAll --temp 26 --mode cool --fan low --power onswitchbot devices watch --name "device-name" --max 1switchbot events mqtt-tail --sink file --sink-file /tmp/events.jsonl --max 1switchbot capabilities --json | jq '.data.mcpTools | length'— should be 9