@switchbot/openapi-cli 3.2.0 → 3.2.1

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 (331) hide show
  1. package/dist/api/client.d.ts +31 -0
  2. package/dist/api/client.js +236 -0
  3. package/dist/api/client.js.map +1 -0
  4. package/dist/auth.d.ts +1 -0
  5. package/dist/auth.js +21 -0
  6. package/dist/auth.js.map +1 -0
  7. package/dist/commands/agent-bootstrap.d.ts +10 -0
  8. package/dist/commands/agent-bootstrap.js +200 -0
  9. package/dist/commands/agent-bootstrap.js.map +1 -0
  10. package/dist/commands/auth.d.ts +18 -0
  11. package/dist/commands/auth.js +355 -0
  12. package/dist/commands/auth.js.map +1 -0
  13. package/dist/commands/batch.d.ts +2 -0
  14. package/dist/commands/batch.js +414 -0
  15. package/dist/commands/batch.js.map +1 -0
  16. package/dist/commands/cache.d.ts +2 -0
  17. package/dist/commands/cache.js +127 -0
  18. package/dist/commands/cache.js.map +1 -0
  19. package/dist/commands/capabilities.d.ts +31 -0
  20. package/dist/commands/capabilities.js +383 -0
  21. package/dist/commands/capabilities.js.map +1 -0
  22. package/dist/commands/catalog.d.ts +2 -0
  23. package/dist/commands/catalog.js +360 -0
  24. package/dist/commands/catalog.js.map +1 -0
  25. package/dist/commands/completion.d.ts +2 -0
  26. package/dist/commands/completion.js +386 -0
  27. package/dist/commands/completion.js.map +1 -0
  28. package/dist/commands/config.d.ts +21 -0
  29. package/dist/commands/config.js +377 -0
  30. package/dist/commands/config.js.map +1 -0
  31. package/dist/commands/daemon.d.ts +2 -0
  32. package/dist/commands/daemon.js +411 -0
  33. package/dist/commands/daemon.js.map +1 -0
  34. package/dist/commands/device-meta.d.ts +2 -0
  35. package/dist/commands/device-meta.js +160 -0
  36. package/dist/commands/device-meta.js.map +1 -0
  37. package/dist/commands/devices.d.ts +2 -0
  38. package/dist/commands/devices.js +949 -0
  39. package/dist/commands/devices.js.map +1 -0
  40. package/dist/commands/doctor.d.ts +3 -0
  41. package/dist/commands/doctor.js +1016 -0
  42. package/dist/commands/doctor.js.map +1 -0
  43. package/dist/commands/events.d.ts +31 -0
  44. package/dist/commands/events.js +564 -0
  45. package/dist/commands/events.js.map +1 -0
  46. package/dist/commands/expand.d.ts +2 -0
  47. package/dist/commands/expand.js +131 -0
  48. package/dist/commands/expand.js.map +1 -0
  49. package/dist/commands/explain.d.ts +2 -0
  50. package/dist/commands/explain.js +140 -0
  51. package/dist/commands/explain.js.map +1 -0
  52. package/dist/commands/health.d.ts +8 -0
  53. package/dist/commands/health.js +114 -0
  54. package/dist/commands/health.js.map +1 -0
  55. package/dist/commands/history.d.ts +2 -0
  56. package/dist/commands/history.js +321 -0
  57. package/dist/commands/history.js.map +1 -0
  58. package/dist/commands/identity.d.ts +45 -0
  59. package/dist/commands/identity.js +60 -0
  60. package/dist/commands/identity.js.map +1 -0
  61. package/dist/commands/install.d.ts +20 -0
  62. package/dist/commands/install.js +247 -0
  63. package/dist/commands/install.js.map +1 -0
  64. package/dist/commands/mcp.d.ts +14 -0
  65. package/dist/commands/mcp.js +2018 -0
  66. package/dist/commands/mcp.js.map +1 -0
  67. package/dist/commands/plan.d.ts +51 -0
  68. package/dist/commands/plan.js +654 -0
  69. package/dist/commands/plan.js.map +1 -0
  70. package/dist/commands/policy.d.ts +24 -0
  71. package/dist/commands/policy.js +587 -0
  72. package/dist/commands/policy.js.map +1 -0
  73. package/dist/commands/quota.d.ts +2 -0
  74. package/dist/commands/quota.js +79 -0
  75. package/dist/commands/quota.js.map +1 -0
  76. package/dist/commands/rules.d.ts +2 -0
  77. package/dist/commands/rules.js +876 -0
  78. package/dist/commands/rules.js.map +1 -0
  79. package/dist/commands/scenes.d.ts +2 -0
  80. package/dist/commands/scenes.js +265 -0
  81. package/dist/commands/scenes.js.map +1 -0
  82. package/dist/commands/schema.d.ts +2 -0
  83. package/dist/commands/schema.js +185 -0
  84. package/dist/commands/schema.js.map +1 -0
  85. package/dist/commands/status-sync.d.ts +2 -0
  86. package/dist/commands/status-sync.js +132 -0
  87. package/dist/commands/status-sync.js.map +1 -0
  88. package/dist/commands/uninstall.d.ts +20 -0
  89. package/dist/commands/uninstall.js +238 -0
  90. package/dist/commands/uninstall.js.map +1 -0
  91. package/dist/commands/upgrade-check.d.ts +2 -0
  92. package/dist/commands/upgrade-check.js +107 -0
  93. package/dist/commands/upgrade-check.js.map +1 -0
  94. package/dist/commands/watch.d.ts +2 -0
  95. package/dist/commands/watch.js +195 -0
  96. package/dist/commands/watch.js.map +1 -0
  97. package/dist/commands/webhook.d.ts +2 -0
  98. package/dist/commands/webhook.js +183 -0
  99. package/dist/commands/webhook.js.map +1 -0
  100. package/dist/config.d.ts +57 -0
  101. package/dist/config.js +259 -0
  102. package/dist/config.js.map +1 -0
  103. package/dist/credentials/backends/file.d.ts +18 -0
  104. package/dist/credentials/backends/file.js +102 -0
  105. package/dist/credentials/backends/file.js.map +1 -0
  106. package/dist/credentials/backends/linux.d.ts +16 -0
  107. package/dist/credentials/backends/linux.js +130 -0
  108. package/dist/credentials/backends/linux.js.map +1 -0
  109. package/dist/credentials/backends/macos.d.ts +18 -0
  110. package/dist/credentials/backends/macos.js +130 -0
  111. package/dist/credentials/backends/macos.js.map +1 -0
  112. package/dist/credentials/backends/windows.d.ts +23 -0
  113. package/dist/credentials/backends/windows.js +216 -0
  114. package/dist/credentials/backends/windows.js.map +1 -0
  115. package/dist/credentials/keychain.d.ts +83 -0
  116. package/dist/credentials/keychain.js +89 -0
  117. package/dist/credentials/keychain.js.map +1 -0
  118. package/dist/credentials/prime.d.ts +32 -0
  119. package/dist/credentials/prime.js +53 -0
  120. package/dist/credentials/prime.js.map +1 -0
  121. package/dist/devices/cache.d.ts +79 -0
  122. package/dist/devices/cache.js +294 -0
  123. package/dist/devices/cache.js.map +1 -0
  124. package/dist/devices/catalog.d.ts +138 -0
  125. package/dist/devices/catalog.js +768 -0
  126. package/dist/devices/catalog.js.map +1 -0
  127. package/dist/devices/device-meta.d.ts +15 -0
  128. package/dist/devices/device-meta.js +57 -0
  129. package/dist/devices/device-meta.js.map +1 -0
  130. package/dist/devices/history-agg.d.ts +37 -0
  131. package/dist/devices/history-agg.js +139 -0
  132. package/dist/devices/history-agg.js.map +1 -0
  133. package/dist/devices/history-query.d.ts +45 -0
  134. package/dist/devices/history-query.js +182 -0
  135. package/dist/devices/history-query.js.map +1 -0
  136. package/dist/devices/param-validator.d.ts +40 -0
  137. package/dist/devices/param-validator.js +434 -0
  138. package/dist/devices/param-validator.js.map +1 -0
  139. package/dist/devices/resources.d.ts +74 -0
  140. package/dist/devices/resources.js +271 -0
  141. package/dist/devices/resources.js.map +1 -0
  142. package/dist/index.d.ts +1 -0
  143. package/dist/index.js +170 -56946
  144. package/dist/index.js.map +1 -0
  145. package/dist/install/default-steps.d.ts +66 -0
  146. package/dist/install/default-steps.js +258 -0
  147. package/dist/install/default-steps.js.map +1 -0
  148. package/dist/install/preflight.d.ts +60 -0
  149. package/dist/install/preflight.js +213 -0
  150. package/dist/install/preflight.js.map +1 -0
  151. package/dist/install/steps.d.ts +61 -0
  152. package/dist/install/steps.js +68 -0
  153. package/dist/install/steps.js.map +1 -0
  154. package/dist/lib/command-keywords.d.ts +5 -0
  155. package/dist/lib/command-keywords.js +18 -0
  156. package/dist/lib/command-keywords.js.map +1 -0
  157. package/dist/lib/daemon-state.d.ts +24 -0
  158. package/dist/lib/daemon-state.js +47 -0
  159. package/dist/lib/daemon-state.js.map +1 -0
  160. package/dist/lib/destructive-mode.d.ts +2 -0
  161. package/dist/lib/destructive-mode.js +13 -0
  162. package/dist/lib/destructive-mode.js.map +1 -0
  163. package/dist/lib/devices.d.ts +151 -0
  164. package/dist/lib/devices.js +383 -0
  165. package/dist/lib/devices.js.map +1 -0
  166. package/dist/lib/idempotency.d.ts +46 -0
  167. package/dist/lib/idempotency.js +107 -0
  168. package/dist/lib/idempotency.js.map +1 -0
  169. package/dist/lib/plan-store.d.ts +19 -0
  170. package/dist/lib/plan-store.js +69 -0
  171. package/dist/lib/plan-store.js.map +1 -0
  172. package/dist/lib/request-context.d.ts +7 -0
  173. package/dist/lib/request-context.js +13 -0
  174. package/dist/lib/request-context.js.map +1 -0
  175. package/dist/lib/scenes.d.ts +7 -0
  176. package/dist/lib/scenes.js +11 -0
  177. package/dist/lib/scenes.js.map +1 -0
  178. package/dist/logger.d.ts +4 -0
  179. package/dist/logger.js +17 -0
  180. package/dist/logger.js.map +1 -0
  181. package/dist/mcp/device-history.d.ts +36 -0
  182. package/dist/mcp/device-history.js +146 -0
  183. package/dist/mcp/device-history.js.map +1 -0
  184. package/dist/mcp/events-subscription.d.ts +45 -0
  185. package/dist/mcp/events-subscription.js +214 -0
  186. package/dist/mcp/events-subscription.js.map +1 -0
  187. package/dist/mqtt/client.d.ts +25 -0
  188. package/dist/mqtt/client.js +181 -0
  189. package/dist/mqtt/client.js.map +1 -0
  190. package/dist/mqtt/credential.d.ts +16 -0
  191. package/dist/mqtt/credential.js +31 -0
  192. package/dist/mqtt/credential.js.map +1 -0
  193. package/dist/policy/add-rule.d.ts +21 -0
  194. package/dist/policy/add-rule.js +125 -0
  195. package/dist/policy/add-rule.js.map +1 -0
  196. package/dist/policy/diff.d.ts +21 -0
  197. package/dist/policy/diff.js +92 -0
  198. package/dist/policy/diff.js.map +1 -0
  199. package/dist/policy/format.d.ts +6 -0
  200. package/dist/policy/format.js +58 -0
  201. package/dist/policy/format.js.map +1 -0
  202. package/dist/policy/load.d.ts +32 -0
  203. package/dist/policy/load.js +62 -0
  204. package/dist/policy/load.js.map +1 -0
  205. package/dist/policy/migrate.d.ts +21 -0
  206. package/dist/policy/migrate.js +68 -0
  207. package/dist/policy/migrate.js.map +1 -0
  208. package/dist/policy/schema.d.ts +5 -0
  209. package/dist/policy/schema.js +19 -0
  210. package/dist/policy/schema.js.map +1 -0
  211. package/dist/policy/validate.d.ts +19 -0
  212. package/dist/policy/validate.js +263 -0
  213. package/dist/policy/validate.js.map +1 -0
  214. package/dist/rules/action.d.ts +65 -0
  215. package/dist/rules/action.js +217 -0
  216. package/dist/rules/action.js.map +1 -0
  217. package/dist/rules/audit-query.d.ts +51 -0
  218. package/dist/rules/audit-query.js +90 -0
  219. package/dist/rules/audit-query.js.map +1 -0
  220. package/dist/rules/conflict-analyzer.d.ts +57 -0
  221. package/dist/rules/conflict-analyzer.js +215 -0
  222. package/dist/rules/conflict-analyzer.js.map +1 -0
  223. package/dist/rules/cron-scheduler.d.ts +62 -0
  224. package/dist/rules/cron-scheduler.js +187 -0
  225. package/dist/rules/cron-scheduler.js.map +1 -0
  226. package/dist/rules/destructive.d.ts +20 -0
  227. package/dist/rules/destructive.js +53 -0
  228. package/dist/rules/destructive.js.map +1 -0
  229. package/dist/rules/engine.d.ts +193 -0
  230. package/dist/rules/engine.js +758 -0
  231. package/dist/rules/engine.js.map +1 -0
  232. package/dist/rules/matcher.d.ts +56 -0
  233. package/dist/rules/matcher.js +231 -0
  234. package/dist/rules/matcher.js.map +1 -0
  235. package/dist/rules/pid-file.d.ts +43 -0
  236. package/dist/rules/pid-file.js +96 -0
  237. package/dist/rules/pid-file.js.map +1 -0
  238. package/dist/rules/quiet-hours.d.ts +26 -0
  239. package/dist/rules/quiet-hours.js +46 -0
  240. package/dist/rules/quiet-hours.js.map +1 -0
  241. package/dist/rules/suggest.d.ts +20 -0
  242. package/dist/rules/suggest.js +96 -0
  243. package/dist/rules/suggest.js.map +1 -0
  244. package/dist/rules/throttle.d.ts +61 -0
  245. package/dist/rules/throttle.js +117 -0
  246. package/dist/rules/throttle.js.map +1 -0
  247. package/dist/rules/types.d.ts +117 -0
  248. package/dist/rules/types.js +35 -0
  249. package/dist/rules/types.js.map +1 -0
  250. package/dist/rules/webhook-listener.d.ts +63 -0
  251. package/dist/rules/webhook-listener.js +224 -0
  252. package/dist/rules/webhook-listener.js.map +1 -0
  253. package/dist/rules/webhook-token.d.ts +50 -0
  254. package/dist/rules/webhook-token.js +91 -0
  255. package/dist/rules/webhook-token.js.map +1 -0
  256. package/dist/schema/field-aliases.d.ts +34 -0
  257. package/dist/schema/field-aliases.js +132 -0
  258. package/dist/schema/field-aliases.js.map +1 -0
  259. package/dist/sinks/dispatcher.d.ts +7 -0
  260. package/dist/sinks/dispatcher.js +13 -0
  261. package/dist/sinks/dispatcher.js.map +1 -0
  262. package/dist/sinks/file.d.ts +6 -0
  263. package/dist/sinks/file.js +20 -0
  264. package/dist/sinks/file.js.map +1 -0
  265. package/dist/sinks/format.d.ts +20 -0
  266. package/dist/sinks/format.js +57 -0
  267. package/dist/sinks/format.js.map +1 -0
  268. package/dist/sinks/homeassistant.d.ts +18 -0
  269. package/dist/sinks/homeassistant.js +45 -0
  270. package/dist/sinks/homeassistant.js.map +1 -0
  271. package/dist/sinks/openclaw.d.ts +13 -0
  272. package/dist/sinks/openclaw.js +34 -0
  273. package/dist/sinks/openclaw.js.map +1 -0
  274. package/dist/sinks/stdout.d.ts +4 -0
  275. package/dist/sinks/stdout.js +6 -0
  276. package/dist/sinks/stdout.js.map +1 -0
  277. package/dist/sinks/telegram.d.ts +11 -0
  278. package/dist/sinks/telegram.js +29 -0
  279. package/dist/sinks/telegram.js.map +1 -0
  280. package/dist/sinks/types.d.ts +13 -0
  281. package/dist/sinks/types.js +2 -0
  282. package/dist/sinks/types.js.map +1 -0
  283. package/dist/sinks/webhook.d.ts +6 -0
  284. package/dist/sinks/webhook.js +23 -0
  285. package/dist/sinks/webhook.js.map +1 -0
  286. package/dist/status-sync/manager.d.ts +48 -0
  287. package/dist/status-sync/manager.js +269 -0
  288. package/dist/status-sync/manager.js.map +1 -0
  289. package/dist/utils/arg-parsers.d.ts +16 -0
  290. package/dist/utils/arg-parsers.js +67 -0
  291. package/dist/utils/arg-parsers.js.map +1 -0
  292. package/dist/utils/audit.d.ts +69 -0
  293. package/dist/utils/audit.js +122 -0
  294. package/dist/utils/audit.js.map +1 -0
  295. package/dist/utils/filter.d.ts +81 -0
  296. package/dist/utils/filter.js +190 -0
  297. package/dist/utils/filter.js.map +1 -0
  298. package/dist/utils/flags.d.ts +72 -0
  299. package/dist/utils/flags.js +187 -0
  300. package/dist/utils/flags.js.map +1 -0
  301. package/dist/utils/format.d.ts +9 -0
  302. package/dist/utils/format.js +118 -0
  303. package/dist/utils/format.js.map +1 -0
  304. package/dist/utils/health.d.ts +48 -0
  305. package/dist/utils/health.js +102 -0
  306. package/dist/utils/health.js.map +1 -0
  307. package/dist/utils/help-json.d.ts +39 -0
  308. package/dist/utils/help-json.js +55 -0
  309. package/dist/utils/help-json.js.map +1 -0
  310. package/dist/utils/name-resolver.d.ts +26 -0
  311. package/dist/utils/name-resolver.js +138 -0
  312. package/dist/utils/name-resolver.js.map +1 -0
  313. package/dist/utils/output.d.ts +73 -0
  314. package/dist/utils/output.js +405 -0
  315. package/dist/utils/output.js.map +1 -0
  316. package/dist/utils/quota.d.ts +61 -0
  317. package/dist/utils/quota.js +228 -0
  318. package/dist/utils/quota.js.map +1 -0
  319. package/dist/utils/redact.d.ts +23 -0
  320. package/dist/utils/redact.js +69 -0
  321. package/dist/utils/redact.js.map +1 -0
  322. package/dist/utils/retry.d.ts +72 -0
  323. package/dist/utils/retry.js +141 -0
  324. package/dist/utils/retry.js.map +1 -0
  325. package/dist/utils/string.d.ts +2 -0
  326. package/dist/utils/string.js +23 -0
  327. package/dist/utils/string.js.map +1 -0
  328. package/dist/version.d.ts +2 -0
  329. package/dist/version.js +5 -0
  330. package/dist/version.js.map +1 -0
  331. package/package.json +2 -2
