smart-home-engine 1.0.4 → 1.0.6

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.
@@ -1,4 +1,4 @@
1
- import{m as O}from"./monaco-langs-BW2J83t5.js";import{t as I}from"./index-BVcuT75t.js";/*!-----------------------------------------------------------------------------
1
+ import{m as O}from"./monaco-langs-BW2J83t5.js";import{t as I}from"./index-BQ_d2xRZ.js";/*!-----------------------------------------------------------------------------
2
2
  * Copyright (c) Microsoft Corporation. All rights reserved.
3
3
  * Version: 0.52.2(404545bded1df6ffa41ea0af4e8ddb219018c6c1)
4
4
  * Released under the MIT license
@@ -137,7 +137,14 @@
137
137
  box-sizing: border-box;
138
138
  margin: 0;
139
139
  padding: 0;
140
+ /* Thin custom scrollbar — matches Monaco's 6 px scrollbar style */
141
+ scrollbar-width: thin;
142
+ scrollbar-color: var(--fg-dim) transparent;
140
143
  }
144
+ *::-webkit-scrollbar { width: 6px; height: 6px; }
145
+ *::-webkit-scrollbar-track { background: transparent; }
146
+ *::-webkit-scrollbar-thumb { background: var(--fg-dim); border-radius: 3px; }
147
+ *::-webkit-scrollbar-thumb:hover { background: var(--fg-muted); }
141
148
  body {
142
149
  font-family: 'Segoe UI', system-ui, sans-serif;
143
150
  background: var(--bg-app);
@@ -155,10 +162,10 @@
155
162
  }
156
163
  })();
157
164
  </script>
158
- <script type="module" crossorigin src="/assets/index-BVcuT75t.js"></script>
165
+ <script type="module" crossorigin src="/assets/index-BQ_d2xRZ.js"></script>
159
166
  <link rel="modulepreload" crossorigin href="/assets/monaco-langs-BW2J83t5.js">
160
167
  <link rel="stylesheet" crossorigin href="/assets/monaco-langs-DyX1CsEw.css">
161
- <link rel="stylesheet" crossorigin href="/assets/index-XdHeWvgU.css">
168
+ <link rel="stylesheet" crossorigin href="/assets/index-hs5iZLtu.css">
162
169
  </head>
163
170
  <body>
164
171
  <div id="app"></div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "smart-home-engine",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "description": "Node.js based script runner for use in MQTT based Smart Home environments",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
package/src/index.js CHANGED
@@ -337,6 +337,10 @@ require('./web/server').setStatsProvider(() => {
337
337
  // Inform newly-connected WebSocket clients of the current mqtt:status so the
338
338
  // UI shows the correct indicator even if the browser opened after the event fired.
339
339
  setWelcomeProvider(() => ({ type: 'mqtt:status', ready: _started }));
340
+ // Push current script:running state so the UI green dots survive a browser reload.
341
+ setWelcomeProvider(() =>
342
+ Object.keys(scripts).map((f) => ({ type: 'script:running', path: makeLabel(f).slice(0, -1), running: true }))
343
+ );
340
344
 
341
345
  if (!config.url) {
342
346
  log.warn('no MQTT broker URL configured — set "url" in ' + path.join(require('os').homedir(), '.she', 'config.json'));
@@ -21,6 +21,13 @@ module.exports = function (she, ctx = {}) {
21
21
  // Timeout handles indexed by target (string key or function reference).
22
22
  const timerHandles = new Map();
23
23
 
24
+ // Treat common MQTT string payloads as falsy: "off" (any case) matches
25
+ // devices (Zigbee, Tasmota, etc.) that publish "off"/"OFF" instead of 0.
26
+ function isTruthy(v) {
27
+ if (typeof v === 'string') return v.toLowerCase() !== 'off';
28
+ return !!v;
29
+ }
30
+
24
31
  /**
25
32
  * Namespaced MQTT API - the primary way to interact with MQTT from scripts.
26
33
  * @namespace she.mqtt
@@ -55,7 +62,7 @@ module.exports = function (she, ctx = {}) {
55
62
  */
56
63
  or: function Sandbox_mqtt_or(srcs, target) {
57
64
  function combine(topic) {
58
- const result = srcs.some((src) => she.getValue(src)) ? 1 : 0;
65
+ const result = srcs.some((src) => isTruthy(she.getValue(src))) ? 1 : 0;
59
66
  sink(target, topic ?? null, result);
60
67
  }
61
68
  combine(null);
@@ -67,7 +74,7 @@ module.exports = function (she, ctx = {}) {
67
74
  */
68
75
  and: function Sandbox_mqtt_and(srcs, target) {
69
76
  function combine(topic) {
70
- const result = srcs.every((src) => she.getValue(src)) ? 1 : 0;
77
+ const result = srcs.every((src) => isTruthy(she.getValue(src))) ? 1 : 0;
71
78
  sink(target, topic ?? null, result);
72
79
  }
73
80
  combine(null);
@@ -112,7 +119,7 @@ module.exports = function (she, ctx = {}) {
112
119
  timer: function Sandbox_mqtt_timer(src, ms, target) {
113
120
  const key = target;
114
121
  she.mqttsub(src, { retain: false }, (topic, val) => {
115
- if (val) {
122
+ if (isTruthy(val)) {
116
123
  she.clearTimeout(timerHandles.get(key));
117
124
  sink(target, topic, 1);
118
125
  timerHandles.set(
package/src/web/log-ws.js CHANGED
@@ -4,16 +4,16 @@ const { WebSocketServer } = require('ws');
4
4
 
5
5
  let _wss = null;
6
6
  const _clients = new Set();
7
- let _welcomeProvider = null;
7
+ const _welcomeProviders = [];
8
8
 
9
9
  /**
10
- * Register a function that returns a welcome message to send to each new
11
- * WebSocket client immediately after it connects. Useful for pushing
12
- * current state (e.g. mqtt:status) without waiting for the next broadcast.
13
- * @param {() => object} fn
10
+ * Register a function that returns a welcome message (or array of messages)
11
+ * to send to each new WebSocket client immediately after it connects.
12
+ * May be called multiple times; all registered providers are invoked in order.
13
+ * @param {() => object | object[]} fn
14
14
  */
15
15
  function setWelcomeProvider(fn) {
16
- _welcomeProvider = fn;
16
+ _welcomeProviders.push(fn);
17
17
  }
18
18
 
19
19
  // Ring buffer of recent log entries for the AI tool get_script_logs
@@ -43,9 +43,12 @@ function attachWss(httpServer, authCheck = () => true) {
43
43
  ws.on('close', () => _clients.delete(ws));
44
44
  ws.on('error', () => _clients.delete(ws));
45
45
  // Send current state to this new client immediately
46
- if (_welcomeProvider) {
47
- const welcome = _welcomeProvider();
48
- if (welcome) ws.send(JSON.stringify(welcome));
46
+ for (const provider of _welcomeProviders) {
47
+ const msgs = provider();
48
+ if (!msgs) continue;
49
+ for (const msg of (Array.isArray(msgs) ? msgs : [msgs])) {
50
+ ws.send(JSON.stringify(msg));
51
+ }
49
52
  }
50
53
  });
51
54