@switchbot/openapi-cli 3.2.1 → 3.2.2

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.
Files changed (332) hide show
  1. package/README.md +3 -1
  2. package/dist/index.js +57349 -170
  3. package/package.json +9 -5
  4. package/dist/api/client.d.ts +0 -31
  5. package/dist/api/client.js +0 -236
  6. package/dist/api/client.js.map +0 -1
  7. package/dist/auth.d.ts +0 -1
  8. package/dist/auth.js +0 -21
  9. package/dist/auth.js.map +0 -1
  10. package/dist/commands/agent-bootstrap.d.ts +0 -10
  11. package/dist/commands/agent-bootstrap.js +0 -200
  12. package/dist/commands/agent-bootstrap.js.map +0 -1
  13. package/dist/commands/auth.d.ts +0 -18
  14. package/dist/commands/auth.js +0 -355
  15. package/dist/commands/auth.js.map +0 -1
  16. package/dist/commands/batch.d.ts +0 -2
  17. package/dist/commands/batch.js +0 -414
  18. package/dist/commands/batch.js.map +0 -1
  19. package/dist/commands/cache.d.ts +0 -2
  20. package/dist/commands/cache.js +0 -127
  21. package/dist/commands/cache.js.map +0 -1
  22. package/dist/commands/capabilities.d.ts +0 -31
  23. package/dist/commands/capabilities.js +0 -383
  24. package/dist/commands/capabilities.js.map +0 -1
  25. package/dist/commands/catalog.d.ts +0 -2
  26. package/dist/commands/catalog.js +0 -360
  27. package/dist/commands/catalog.js.map +0 -1
  28. package/dist/commands/completion.d.ts +0 -2
  29. package/dist/commands/completion.js +0 -386
  30. package/dist/commands/completion.js.map +0 -1
  31. package/dist/commands/config.d.ts +0 -21
  32. package/dist/commands/config.js +0 -377
  33. package/dist/commands/config.js.map +0 -1
  34. package/dist/commands/daemon.d.ts +0 -2
  35. package/dist/commands/daemon.js +0 -411
  36. package/dist/commands/daemon.js.map +0 -1
  37. package/dist/commands/device-meta.d.ts +0 -2
  38. package/dist/commands/device-meta.js +0 -160
  39. package/dist/commands/device-meta.js.map +0 -1
  40. package/dist/commands/devices.d.ts +0 -2
  41. package/dist/commands/devices.js +0 -949
  42. package/dist/commands/devices.js.map +0 -1
  43. package/dist/commands/doctor.d.ts +0 -3
  44. package/dist/commands/doctor.js +0 -1016
  45. package/dist/commands/doctor.js.map +0 -1
  46. package/dist/commands/events.d.ts +0 -31
  47. package/dist/commands/events.js +0 -564
  48. package/dist/commands/events.js.map +0 -1
  49. package/dist/commands/expand.d.ts +0 -2
  50. package/dist/commands/expand.js +0 -131
  51. package/dist/commands/expand.js.map +0 -1
  52. package/dist/commands/explain.d.ts +0 -2
  53. package/dist/commands/explain.js +0 -140
  54. package/dist/commands/explain.js.map +0 -1
  55. package/dist/commands/health.d.ts +0 -8
  56. package/dist/commands/health.js +0 -114
  57. package/dist/commands/health.js.map +0 -1
  58. package/dist/commands/history.d.ts +0 -2
  59. package/dist/commands/history.js +0 -321
  60. package/dist/commands/history.js.map +0 -1
  61. package/dist/commands/identity.d.ts +0 -45
  62. package/dist/commands/identity.js +0 -60
  63. package/dist/commands/identity.js.map +0 -1
  64. package/dist/commands/install.d.ts +0 -20
  65. package/dist/commands/install.js +0 -247
  66. package/dist/commands/install.js.map +0 -1
  67. package/dist/commands/mcp.d.ts +0 -14
  68. package/dist/commands/mcp.js +0 -2018
  69. package/dist/commands/mcp.js.map +0 -1
  70. package/dist/commands/plan.d.ts +0 -51
  71. package/dist/commands/plan.js +0 -654
  72. package/dist/commands/plan.js.map +0 -1
  73. package/dist/commands/policy.d.ts +0 -24
  74. package/dist/commands/policy.js +0 -587
  75. package/dist/commands/policy.js.map +0 -1
  76. package/dist/commands/quota.d.ts +0 -2
  77. package/dist/commands/quota.js +0 -79
  78. package/dist/commands/quota.js.map +0 -1
  79. package/dist/commands/rules.d.ts +0 -2
  80. package/dist/commands/rules.js +0 -876
  81. package/dist/commands/rules.js.map +0 -1
  82. package/dist/commands/scenes.d.ts +0 -2
  83. package/dist/commands/scenes.js +0 -265
  84. package/dist/commands/scenes.js.map +0 -1
  85. package/dist/commands/schema.d.ts +0 -2
  86. package/dist/commands/schema.js +0 -185
  87. package/dist/commands/schema.js.map +0 -1
  88. package/dist/commands/status-sync.d.ts +0 -2
  89. package/dist/commands/status-sync.js +0 -132
  90. package/dist/commands/status-sync.js.map +0 -1
  91. package/dist/commands/uninstall.d.ts +0 -20
  92. package/dist/commands/uninstall.js +0 -238
  93. package/dist/commands/uninstall.js.map +0 -1
  94. package/dist/commands/upgrade-check.d.ts +0 -2
  95. package/dist/commands/upgrade-check.js +0 -107
  96. package/dist/commands/upgrade-check.js.map +0 -1
  97. package/dist/commands/watch.d.ts +0 -2
  98. package/dist/commands/watch.js +0 -195
  99. package/dist/commands/watch.js.map +0 -1
  100. package/dist/commands/webhook.d.ts +0 -2
  101. package/dist/commands/webhook.js +0 -183
  102. package/dist/commands/webhook.js.map +0 -1
  103. package/dist/config.d.ts +0 -57
  104. package/dist/config.js +0 -259
  105. package/dist/config.js.map +0 -1
  106. package/dist/credentials/backends/file.d.ts +0 -18
  107. package/dist/credentials/backends/file.js +0 -102
  108. package/dist/credentials/backends/file.js.map +0 -1
  109. package/dist/credentials/backends/linux.d.ts +0 -16
  110. package/dist/credentials/backends/linux.js +0 -130
  111. package/dist/credentials/backends/linux.js.map +0 -1
  112. package/dist/credentials/backends/macos.d.ts +0 -18
  113. package/dist/credentials/backends/macos.js +0 -130
  114. package/dist/credentials/backends/macos.js.map +0 -1
  115. package/dist/credentials/backends/windows.d.ts +0 -23
  116. package/dist/credentials/backends/windows.js +0 -216
  117. package/dist/credentials/backends/windows.js.map +0 -1
  118. package/dist/credentials/keychain.d.ts +0 -83
  119. package/dist/credentials/keychain.js +0 -89
  120. package/dist/credentials/keychain.js.map +0 -1
  121. package/dist/credentials/prime.d.ts +0 -32
  122. package/dist/credentials/prime.js +0 -53
  123. package/dist/credentials/prime.js.map +0 -1
  124. package/dist/devices/cache.d.ts +0 -79
  125. package/dist/devices/cache.js +0 -294
  126. package/dist/devices/cache.js.map +0 -1
  127. package/dist/devices/catalog.d.ts +0 -138
  128. package/dist/devices/catalog.js +0 -768
  129. package/dist/devices/catalog.js.map +0 -1
  130. package/dist/devices/device-meta.d.ts +0 -15
  131. package/dist/devices/device-meta.js +0 -57
  132. package/dist/devices/device-meta.js.map +0 -1
  133. package/dist/devices/history-agg.d.ts +0 -37
  134. package/dist/devices/history-agg.js +0 -139
  135. package/dist/devices/history-agg.js.map +0 -1
  136. package/dist/devices/history-query.d.ts +0 -45
  137. package/dist/devices/history-query.js +0 -182
  138. package/dist/devices/history-query.js.map +0 -1
  139. package/dist/devices/param-validator.d.ts +0 -40
  140. package/dist/devices/param-validator.js +0 -434
  141. package/dist/devices/param-validator.js.map +0 -1
  142. package/dist/devices/resources.d.ts +0 -74
  143. package/dist/devices/resources.js +0 -271
  144. package/dist/devices/resources.js.map +0 -1
  145. package/dist/index.d.ts +0 -1
  146. package/dist/index.js.map +0 -1
  147. package/dist/install/default-steps.d.ts +0 -66
  148. package/dist/install/default-steps.js +0 -258
  149. package/dist/install/default-steps.js.map +0 -1
  150. package/dist/install/preflight.d.ts +0 -60
  151. package/dist/install/preflight.js +0 -213
  152. package/dist/install/preflight.js.map +0 -1
  153. package/dist/install/steps.d.ts +0 -61
  154. package/dist/install/steps.js +0 -68
  155. package/dist/install/steps.js.map +0 -1
  156. package/dist/lib/command-keywords.d.ts +0 -5
  157. package/dist/lib/command-keywords.js +0 -18
  158. package/dist/lib/command-keywords.js.map +0 -1
  159. package/dist/lib/daemon-state.d.ts +0 -24
  160. package/dist/lib/daemon-state.js +0 -47
  161. package/dist/lib/daemon-state.js.map +0 -1
  162. package/dist/lib/destructive-mode.d.ts +0 -2
  163. package/dist/lib/destructive-mode.js +0 -13
  164. package/dist/lib/destructive-mode.js.map +0 -1
  165. package/dist/lib/devices.d.ts +0 -151
  166. package/dist/lib/devices.js +0 -383
  167. package/dist/lib/devices.js.map +0 -1
  168. package/dist/lib/idempotency.d.ts +0 -46
  169. package/dist/lib/idempotency.js +0 -107
  170. package/dist/lib/idempotency.js.map +0 -1
  171. package/dist/lib/plan-store.d.ts +0 -19
  172. package/dist/lib/plan-store.js +0 -69
  173. package/dist/lib/plan-store.js.map +0 -1
  174. package/dist/lib/request-context.d.ts +0 -7
  175. package/dist/lib/request-context.js +0 -13
  176. package/dist/lib/request-context.js.map +0 -1
  177. package/dist/lib/scenes.d.ts +0 -7
  178. package/dist/lib/scenes.js +0 -11
  179. package/dist/lib/scenes.js.map +0 -1
  180. package/dist/logger.d.ts +0 -4
  181. package/dist/logger.js +0 -17
  182. package/dist/logger.js.map +0 -1
  183. package/dist/mcp/device-history.d.ts +0 -36
  184. package/dist/mcp/device-history.js +0 -146
  185. package/dist/mcp/device-history.js.map +0 -1
  186. package/dist/mcp/events-subscription.d.ts +0 -45
  187. package/dist/mcp/events-subscription.js +0 -214
  188. package/dist/mcp/events-subscription.js.map +0 -1
  189. package/dist/mqtt/client.d.ts +0 -25
  190. package/dist/mqtt/client.js +0 -181
  191. package/dist/mqtt/client.js.map +0 -1
  192. package/dist/mqtt/credential.d.ts +0 -16
  193. package/dist/mqtt/credential.js +0 -31
  194. package/dist/mqtt/credential.js.map +0 -1
  195. package/dist/policy/add-rule.d.ts +0 -21
  196. package/dist/policy/add-rule.js +0 -125
  197. package/dist/policy/add-rule.js.map +0 -1
  198. package/dist/policy/diff.d.ts +0 -21
  199. package/dist/policy/diff.js +0 -92
  200. package/dist/policy/diff.js.map +0 -1
  201. package/dist/policy/format.d.ts +0 -6
  202. package/dist/policy/format.js +0 -58
  203. package/dist/policy/format.js.map +0 -1
  204. package/dist/policy/load.d.ts +0 -32
  205. package/dist/policy/load.js +0 -62
  206. package/dist/policy/load.js.map +0 -1
  207. package/dist/policy/migrate.d.ts +0 -21
  208. package/dist/policy/migrate.js +0 -68
  209. package/dist/policy/migrate.js.map +0 -1
  210. package/dist/policy/schema.d.ts +0 -5
  211. package/dist/policy/schema.js +0 -19
  212. package/dist/policy/schema.js.map +0 -1
  213. package/dist/policy/validate.d.ts +0 -19
  214. package/dist/policy/validate.js +0 -263
  215. package/dist/policy/validate.js.map +0 -1
  216. package/dist/rules/action.d.ts +0 -65
  217. package/dist/rules/action.js +0 -217
  218. package/dist/rules/action.js.map +0 -1
  219. package/dist/rules/audit-query.d.ts +0 -51
  220. package/dist/rules/audit-query.js +0 -90
  221. package/dist/rules/audit-query.js.map +0 -1
  222. package/dist/rules/conflict-analyzer.d.ts +0 -57
  223. package/dist/rules/conflict-analyzer.js +0 -215
  224. package/dist/rules/conflict-analyzer.js.map +0 -1
  225. package/dist/rules/cron-scheduler.d.ts +0 -62
  226. package/dist/rules/cron-scheduler.js +0 -187
  227. package/dist/rules/cron-scheduler.js.map +0 -1
  228. package/dist/rules/destructive.d.ts +0 -20
  229. package/dist/rules/destructive.js +0 -53
  230. package/dist/rules/destructive.js.map +0 -1
  231. package/dist/rules/engine.d.ts +0 -193
  232. package/dist/rules/engine.js +0 -758
  233. package/dist/rules/engine.js.map +0 -1
  234. package/dist/rules/matcher.d.ts +0 -56
  235. package/dist/rules/matcher.js +0 -231
  236. package/dist/rules/matcher.js.map +0 -1
  237. package/dist/rules/pid-file.d.ts +0 -43
  238. package/dist/rules/pid-file.js +0 -96
  239. package/dist/rules/pid-file.js.map +0 -1
  240. package/dist/rules/quiet-hours.d.ts +0 -26
  241. package/dist/rules/quiet-hours.js +0 -46
  242. package/dist/rules/quiet-hours.js.map +0 -1
  243. package/dist/rules/suggest.d.ts +0 -20
  244. package/dist/rules/suggest.js +0 -96
  245. package/dist/rules/suggest.js.map +0 -1
  246. package/dist/rules/throttle.d.ts +0 -61
  247. package/dist/rules/throttle.js +0 -117
  248. package/dist/rules/throttle.js.map +0 -1
  249. package/dist/rules/types.d.ts +0 -117
  250. package/dist/rules/types.js +0 -35
  251. package/dist/rules/types.js.map +0 -1
  252. package/dist/rules/webhook-listener.d.ts +0 -63
  253. package/dist/rules/webhook-listener.js +0 -224
  254. package/dist/rules/webhook-listener.js.map +0 -1
  255. package/dist/rules/webhook-token.d.ts +0 -50
  256. package/dist/rules/webhook-token.js +0 -91
  257. package/dist/rules/webhook-token.js.map +0 -1
  258. package/dist/schema/field-aliases.d.ts +0 -34
  259. package/dist/schema/field-aliases.js +0 -132
  260. package/dist/schema/field-aliases.js.map +0 -1
  261. package/dist/sinks/dispatcher.d.ts +0 -7
  262. package/dist/sinks/dispatcher.js +0 -13
  263. package/dist/sinks/dispatcher.js.map +0 -1
  264. package/dist/sinks/file.d.ts +0 -6
  265. package/dist/sinks/file.js +0 -20
  266. package/dist/sinks/file.js.map +0 -1
  267. package/dist/sinks/format.d.ts +0 -20
  268. package/dist/sinks/format.js +0 -57
  269. package/dist/sinks/format.js.map +0 -1
  270. package/dist/sinks/homeassistant.d.ts +0 -18
  271. package/dist/sinks/homeassistant.js +0 -45
  272. package/dist/sinks/homeassistant.js.map +0 -1
  273. package/dist/sinks/openclaw.d.ts +0 -13
  274. package/dist/sinks/openclaw.js +0 -34
  275. package/dist/sinks/openclaw.js.map +0 -1
  276. package/dist/sinks/stdout.d.ts +0 -4
  277. package/dist/sinks/stdout.js +0 -6
  278. package/dist/sinks/stdout.js.map +0 -1
  279. package/dist/sinks/telegram.d.ts +0 -11
  280. package/dist/sinks/telegram.js +0 -29
  281. package/dist/sinks/telegram.js.map +0 -1
  282. package/dist/sinks/types.d.ts +0 -13
  283. package/dist/sinks/types.js +0 -2
  284. package/dist/sinks/types.js.map +0 -1
  285. package/dist/sinks/webhook.d.ts +0 -6
  286. package/dist/sinks/webhook.js +0 -23
  287. package/dist/sinks/webhook.js.map +0 -1
  288. package/dist/status-sync/manager.d.ts +0 -48
  289. package/dist/status-sync/manager.js +0 -269
  290. package/dist/status-sync/manager.js.map +0 -1
  291. package/dist/utils/arg-parsers.d.ts +0 -16
  292. package/dist/utils/arg-parsers.js +0 -67
  293. package/dist/utils/arg-parsers.js.map +0 -1
  294. package/dist/utils/audit.d.ts +0 -69
  295. package/dist/utils/audit.js +0 -122
  296. package/dist/utils/audit.js.map +0 -1
  297. package/dist/utils/filter.d.ts +0 -81
  298. package/dist/utils/filter.js +0 -190
  299. package/dist/utils/filter.js.map +0 -1
  300. package/dist/utils/flags.d.ts +0 -72
  301. package/dist/utils/flags.js +0 -187
  302. package/dist/utils/flags.js.map +0 -1
  303. package/dist/utils/format.d.ts +0 -9
  304. package/dist/utils/format.js +0 -118
  305. package/dist/utils/format.js.map +0 -1
  306. package/dist/utils/health.d.ts +0 -48
  307. package/dist/utils/health.js +0 -102
  308. package/dist/utils/health.js.map +0 -1
  309. package/dist/utils/help-json.d.ts +0 -39
  310. package/dist/utils/help-json.js +0 -55
  311. package/dist/utils/help-json.js.map +0 -1
  312. package/dist/utils/name-resolver.d.ts +0 -26
  313. package/dist/utils/name-resolver.js +0 -138
  314. package/dist/utils/name-resolver.js.map +0 -1
  315. package/dist/utils/output.d.ts +0 -73
  316. package/dist/utils/output.js +0 -405
  317. package/dist/utils/output.js.map +0 -1
  318. package/dist/utils/quota.d.ts +0 -61
  319. package/dist/utils/quota.js +0 -228
  320. package/dist/utils/quota.js.map +0 -1
  321. package/dist/utils/redact.d.ts +0 -23
  322. package/dist/utils/redact.js +0 -69
  323. package/dist/utils/redact.js.map +0 -1
  324. package/dist/utils/retry.d.ts +0 -72
  325. package/dist/utils/retry.js +0 -141
  326. package/dist/utils/retry.js.map +0 -1
  327. package/dist/utils/string.d.ts +0 -2
  328. package/dist/utils/string.js +0 -23
  329. package/dist/utils/string.js.map +0 -1
  330. package/dist/version.d.ts +0 -2
  331. package/dist/version.js +0 -5
  332. package/dist/version.js.map +0 -1