@@ -0,0 +1,57 @@
1
+ const ICONS = {
2
+ 'Bot': '🤖',
3
+ 'Curtain': '🪟',
4
+ 'Hub': '📡',
5
+ 'Hub 2': '📡',
6
+ 'Hub 3': '📡',
7
+ 'Hub Mini': '📡',
8
+ 'Smart Lock': '🔒',
9
+ 'Smart Lock Pro': '🔒',
10
+ 'Plug': '🔌',
11
+ 'Plug Mini (US)': '🔌',
12
+ 'Plug Mini (JP)': '🔌',
13
+ 'Color Bulb': '💡',
14
+ 'Strip Light': '💡',
15
+ 'Contact Sensor': '🚪',
16
+ 'Motion Sensor': '👁',
17
+ 'Meter': '🌡',
18
+ 'MeterPro': '🌡',
19
+ 'Climate Panel': '🌡',
20
+ 'WoMeter': '🌡',
21
+ 'WoIOSensor': '🌡',
22
+ };
23
+ function icon(deviceType) {
24
+ return ICONS[deviceType] ?? '📱';
25
+ }
26
+ export function formatEventText(context) {
27
+ const type = context.deviceType ?? 'Unknown';
28
+ const pfx = `${icon(type)} ${type}`;
29
+ const parts = [];
30
+ if (context.temperature !== undefined)
31
+ parts.push(`${context.temperature}°C`);
32
+ if (context.humidity !== undefined)
33
+ parts.push(`${context.humidity}%`);
34
+ if (parts.length)
35
+ return `${pfx}: ${parts.join(' / ')}`;
36
+ if (context.power !== undefined)
37
+ return `${pfx}: ${context.power}`;
38
+ if (context.lockState !== undefined)
39
+ return `${pfx}: ${context.lockState}`;
40
+ if (context.openState !== undefined)
41
+ return `${pfx}: ${context.openState}`;
42
+ if (context.detectionState !== undefined)
43
+ return `${pfx}: ${context.detectionState}`;
44
+ if (context.brightness !== undefined)
45
+ return `${pfx}: ${context.brightness}`;
46
+ return `${pfx}: state change`;
47
+ }
48
+ export function parseSinkEvent(payload) {
49
+ const p = payload;
50
+ const context = (p?.context ?? {});
51
+ return {
52
+ deviceId: String(context.deviceMac ?? 'unknown'),
53
+ deviceType: String(context.deviceType ?? 'Unknown'),
54
+ text: formatEventText(context),
55
+ };
56
+ }
57
+ //# sourceMappingURL=format.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/sinks/format.ts"],"names":[],"mappings":"AAeA,MAAM,KAAK,GAA2B;IACpC,KAAK,EAAE,IAAI;IACX,SAAS,EAAE,IAAI;IACf,KAAK,EAAE,IAAI;IACX,OAAO,EAAE,IAAI;IACb,OAAO,EAAE,IAAI;IACb,UAAU,EAAE,IAAI;IAChB,YAAY,EAAE,IAAI;IAClB,gBAAgB,EAAE,IAAI;IACtB,MAAM,EAAE,IAAI;IACZ,gBAAgB,EAAE,IAAI;IACtB,gBAAgB,EAAE,IAAI;IACtB,YAAY,EAAE,IAAI;IAClB,aAAa,EAAE,IAAI;IACnB,gBAAgB,EAAE,IAAI;IACtB,eAAe,EAAE,IAAI;IACrB,OAAO,EAAE,IAAI;IACb,UAAU,EAAE,IAAI;IAChB,eAAe,EAAE,IAAI;IACrB,SAAS,EAAE,IAAI;IACf,YAAY,EAAE,IAAI;CACnB,CAAC;AAEF,SAAS,IAAI,CAAC,UAAkB;IAC9B,OAAO,KAAK,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,OAAsB;IACpD,MAAM,IAAI,GAAG,OAAO,CAAC,UAAU,IAAI,SAAS,CAAC;IAC7C,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;IACpC,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,IAAI,OAAO,CAAC,WAAW,KAAK,SAAS;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,WAAW,IAAI,CAAC,CAAC;IAC9E,IAAI,OAAO,CAAC,QAAQ,KAAK,SAAS;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACvE,IAAI,KAAK,CAAC,MAAM;QAAE,OAAO,GAAG,GAAG,KAAK,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;IAExD,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS;QAAE,OAAO,GAAG,GAAG,KAAK,OAAO,CAAC,KAAK,EAAE,CAAC;IACnE,IAAI,OAAO,CAAC,SAAS,KAAK,SAAS;QAAE,OAAO,GAAG,GAAG,KAAK,OAAO,CAAC,SAAS,EAAE,CAAC;IAC3E,IAAI,OAAO,CAAC,SAAS,KAAK,SAAS;QAAE,OAAO,GAAG,GAAG,KAAK,OAAO,CAAC,SAAS,EAAE,CAAC;IAC3E,IAAI,OAAO,CAAC,cAAc,KAAK,SAAS;QAAE,OAAO,GAAG,GAAG,KAAK,OAAO,CAAC,cAAc,EAAE,CAAC;IACrF,IAAI,OAAO,CAAC,UAAU,KAAK,SAAS;QAAE,OAAO,GAAG,GAAG,KAAK,OAAO,CAAC,UAAU,EAAE,CAAC;IAE7E,OAAO,GAAG,GAAG,gBAAgB,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,OAAgB;IAK7C,MAAM,CAAC,GAAG,OAAqD,CAAC;IAChE,MAAM,OAAO,GAAI,CAAC,CAAC,EAAE,OAAO,IAAI,EAAE,CAAmB,CAAC;IACtD,OAAO;QACL,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,SAAS,IAAI,SAAS,CAAC;QAChD,UAAU,EAAE,MAAM,CAAC,OAAO,CAAC,UAAU,IAAI,SAAS,CAAC;QACnD,IAAI,EAAE,eAAe,CAAC,OAAO,CAAC;KAC/B,CAAC;AACJ,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { Sink, MqttSinkEvent } from './types.js';
2
+ export interface HomeAssistantSinkOptions {
3
+ url: string;
4
+ /** Long-lived access token — used when webhookId is not set */
5
+ token?: string;
6
+ /** Webhook ID — no auth required, takes priority over token */
7
+ webhookId?: string;
8
+ /** Event type for REST event API (default: switchbot_event) */
9
+ eventType?: string;
10
+ }
11
+ export declare class HomeAssistantSink implements Sink {
12
+ private url;
13
+ private token?;
14
+ private webhookId?;
15
+ private eventType;
16
+ constructor(opts: HomeAssistantSinkOptions);
17
+ write(event: MqttSinkEvent): Promise<void>;
18
+ }
@@ -0,0 +1,45 @@
1
+ export class HomeAssistantSink {
2
+ url;
3
+ token;
4
+ webhookId;
5
+ eventType;
6
+ constructor(opts) {
7
+ this.url = opts.url.replace(/\/$/, '');
8
+ this.token = opts.token;
9
+ this.webhookId = opts.webhookId;
10
+ this.eventType = opts.eventType ?? 'switchbot_event';
11
+ }
12
+ async write(event) {
13
+ try {
14
+ let endpoint;
15
+ const headers = { 'content-type': 'application/json' };
16
+ if (this.webhookId) {
17
+ // Webhook mode: no auth needed, HA triggers automations directly
18
+ endpoint = `${this.url}/api/webhook/${this.webhookId}`;
19
+ }
20
+ else if (this.token) {
21
+ // REST event API: fires a custom event on the HA event bus
22
+ endpoint = `${this.url}/api/events/${this.eventType}`;
23
+ headers['authorization'] = `Bearer ${this.token}`;
24
+ }
25
+ else {
26
+ console.error('[homeassistant] requires --ha-webhook-id or --ha-token');
27
+ return;
28
+ }
29
+ const res = await fetch(endpoint, {
30
+ method: 'POST',
31
+ headers,
32
+ body: JSON.stringify(event),
33
+ signal: AbortSignal.timeout(10000),
34
+ });
35
+ if (!res.ok) {
36
+ const body = await res.text().catch(() => '');
37
+ console.error(`[homeassistant] POST failed: HTTP ${res.status} ${body.slice(0, 200)}`);
38
+ }
39
+ }
40
+ catch (err) {
41
+ console.error(`[homeassistant] error: ${err instanceof Error ? err.message : String(err)}`);
42
+ }
43
+ }
44
+ }
45
+ //# sourceMappingURL=homeassistant.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"homeassistant.js","sourceRoot":"","sources":["../../src/sinks/homeassistant.ts"],"names":[],"mappings":"AAYA,MAAM,OAAO,iBAAiB;IACpB,GAAG,CAAS;IACZ,KAAK,CAAU;IACf,SAAS,CAAU;IACnB,SAAS,CAAS;IAE1B,YAAY,IAA8B;QACxC,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACvC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QACxB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;QAChC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,iBAAiB,CAAC;IACvD,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,KAAoB;QAC9B,IAAI,CAAC;YACH,IAAI,QAAgB,CAAC;YACrB,MAAM,OAAO,GAA2B,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC;YAE/E,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;gBACnB,iEAAiE;gBACjE,QAAQ,GAAG,GAAG,IAAI,CAAC,GAAG,gBAAgB,IAAI,CAAC,SAAS,EAAE,CAAC;YACzD,CAAC;iBAAM,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBACtB,2DAA2D;gBAC3D,QAAQ,GAAG,GAAG,IAAI,CAAC,GAAG,eAAe,IAAI,CAAC,SAAS,EAAE,CAAC;gBACtD,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,IAAI,CAAC,KAAK,EAAE,CAAC;YACpD,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,KAAK,CAAC,wDAAwD,CAAC,CAAC;gBACxE,OAAO;YACT,CAAC;YAED,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,QAAQ,EAAE;gBAChC,MAAM,EAAE,MAAM;gBACd,OAAO;gBACP,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;gBAC3B,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC;aACnC,CAAC,CAAC;YACH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;gBACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;gBAC9C,OAAO,CAAC,KAAK,CAAC,qCAAqC,GAAG,CAAC,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;YACzF,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,0BAA0B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC9F,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,13 @@
1
+ import type { Sink, MqttSinkEvent } from './types.js';
2
+ export interface OpenClawSinkOptions {
3
+ url?: string;
4
+ token: string;
5
+ model: string;
6
+ }
7
+ export declare class OpenClawSink implements Sink {
8
+ private url;
9
+ private token;
10
+ private model;
11
+ constructor(opts: OpenClawSinkOptions);
12
+ write(event: MqttSinkEvent): Promise<void>;
13
+ }
@@ -0,0 +1,34 @@
1
+ export class OpenClawSink {
2
+ url;
3
+ token;
4
+ model;
5
+ constructor(opts) {
6
+ this.url = (opts.url ?? 'http://localhost:18789').replace(/\/$/, '');
7
+ this.token = opts.token;
8
+ this.model = opts.model;
9
+ }
10
+ async write(event) {
11
+ try {
12
+ const res = await fetch(`${this.url}/v1/chat/completions`, {
13
+ method: 'POST',
14
+ headers: {
15
+ 'content-type': 'application/json',
16
+ 'authorization': `Bearer ${this.token}`,
17
+ },
18
+ body: JSON.stringify({
19
+ model: this.model,
20
+ messages: [{ role: 'user', content: event.text }],
21
+ }),
22
+ signal: AbortSignal.timeout(10000),
23
+ });
24
+ if (!res.ok) {
25
+ const body = await res.text().catch(() => '');
26
+ console.error(`[openclaw] POST failed: HTTP ${res.status} ${body.slice(0, 200)}`);
27
+ }
28
+ }
29
+ catch (err) {
30
+ console.error(`[openclaw] error: ${err instanceof Error ? err.message : String(err)}`);
31
+ }
32
+ }
33
+ }
34
+ //# sourceMappingURL=openclaw.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openclaw.js","sourceRoot":"","sources":["../../src/sinks/openclaw.ts"],"names":[],"mappings":"AAQA,MAAM,OAAO,YAAY;IACf,GAAG,CAAS;IACZ,KAAK,CAAS;IACd,KAAK,CAAS;IAEtB,YAAY,IAAyB;QACnC,IAAI,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,wBAAwB,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACrE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QACxB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;IAC1B,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,KAAoB;QAC9B,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,GAAG,sBAAsB,EAAE;gBACzD,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,cAAc,EAAE,kBAAkB;oBAClC,eAAe,EAAE,UAAU,IAAI,CAAC,KAAK,EAAE;iBACxC;gBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;oBACnB,KAAK,EAAE,IAAI,CAAC,KAAK;oBACjB,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;iBAClD,CAAC;gBACF,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC;aACnC,CAAC,CAAC;YACH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;gBACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;gBAC9C,OAAO,CAAC,KAAK,CAAC,gCAAgC,GAAG,CAAC,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;YACpF,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,qBAAqB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACzF,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,4 @@
1
+ import type { Sink, MqttSinkEvent } from './types.js';
2
+ export declare class StdoutSink implements Sink {
3
+ write(event: MqttSinkEvent): Promise<void>;
4
+ }
@@ -0,0 +1,6 @@
1
+ export class StdoutSink {
2
+ async write(event) {
3
+ console.log(JSON.stringify(event));
4
+ }
5
+ }
6
+ //# sourceMappingURL=stdout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stdout.js","sourceRoot":"","sources":["../../src/sinks/stdout.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,UAAU;IACrB,KAAK,CAAC,KAAK,CAAC,KAAoB;QAC9B,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;IACrC,CAAC;CACF"}
@@ -0,0 +1,11 @@
1
+ import type { Sink, MqttSinkEvent } from './types.js';
2
+ export interface TelegramSinkOptions {
3
+ token: string;
4
+ chatId: string;
5
+ }
6
+ export declare class TelegramSink implements Sink {
7
+ private token;
8
+ private chatId;
9
+ constructor(opts: TelegramSinkOptions);
10
+ write(event: MqttSinkEvent): Promise<void>;
11
+ }
@@ -0,0 +1,29 @@
1
+ export class TelegramSink {
2
+ token;
3
+ chatId;
4
+ constructor(opts) {
5
+ this.token = opts.token;
6
+ this.chatId = opts.chatId;
7
+ }
8
+ async write(event) {
9
+ try {
10
+ const res = await fetch(`https://api.telegram.org/bot${this.token}/sendMessage`, {
11
+ method: 'POST',
12
+ headers: { 'content-type': 'application/json' },
13
+ body: JSON.stringify({
14
+ chat_id: this.chatId,
15
+ text: event.text,
16
+ }),
17
+ signal: AbortSignal.timeout(10000),
18
+ });
19
+ if (!res.ok) {
20
+ const body = await res.text().catch(() => '');
21
+ console.error(`[telegram] POST failed: HTTP ${res.status} ${body.slice(0, 200)}`);
22
+ }
23
+ }
24
+ catch (err) {
25
+ console.error(`[telegram] error: ${err instanceof Error ? err.message : String(err)}`);
26
+ }
27
+ }
28
+ }
29
+ //# sourceMappingURL=telegram.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telegram.js","sourceRoot":"","sources":["../../src/sinks/telegram.ts"],"names":[],"mappings":"AAOA,MAAM,OAAO,YAAY;IACf,KAAK,CAAS;IACd,MAAM,CAAS;IAEvB,YAAY,IAAyB;QACnC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QACxB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IAC5B,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,KAAoB;QAC9B,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,+BAA+B,IAAI,CAAC,KAAK,cAAc,EAAE;gBAC/E,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;gBAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;oBACnB,OAAO,EAAE,IAAI,CAAC,MAAM;oBACpB,IAAI,EAAE,KAAK,CAAC,IAAI;iBACjB,CAAC;gBACF,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC;aACnC,CAAC,CAAC;YACH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;gBACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;gBAC9C,OAAO,CAAC,KAAK,CAAC,gCAAgC,GAAG,CAAC,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;YACpF,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,qBAAqB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACzF,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,13 @@
1
+ export interface MqttSinkEvent {
2
+ t: string;
3
+ topic: string;
4
+ deviceId: string;
5
+ deviceType: string;
6
+ payload: unknown;
7
+ text: string;
8
+ eventId?: string;
9
+ }
10
+ export interface Sink {
11
+ write(event: MqttSinkEvent): Promise<void>;
12
+ close?(): Promise<void>;
13
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/sinks/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,6 @@
1
+ import type { Sink, MqttSinkEvent } from './types.js';
2
+ export declare class WebhookSink implements Sink {
3
+ private url;
4
+ constructor(url: string);
5
+ write(event: MqttSinkEvent): Promise<void>;
6
+ }
@@ -0,0 +1,23 @@
1
+ export class WebhookSink {
2
+ url;
3
+ constructor(url) {
4
+ this.url = url;
5
+ }
6
+ async write(event) {
7
+ try {
8
+ const res = await fetch(this.url, {
9
+ method: 'POST',
10
+ headers: { 'content-type': 'application/json' },
11
+ body: JSON.stringify(event),
12
+ signal: AbortSignal.timeout(10000),
13
+ });
14
+ if (!res.ok) {
15
+ console.error(`[webhook] POST failed: HTTP ${res.status}`);
16
+ }
17
+ }
18
+ catch (err) {
19
+ console.error(`[webhook] error: ${err instanceof Error ? err.message : String(err)}`);
20
+ }
21
+ }
22
+ }
23
+ //# sourceMappingURL=webhook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook.js","sourceRoot":"","sources":["../../src/sinks/webhook.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,WAAW;IACd,GAAG,CAAS;IAEpB,YAAY,GAAW;QACrB,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,KAAoB;QAC9B,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE;gBAChC,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;gBAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;gBAC3B,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC;aACnC,CAAC,CAAC;YACH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;gBACZ,OAAO,CAAC,KAAK,CAAC,+BAA+B,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;YAC7D,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,oBAAoB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACxF,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,48 @@
1
+ export interface StatusSyncPaths {
2
+ stateDir: string;
3
+ stateFile: string;
4
+ stdoutLog: string;
5
+ stderrLog: string;
6
+ }
7
+ export interface StatusSyncStatus {
8
+ running: boolean;
9
+ pid: number | null;
10
+ startedAt: string | null;
11
+ stateDir: string;
12
+ stateFile: string;
13
+ stdoutLog: string;
14
+ stderrLog: string;
15
+ command: string[] | null;
16
+ openclawUrl: string | null;
17
+ openclawModel: string | null;
18
+ topic: string | null;
19
+ configPath: string | null;
20
+ profile: string | null;
21
+ }
22
+ export interface StopStatusSyncResult {
23
+ stopped: boolean;
24
+ stale: boolean;
25
+ pid: number | null;
26
+ status: StatusSyncStatus;
27
+ }
28
+ export interface StartStatusSyncOptions {
29
+ openclawUrl?: string;
30
+ openclawToken?: string;
31
+ openclawModel?: string;
32
+ topic?: string;
33
+ stateDir?: string;
34
+ force?: boolean;
35
+ }
36
+ export interface StatusSyncStatusOptions {
37
+ stateDir?: string;
38
+ }
39
+ export declare function resolveStatusSyncPaths(explicitStateDir?: string): StatusSyncPaths;
40
+ export declare function buildStatusSyncChildArgs(options: {
41
+ openclawUrl: string;
42
+ openclawModel: string;
43
+ topic?: string;
44
+ }): string[];
45
+ export declare function getStatusSyncStatus(options?: StatusSyncStatusOptions): StatusSyncStatus;
46
+ export declare function stopStatusSync(options?: StatusSyncStatusOptions): StopStatusSyncResult;
47
+ export declare function startStatusSync(options?: StartStatusSyncOptions): StatusSyncStatus;
48
+ export declare function runStatusSyncForeground(options?: Omit<StartStatusSyncOptions, 'stateDir' | 'force'>): Promise<number>;
@@ -0,0 +1,269 @@
1
+ import { spawn, spawnSync } from 'node:child_process';
2
+ import fs from 'node:fs';
3
+ import os from 'node:os';
4
+ import path from 'node:path';
5
+ import { tryLoadConfig } from '../config.js';
6
+ import { getActiveProfile } from '../lib/request-context.js';
7
+ import { UsageError } from '../utils/output.js';
8
+ import { getConfigPath } from '../utils/flags.js';
9
+ const DEFAULT_OPENCLAW_URL = 'http://localhost:18789';
10
+ function resolveStatusSyncRuntime(options) {
11
+ if (!tryLoadConfig()) {
12
+ throw new UsageError('No credentials found. Run \'switchbot config set-token\' or set SWITCHBOT_TOKEN and SWITCHBOT_SECRET.');
13
+ }
14
+ const openclawToken = options.openclawToken ?? process.env.OPENCLAW_TOKEN;
15
+ if (!openclawToken) {
16
+ throw new UsageError('--openclaw-token is required or set OPENCLAW_TOKEN in the environment.');
17
+ }
18
+ const openclawModel = options.openclawModel ?? process.env.OPENCLAW_MODEL;
19
+ if (!openclawModel) {
20
+ throw new UsageError('--openclaw-model is required or set OPENCLAW_MODEL in the environment.');
21
+ }
22
+ return {
23
+ openclawUrl: options.openclawUrl ?? process.env.OPENCLAW_URL ?? DEFAULT_OPENCLAW_URL,
24
+ openclawToken,
25
+ openclawModel,
26
+ ...(options.topic ? { topic: options.topic } : {}),
27
+ };
28
+ }
29
+ export function resolveStatusSyncPaths(explicitStateDir) {
30
+ const stateDir = path.resolve(explicitStateDir
31
+ ?? process.env.SWITCHBOT_STATUS_SYNC_HOME
32
+ ?? path.join(os.homedir(), '.switchbot', 'status-sync'));
33
+ return {
34
+ stateDir,
35
+ stateFile: path.join(stateDir, 'state.json'),
36
+ stdoutLog: path.join(stateDir, 'stdout.log'),
37
+ stderrLog: path.join(stateDir, 'stderr.log'),
38
+ };
39
+ }
40
+ export function buildStatusSyncChildArgs(options) {
41
+ const scriptPath = process.argv[1];
42
+ if (!scriptPath) {
43
+ throw new Error('Cannot determine the current CLI entrypoint path.');
44
+ }
45
+ const args = [path.resolve(scriptPath)];
46
+ const configPath = getConfigPath();
47
+ const profile = getActiveProfile();
48
+ if (configPath) {
49
+ args.push('--config', path.resolve(configPath));
50
+ }
51
+ else if (profile) {
52
+ args.push('--profile', profile);
53
+ }
54
+ args.push('events', 'mqtt-tail', '--sink', 'openclaw', '--openclaw-url', options.openclawUrl, '--openclaw-model', options.openclawModel);
55
+ if (options.topic) {
56
+ args.push('--topic', options.topic);
57
+ }
58
+ return args;
59
+ }
60
+ function safeUnlink(filePath) {
61
+ try {
62
+ fs.unlinkSync(filePath);
63
+ }
64
+ catch {
65
+ // best-effort cleanup
66
+ }
67
+ }
68
+ function isProcessRunning(pid) {
69
+ try {
70
+ process.kill(pid, 0);
71
+ return true;
72
+ }
73
+ catch (err) {
74
+ const code = err.code;
75
+ if (code === 'EPERM')
76
+ return true;
77
+ return false;
78
+ }
79
+ }
80
+ function readStateFile(paths) {
81
+ if (!fs.existsSync(paths.stateFile))
82
+ return null;
83
+ try {
84
+ const raw = JSON.parse(fs.readFileSync(paths.stateFile, 'utf-8'));
85
+ if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {
86
+ safeUnlink(paths.stateFile);
87
+ return null;
88
+ }
89
+ const parsed = raw;
90
+ if (typeof parsed.pid !== 'number' ||
91
+ !Number.isInteger(parsed.pid) ||
92
+ parsed.pid < 1 ||
93
+ typeof parsed.startedAt !== 'string' ||
94
+ !Array.isArray(parsed.command) ||
95
+ typeof parsed.stdoutLog !== 'string' ||
96
+ typeof parsed.stderrLog !== 'string') {
97
+ safeUnlink(paths.stateFile);
98
+ return null;
99
+ }
100
+ return {
101
+ pid: parsed.pid,
102
+ startedAt: parsed.startedAt,
103
+ command: parsed.command.map(String),
104
+ openclawUrl: typeof parsed.openclawUrl === 'string' ? parsed.openclawUrl : DEFAULT_OPENCLAW_URL,
105
+ openclawModel: typeof parsed.openclawModel === 'string' ? parsed.openclawModel : '',
106
+ topic: typeof parsed.topic === 'string' ? parsed.topic : null,
107
+ configPath: typeof parsed.configPath === 'string' ? parsed.configPath : null,
108
+ profile: typeof parsed.profile === 'string' ? parsed.profile : null,
109
+ stdoutLog: parsed.stdoutLog,
110
+ stderrLog: parsed.stderrLog,
111
+ };
112
+ }
113
+ catch {
114
+ safeUnlink(paths.stateFile);
115
+ return null;
116
+ }
117
+ }
118
+ function toStatus(paths, state, running) {
119
+ return {
120
+ running,
121
+ pid: running && state ? state.pid : null,
122
+ startedAt: running && state ? state.startedAt : null,
123
+ stateDir: paths.stateDir,
124
+ stateFile: paths.stateFile,
125
+ stdoutLog: state?.stdoutLog ?? paths.stdoutLog,
126
+ stderrLog: state?.stderrLog ?? paths.stderrLog,
127
+ command: running && state ? state.command : null,
128
+ openclawUrl: running && state ? state.openclawUrl : null,
129
+ openclawModel: running && state ? state.openclawModel : null,
130
+ topic: running && state ? state.topic : null,
131
+ configPath: running && state ? state.configPath : null,
132
+ profile: running && state ? state.profile : null,
133
+ };
134
+ }
135
+ function killProcessTree(pid) {
136
+ if (process.platform === 'win32') {
137
+ const result = spawnSync('taskkill', ['/PID', String(pid), '/T', '/F'], { stdio: 'ignore' });
138
+ if (result.error)
139
+ throw result.error;
140
+ if (result.status !== 0 && isProcessRunning(pid)) {
141
+ throw new Error(`Failed to stop status-sync process tree (PID ${pid}).`);
142
+ }
143
+ return;
144
+ }
145
+ try {
146
+ process.kill(-pid, 'SIGTERM');
147
+ }
148
+ catch (err) {
149
+ const code = err.code;
150
+ if (code === 'ESRCH') {
151
+ return;
152
+ }
153
+ process.kill(pid, 'SIGTERM');
154
+ }
155
+ }
156
+ export function getStatusSyncStatus(options = {}) {
157
+ const paths = resolveStatusSyncPaths(options.stateDir);
158
+ const state = readStateFile(paths);
159
+ if (!state) {
160
+ return toStatus(paths, null, false);
161
+ }
162
+ if (!isProcessRunning(state.pid)) {
163
+ safeUnlink(paths.stateFile);
164
+ return toStatus(paths, null, false);
165
+ }
166
+ return toStatus(paths, state, true);
167
+ }
168
+ export function stopStatusSync(options = {}) {
169
+ const paths = resolveStatusSyncPaths(options.stateDir);
170
+ const state = readStateFile(paths);
171
+ if (!state) {
172
+ return {
173
+ stopped: false,
174
+ stale: false,
175
+ pid: null,
176
+ status: toStatus(paths, null, false),
177
+ };
178
+ }
179
+ if (!isProcessRunning(state.pid)) {
180
+ safeUnlink(paths.stateFile);
181
+ return {
182
+ stopped: false,
183
+ stale: true,
184
+ pid: state.pid,
185
+ status: toStatus(paths, null, false),
186
+ };
187
+ }
188
+ killProcessTree(state.pid);
189
+ if (isProcessRunning(state.pid)) {
190
+ throw new Error(`Failed to stop status-sync process (PID ${state.pid}); process is still running.`);
191
+ }
192
+ safeUnlink(paths.stateFile);
193
+ return {
194
+ stopped: true,
195
+ stale: false,
196
+ pid: state.pid,
197
+ status: toStatus(paths, null, false),
198
+ };
199
+ }
200
+ export function startStatusSync(options = {}) {
201
+ const runtime = resolveStatusSyncRuntime(options);
202
+ const paths = resolveStatusSyncPaths(options.stateDir);
203
+ const existing = getStatusSyncStatus({ stateDir: paths.stateDir });
204
+ if (existing.running) {
205
+ if (!options.force) {
206
+ throw new UsageError(`status-sync is already running (PID ${existing.pid}). Run 'switchbot status-sync stop' first or re-run with --force.`);
207
+ }
208
+ stopStatusSync({ stateDir: paths.stateDir });
209
+ }
210
+ fs.mkdirSync(paths.stateDir, { recursive: true });
211
+ const configPath = getConfigPath();
212
+ const command = buildStatusSyncChildArgs(runtime);
213
+ let stdoutFd = null;
214
+ let stderrFd = null;
215
+ try {
216
+ stdoutFd = fs.openSync(paths.stdoutLog, 'a');
217
+ stderrFd = fs.openSync(paths.stderrLog, 'a');
218
+ const child = spawn(process.execPath, command, {
219
+ detached: true,
220
+ stdio: ['ignore', stdoutFd, stderrFd],
221
+ windowsHide: true,
222
+ env: { ...process.env, OPENCLAW_TOKEN: runtime.openclawToken },
223
+ });
224
+ if (!child.pid) {
225
+ throw new Error('Failed to start status-sync child process.');
226
+ }
227
+ child.unref();
228
+ const state = {
229
+ pid: child.pid,
230
+ startedAt: new Date().toISOString(),
231
+ command: [process.execPath, ...command],
232
+ openclawUrl: runtime.openclawUrl,
233
+ openclawModel: runtime.openclawModel,
234
+ topic: runtime.topic ?? null,
235
+ configPath: configPath ? path.resolve(configPath) : null,
236
+ profile: configPath ? null : (getActiveProfile() ?? null),
237
+ stdoutLog: paths.stdoutLog,
238
+ stderrLog: paths.stderrLog,
239
+ };
240
+ fs.writeFileSync(paths.stateFile, JSON.stringify(state, null, 2), { mode: 0o600 });
241
+ return toStatus(paths, state, true);
242
+ }
243
+ finally {
244
+ if (stdoutFd !== null)
245
+ fs.closeSync(stdoutFd);
246
+ if (stderrFd !== null)
247
+ fs.closeSync(stderrFd);
248
+ }
249
+ }
250
+ export async function runStatusSyncForeground(options = {}) {
251
+ const runtime = resolveStatusSyncRuntime(options);
252
+ const command = buildStatusSyncChildArgs(runtime);
253
+ return await new Promise((resolve, reject) => {
254
+ const child = spawn(process.execPath, command, {
255
+ stdio: 'inherit',
256
+ windowsHide: true,
257
+ env: { ...process.env, OPENCLAW_TOKEN: runtime.openclawToken },
258
+ });
259
+ child.once('error', reject);
260
+ child.once('exit', (code, signal) => {
261
+ if (signal) {
262
+ resolve(1);
263
+ return;
264
+ }
265
+ resolve(code ?? 0);
266
+ });
267
+ });
268
+ }
269
+ //# sourceMappingURL=manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/status-sync/manager.ts"],"names":[],"mappings":"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"}