@@ -1,414 +0,0 @@
1
- import { intArg, enumArg, stringArg } from '../utils/arg-parsers.js';
2
- import { printJson, isJsonMode, handleError, buildErrorPayload, UsageError, exitWithError } from '../utils/output.js';
3
- import { fetchDeviceList, executeCommand, isDestructiveCommand, buildHubLocationMap, } from '../lib/devices.js';
4
- import { createClient } from '../api/client.js';
5
- import { parseFilter, applyFilter, FilterSyntaxError } from '../utils/filter.js';
6
- import { isDryRun } from '../utils/flags.js';
7
- import { DryRunSignal } from '../api/client.js';
8
- import { getCachedTypeMap, getCachedDevice, loadStatusCache } from '../devices/cache.js';
9
- import { allowsDirectDestructiveExecution, destructiveExecutionHint } from '../lib/destructive-mode.js';
10
- const DEFAULT_CONCURRENCY = 5;
11
- const COMMAND_TYPES = ['command', 'customize'];
12
- /**
13
- * Run `task(x)` for every element with at most `concurrency` running at once.
14
- * `staggerMs`: when > 0, delay each task start by this fixed interval (replaces
15
- * the default 20-60ms jitter). Useful for rate-limited endpoints.
16
- */
17
- async function runPool(items, concurrency, staggerMs, task) {
18
- const results = new Array(items.length);
19
- let cursor = 0;
20
- const workers = [];
21
- const width = Math.max(1, Math.min(concurrency, items.length));
22
- for (let w = 0; w < width; w++) {
23
- workers.push((async () => {
24
- while (cursor < items.length) {
25
- const idx = cursor++;
26
- results[idx] = await task(items[idx]);
27
- // Fixed stagger wins over random jitter when set; else keep the
28
- // default polite spacing so we don't hammer the endpoint.
29
- const delay = staggerMs > 0 ? staggerMs : 20 + Math.random() * 40;
30
- await new Promise((r) => setTimeout(r, delay));
31
- }
32
- })());
33
- }
34
- await Promise.all(workers);
35
- return results;
36
- }
37
- async function resolveTargetIds(options, getClient) {
38
- const explicit = [];
39
- if (options.ids) {
40
- for (const id of options.ids.split(',').map((s) => s.trim()).filter(Boolean)) {
41
- explicit.push(id);
42
- }
43
- }
44
- if (options.readStdin) {
45
- const chunks = [];
46
- for await (const chunk of process.stdin)
47
- chunks.push(chunk);
48
- const raw = Buffer.concat(chunks).toString('utf-8');
49
- for (const line of raw.split(/\r?\n/)) {
50
- const id = line.trim();
51
- if (id)
52
- explicit.push(id);
53
- }
54
- }
55
- const hasFilter = Boolean(options.filter);
56
- if (explicit.length === 0 && !hasFilter) {
57
- throw new Error('No target devices supplied — provide --ids, --filter, or pass "-" to read deviceIds from stdin.');
58
- }
59
- const typeMap = getCachedTypeMap(explicit);
60
- let ids;
61
- if (hasFilter) {
62
- const body = await fetchDeviceList(getClient?.());
63
- const hubLoc = buildHubLocationMap(body.deviceList);
64
- for (const d of body.deviceList)
65
- if (d.deviceType)
66
- typeMap.set(d.deviceId, d.deviceType);
67
- for (const ir of body.infraredRemoteList)
68
- typeMap.set(ir.deviceId, ir.remoteType);
69
- const clauses = parseFilter(options.filter);
70
- const matched = applyFilter(clauses, body.deviceList, body.infraredRemoteList, hubLoc);
71
- const filteredIds = new Set(matched.map((m) => m.deviceId));
72
- ids =
73
- explicit.length > 0 ? explicit.filter((id) => filteredIds.has(id)) : [...filteredIds];
74
- }
75
- else {
76
- ids = explicit;
77
- const missingTypeInfo = ids.some((id) => !typeMap.has(id));
78
- if (missingTypeInfo) {
79
- const body = await fetchDeviceList(getClient?.());
80
- for (const d of body.deviceList)
81
- if (d.deviceType)
82
- typeMap.set(d.deviceId, d.deviceType);
83
- for (const ir of body.infraredRemoteList)
84
- typeMap.set(ir.deviceId, ir.remoteType);
85
- }
86
- }
87
- return { ids, typeMap };
88
- }
89
- export function registerBatchCommand(devices) {
90
- devices
91
- .command('batch')
92
- .description('Send the same command to many devices in one run (filter- or stdin-driven)')
93
- .argument('<command>', 'Command name, e.g. turnOn, turnOff, setBrightness')
94
- .argument('[parameter]', 'Command parameter (same rules as `devices command`; omit for no-arg)')
95
- .option('--filter <expr>', 'Target devices matching a filter, e.g. type=Bot,family=Home', stringArg('--filter'))
96
- .option('--ids <csv>', 'Explicit comma-separated list of deviceIds', stringArg('--ids'))
97
- .option('--concurrency <n>', 'Max parallel in-flight requests (default 5)', intArg('--concurrency', { min: 1 }), '5')
98
- .option('--max-concurrent <n>', 'Alias for --concurrency; takes priority when set', intArg('--max-concurrent', { min: 1 }))
99
- .option('--stagger <ms>', 'Fixed delay between task starts in ms (default 0 = random 20-60ms jitter)', intArg('--stagger', { min: 0 }), '0')
100
- .option('--plan', '[DEPRECATED, use --emit-plan] With --dry-run: emit a plan JSON document instead of executing anything')
101
- .option('--emit-plan', 'With --dry-run: emit a plan JSON document instead of executing anything')
102
- .option('--yes', 'Allow destructive commands only from an explicit dev profile')
103
- .option('--type <commandType>', '"command" (default) or "customize" for user-defined IR buttons', enumArg('--type', COMMAND_TYPES), 'command')
104
- .option('--stdin', 'Read deviceIds from stdin, one per line (same as trailing "-")')
105
- .option('--idempotency-key-prefix <prefix>', 'Client-supplied prefix for idempotency keys (key per device: <prefix>-<deviceId>). process-local 60s window; cache is per Node process (MCP session, batch run, plan run). Independent CLI invocations do not share cache.', stringArg('--idempotency-key-prefix'))
106
- .option('--idempotency-key <prefix>', 'Alias for --idempotency-key-prefix.', stringArg('--idempotency-key'))
107
- .option('--skip-offline', 'Skip devices whose cached status is offline (no API call; cache miss → send as usual).')
108
- .addHelpText('after', `
109
- Targets are resolved in this priority order:
110
- 1. --ids when present (explicit deviceIds)
111
- 2. stdin when --stdin / "-" (one deviceId per line)
112
- 3. --filter (matches the account's device list)
113
- You can combine explicit ids with --filter to intersect them.
114
-
115
- Filter grammar:
116
- key=value exact match
117
- key~=value case-insensitive substring match
118
- clauses are comma-separated AND
119
-
120
- Supported keys: type, family, room, category (category: physical | ir)
121
-
122
- Output:
123
- Human mode: one status line per device, summary at the end.
124
- --json: {succeeded[], failed[{deviceId,error}], summary:{total,ok,failed,skipped,durationMs,maxConcurrent,staggerMs}}
125
- Each step includes startedAt / finishedAt / durationMs / replayed (when cached).
126
-
127
- Concurrency & pacing:
128
- --max-concurrent <n> Upper bound on in-flight requests (alias for --concurrency).
129
- --stagger <ms> Fixed delay between task starts; default 0 uses random 20-60ms jitter.
130
-
131
- Planning:
132
- --dry-run --emit-plan Print the plan JSON without executing anything. Useful
133
- for agents that want to show the user what will run.
134
- (--plan is the deprecated alias, removed in v3.0.)
135
-
136
- Safety:
137
- Destructive commands (Smart Lock unlock, Garage Door Opener turnOn/turnOff,
138
- Keypad createKey/deleteKey) are blocked by default. Use the reviewed plan
139
- flow instead of direct execution.
140
- --dry-run intercepts every POST and reports the intended calls without
141
- hitting the API.
142
-
143
- Examples:
144
- $ switchbot devices batch turnOff --filter 'type~=Light,family=home'
145
- $ switchbot devices batch turnOn --ids ID1,ID2,ID3
146
- $ switchbot devices list --format=id --filter 'type=Bot' | switchbot devices batch toggle -
147
- $ switchbot devices batch unlock --filter 'type=Smart Lock' --dry-run --emit-plan
148
- `)
149
- .action(async (cmd, parameter, options, commandObj) => {
150
- // Trailing "-" sentinel selects stdin mode.
151
- const extra = commandObj.args ?? [];
152
- const readStdin = Boolean(options.stdin) || extra.includes('-');
153
- // P12: --plan is deprecated in favor of --emit-plan. Reject both
154
- // together (conflicting) and warn when only the old flag is used.
155
- if (options.plan && options.emitPlan) {
156
- handleError(new UsageError('Use --emit-plan; --plan is deprecated and cannot be combined with --emit-plan.'));
157
- return;
158
- }
159
- if (options.plan && !options.emitPlan) {
160
- // Warning goes to stderr so it cannot corrupt --json output on stdout.
161
- console.error('[WARN] --plan is deprecated; use --emit-plan. Will be removed in v3.0.');
162
- }
163
- const emitPlan = Boolean(options.emitPlan || options.plan);
164
- // Accept --idempotency-key as alias; reject when both forms are supplied.
165
- if (options.idempotencyKey !== undefined && options.idempotencyKeyPrefix !== undefined) {
166
- handleError(new UsageError('Use either --idempotency-key or --idempotency-key-prefix, not both.'));
167
- return;
168
- }
169
- if (options.idempotencyKey !== undefined && options.idempotencyKeyPrefix === undefined) {
170
- options.idempotencyKeyPrefix = options.idempotencyKey;
171
- }
172
- let client;
173
- const getClient = () => (client ??= createClient());
174
- let resolved;
175
- try {
176
- resolved = await resolveTargetIds({
177
- filter: options.filter,
178
- ids: options.ids,
179
- readStdin,
180
- }, getClient);
181
- }
182
- catch (error) {
183
- if (error instanceof FilterSyntaxError) {
184
- exitWithError(`Error: ${error.message}`);
185
- }
186
- if (error instanceof Error && error.message.startsWith('No target devices')) {
187
- exitWithError(`Error: ${error.message}`);
188
- }
189
- handleError(error);
190
- }
191
- if (resolved.ids.length === 0) {
192
- const out = {
193
- succeeded: [],
194
- failed: [],
195
- summary: { total: 0, ok: 0, failed: 0, skipped: 0, durationMs: 0, unverifiableCount: 0 },
196
- };
197
- if (isJsonMode())
198
- printJson(out);
199
- else
200
- console.log('No devices matched — nothing to do.');
201
- return;
202
- }
203
- const effectiveType = (options.type === 'customize' ? 'customize' : 'command');
204
- // --skip-offline: preflight using the status cache (no network). Cache
205
- // miss = send as usual; only definite "offline" cached entries skip.
206
- const preSkipped = [];
207
- if (options.skipOffline && resolved.ids.length > 0) {
208
- const statusCache = loadStatusCache();
209
- const kept = [];
210
- for (const id of resolved.ids) {
211
- const entry = statusCache.entries[id];
212
- const online = entry?.body?.onlineStatus;
213
- if (online === 'offline') {
214
- preSkipped.push({ deviceId: id, reason: 'offline' });
215
- }
216
- else {
217
- kept.push(id);
218
- }
219
- }
220
- resolved = { ...resolved, ids: kept };
221
- }
222
- // Pre-flight: identify destructive targets before spending API calls.
223
- const blockedForDestructive = [];
224
- for (const id of resolved.ids) {
225
- const t = resolved.typeMap.get(id);
226
- if (isDestructiveCommand(t, cmd, effectiveType) && !options.yes) {
227
- blockedForDestructive.push({
228
- deviceId: id,
229
- reason: `destructive command "${cmd}" on ${t ?? 'unknown'} requires --yes`,
230
- });
231
- }
232
- }
233
- if (blockedForDestructive.length > 0 && !options.yes) {
234
- const deviceIds = blockedForDestructive.map((b) => b.deviceId);
235
- exitWithError({
236
- code: 2,
237
- kind: 'guard',
238
- message: `Refusing to run destructive command "${cmd}" on ${blockedForDestructive.length} device(s) without --yes: ${deviceIds.join(', ')}`,
239
- hint: 'Re-issue the call with --yes only from an explicit dev profile, or use the reviewed plan flow.',
240
- context: { command: cmd, deviceIds },
241
- });
242
- }
243
- if (blockedForDestructive.length > 0 && options.yes && !allowsDirectDestructiveExecution()) {
244
- exitWithError({
245
- code: 2,
246
- kind: 'guard',
247
- message: `Direct destructive execution is disabled for batch command "${cmd}".`,
248
- hint: destructiveExecutionHint(),
249
- context: {
250
- command: cmd,
251
- blockedCount: blockedForDestructive.length,
252
- deviceIds: blockedForDestructive.map((item) => item.deviceId),
253
- requiredWorkflow: 'plan-approval',
254
- },
255
- });
256
- }
257
- // parameter may be a JSON object string; mirror the single-command action.
258
- let parsedParam = parameter ?? 'default';
259
- if (parameter) {
260
- try {
261
- parsedParam = JSON.parse(parameter);
262
- }
263
- catch {
264
- // keep as string
265
- }
266
- }
267
- const maxConcurrentRaw = options.maxConcurrent ?? options.concurrency;
268
- const concurrency = Math.max(1, Number.parseInt(maxConcurrentRaw, 10) || DEFAULT_CONCURRENCY);
269
- const staggerMs = Math.max(0, Number.parseInt(options.stagger, 10) || 0);
270
- const dryRun = isDryRun();
271
- // --dry-run --emit-plan (or legacy --plan): emit a plan document and return without executing.
272
- if (dryRun && emitPlan) {
273
- const steps = resolved.ids.map((id) => ({
274
- deviceId: id,
275
- command: cmd,
276
- parameter: parsedParam,
277
- type: effectiveType,
278
- idempotencyKey: options.idempotencyKeyPrefix
279
- ? `${options.idempotencyKeyPrefix}-${id}`
280
- : undefined,
281
- }));
282
- const planDoc = {
283
- schemaVersion: '1.1',
284
- dryRun: true,
285
- plan: {
286
- command: cmd,
287
- parameter: parsedParam,
288
- type: effectiveType,
289
- maxConcurrent: concurrency,
290
- staggerMs,
291
- stepCount: steps.length,
292
- steps,
293
- },
294
- };
295
- if (isJsonMode()) {
296
- printJson(planDoc);
297
- }
298
- else {
299
- console.log(`Plan: ${steps.length} step(s), command=${cmd}, maxConcurrent=${concurrency}, staggerMs=${staggerMs}`);
300
- for (const s of steps)
301
- console.log(` → ${s.deviceId} ${s.type} ${s.command}`);
302
- }
303
- return;
304
- }
305
- const startedAt = Date.now();
306
- const outcomes = await runPool(resolved.ids, concurrency, staggerMs, async (id) => {
307
- const stepStart = Date.now();
308
- const startedIso = new Date(stepStart).toISOString();
309
- try {
310
- const idempotencyKey = options.idempotencyKeyPrefix
311
- ? `${options.idempotencyKeyPrefix}-${id}`
312
- : undefined;
313
- const result = await executeCommand(id, cmd, parsedParam, effectiveType, getClient(), {
314
- idempotencyKey,
315
- });
316
- const finishedIso = new Date().toISOString();
317
- const durationMs = Date.now() - stepStart;
318
- const replayed = typeof result === 'object' && result !== null && result.replayed === true;
319
- if (!isJsonMode()) {
320
- console.log(`✓ ${id}: ${cmd}${replayed ? ' (replayed)' : ''}`);
321
- }
322
- return {
323
- ok: true,
324
- deviceId: id,
325
- result,
326
- startedAt: startedIso,
327
- finishedAt: finishedIso,
328
- durationMs,
329
- replayed,
330
- };
331
- }
332
- catch (err) {
333
- // --dry-run uses DryRunSignal to short-circuit; surface that as a
334
- // "skipped" outcome, not a failure.
335
- if (err instanceof DryRunSignal) {
336
- return {
337
- ok: 'dry-run',
338
- deviceId: id,
339
- startedAt: startedIso,
340
- finishedAt: new Date().toISOString(),
341
- durationMs: Date.now() - stepStart,
342
- };
343
- }
344
- const errorPayload = buildErrorPayload(err);
345
- if (!isJsonMode()) {
346
- console.error(`✗ ${id}: ${errorPayload.message}`);
347
- }
348
- return {
349
- ok: false,
350
- deviceId: id,
351
- error: errorPayload,
352
- startedAt: startedIso,
353
- finishedAt: new Date().toISOString(),
354
- durationMs: Date.now() - stepStart,
355
- };
356
- }
357
- });
358
- const succeeded = outcomes.filter((o) => o.ok === true);
359
- const failed = outcomes.filter((o) => o.ok === false);
360
- const dryRunned = outcomes.filter((o) => o.ok === 'dry-run');
361
- const result = {
362
- succeeded: succeeded.map((s) => {
363
- const isIr = getCachedDevice(s.deviceId)?.category === 'ir';
364
- const entry = {
365
- deviceId: s.deviceId,
366
- result: s.result,
367
- startedAt: s.startedAt,
368
- finishedAt: s.finishedAt,
369
- durationMs: s.durationMs,
370
- replayed: s.replayed,
371
- };
372
- if (isIr) {
373
- entry.subKind = 'ir-no-feedback';
374
- entry.verification = {
375
- verifiable: false,
376
- reason: 'IR transmission is unidirectional; no receipt acknowledgment is possible.',
377
- suggestedFollowup: 'Confirm visible change manually or via a paired state sensor.',
378
- };
379
- }
380
- return entry;
381
- }),
382
- failed: failed.map((f) => ({
383
- deviceId: f.deviceId,
384
- error: f.error,
385
- startedAt: f.startedAt,
386
- finishedAt: f.finishedAt,
387
- durationMs: f.durationMs,
388
- })),
389
- ...(preSkipped.length > 0 ? { skipped: preSkipped } : {}),
390
- summary: {
391
- total: resolved.ids.length + preSkipped.length,
392
- ok: succeeded.length,
393
- failed: failed.length,
394
- skipped: dryRunned.length + preSkipped.length,
395
- durationMs: Date.now() - startedAt,
396
- unverifiableCount: succeeded.filter((s) => getCachedDevice(s.deviceId)?.category === 'ir').length,
397
- schemaVersion: '1.1',
398
- maxConcurrent: concurrency,
399
- staggerMs,
400
- ...(dryRun ? { dryRun: true } : {}),
401
- },
402
- };
403
- if (isJsonMode()) {
404
- printJson(result);
405
- }
406
- else {
407
- console.log(`\nSummary: ${result.summary.ok} ok, ${result.summary.failed} failed, ${result.summary.skipped} skipped (${result.summary.durationMs}ms)`);
408
- }
409
- // Non-zero exit when anything failed so scripts can react.
410
- if (failed.length > 0)
411
- process.exit(1);
412
- });
413
- }
414
- //# sourceMappingURL=batch.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"batch.js","sourceRoot":"","sources":["../../src/commands/batch.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- import { Command } from 'commander';
2
- export declare function registerCacheCommand(program: Command): void;
@@ -1,127 +0,0 @@
1
- import { enumArg } from '../utils/arg-parsers.js';
2
- import { printJson, isJsonMode, handleError, UsageError } from '../utils/output.js';
3
- import { clearCache, clearStatusCache, describeCache, loadStatusCache, } from '../devices/cache.js';
4
- function formatAge(ms) {
5
- if (ms === undefined)
6
- return '—';
7
- if (ms < 1000)
8
- return `${ms}ms`;
9
- const s = Math.floor(ms / 1000);
10
- if (s < 60)
11
- return `${s}s`;
12
- const m = Math.floor(s / 60);
13
- if (m < 60)
14
- return `${m}m ${s % 60}s`;
15
- const h = Math.floor(m / 60);
16
- return `${h}h ${m % 60}m`;
17
- }
18
- export function registerCacheCommand(program) {
19
- const CACHE_KEYS = ['list', 'status', 'all'];
20
- const cache = program
21
- .command('cache')
22
- .description('Inspect and manage the local SwitchBot CLI caches')
23
- .addHelpText('after', `
24
- Two caches live at ~/.switchbot/:
25
- devices.json List of known deviceIds + metadata. Refreshed by every
26
- 'devices list' call. Drives command validation and
27
- helpful hints — keep around even if you don't use TTL.
28
- status.json Per-device status bodies keyed by deviceId. Only written
29
- when a status TTL is enabled (via --cache <duration>).
30
-
31
- Cache modes (global flag, apply to any read):
32
- --cache off | --no-cache disable cache reads
33
- --cache auto (default) list cache on (1h TTL), status cache off
34
- --cache 5m | --cache 1h enable both with the given TTL
35
-
36
- Subcommands:
37
- show Show ages, entry counts, and file locations
38
- clear Delete cache files (specify --key to scope)
39
-
40
- Examples:
41
- $ switchbot cache show
42
- $ switchbot --json cache show
43
- $ switchbot cache clear # removes devices.json + status.json
44
- $ switchbot cache clear --key status # removes only status.json
45
- $ switchbot cache clear --key list # removes only devices.json
46
- `);
47
- cache
48
- .command('show')
49
- .alias('status')
50
- .description('Summarize the cache files (paths, ages, entry counts)')
51
- .addHelpText('after', `
52
- Cache TTL is computed from the 'lastUpdated' field inside the JSON, not the file mtime.
53
- touch does not invalidate; use 'cache clear' to force a refresh.
54
- `)
55
- .action(() => {
56
- const summary = describeCache();
57
- if (isJsonMode()) {
58
- const statusCache = loadStatusCache();
59
- printJson({
60
- list: summary.list,
61
- status: {
62
- ...summary.status,
63
- entries: Object.fromEntries(Object.entries(statusCache.entries).map(([id, e]) => [id, { fetchedAt: e.fetchedAt }])),
64
- },
65
- });
66
- return;
67
- }
68
- console.log('Device list cache (devices.json):');
69
- console.log(` Path: ${summary.list.path}`);
70
- console.log(` Exists: ${summary.list.exists ? 'yes' : 'no'}`);
71
- if (summary.list.exists) {
72
- console.log(` Last update: ${summary.list.lastUpdated ?? '—'}`);
73
- console.log(` Age: ${formatAge(summary.list.ageMs)}`);
74
- console.log(` Devices: ${summary.list.deviceCount ?? 0}`);
75
- }
76
- console.log('\nStatus cache (status.json):');
77
- console.log(` Path: ${summary.status.path}`);
78
- console.log(` Exists: ${summary.status.exists ? 'yes' : 'no'}`);
79
- console.log(` Entries: ${summary.status.entryCount}`);
80
- if (summary.status.entryCount > 0) {
81
- console.log(` Oldest: ${summary.status.oldestFetchedAt ?? '—'}`);
82
- console.log(` Newest: ${summary.status.newestFetchedAt ?? '—'}`);
83
- }
84
- });
85
- cache
86
- .command('clear')
87
- .description('Delete cache files')
88
- .option('--key <which>', 'Which cache to clear: "list" | "status" | "all" (default)', enumArg('--key', CACHE_KEYS), 'all')
89
- .option('--status', 'Shorthand for --key status')
90
- .option('--list', 'Shorthand for --key list')
91
- .action((options) => {
92
- try {
93
- if (options.status && options.list) {
94
- throw new UsageError('--status and --list are mutually exclusive.');
95
- }
96
- if ((options.status || options.list) && options.key !== 'all') {
97
- throw new UsageError('--status / --list cannot be combined with --key.');
98
- }
99
- let key = options.key;
100
- if (options.status)
101
- key = 'status';
102
- if (options.list)
103
- key = 'list';
104
- if (!['list', 'status', 'all'].includes(key)) {
105
- throw new UsageError(`Unknown --key "${key}". Expected: list, status, all.`);
106
- }
107
- const cleared = [];
108
- if (key === 'list' || key === 'all') {
109
- clearCache();
110
- cleared.push('list');
111
- }
112
- if (key === 'status' || key === 'all') {
113
- clearStatusCache();
114
- cleared.push('status');
115
- }
116
- if (isJsonMode()) {
117
- printJson({ cleared });
118
- return;
119
- }
120
- console.log(`Cleared: ${cleared.join(', ')}`);
121
- }
122
- catch (error) {
123
- handleError(error);
124
- }
125
- });
126
- }
127
- //# sourceMappingURL=cache.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/commands/cache.ts"],"names":[],"mappings":"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"}
@@ -1,31 +0,0 @@
1
- import { Command } from 'commander';
2
- export type AgentSafetyTier = 'read' | 'action' | 'destructive';
3
- export type Verifiability = 'local' | 'deviceConfirmed' | 'deviceDependent' | 'none';
4
- export type RiskLevel = 'low' | 'medium' | 'high';
5
- export type IdempotencyHint = 'safe' | 'caution' | 'non-idempotent';
6
- export type RecommendedMode = 'direct' | 'plan' | 'review-before-execute';
7
- interface CommandMeta {
8
- mutating: boolean;
9
- consumesQuota: boolean;
10
- idempotencySupported: boolean;
11
- agentSafetyTier: AgentSafetyTier;
12
- verifiability: Verifiability;
13
- typicalLatencyMs: number;
14
- }
15
- export declare const COMMAND_META: Record<string, CommandMeta>;
16
- export interface CompactLeaf {
17
- name: string;
18
- mutating: boolean;
19
- consumesQuota: boolean;
20
- idempotencySupported: boolean;
21
- agentSafetyTier: AgentSafetyTier;
22
- verifiability: Verifiability;
23
- typicalLatencyMs: number;
24
- riskLevel: RiskLevel;
25
- requiresConfirmation: boolean;
26
- supportsDryRun: boolean;
27
- idempotencyHint: IdempotencyHint;
28
- recommendedMode: RecommendedMode;
29
- }
30
- export declare function registerCapabilitiesCommand(program: Command): void;
31
- export {};