smart-home-engine 0.24.6 → 0.26.0
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.
- package/dist/web/assets/{index-2XghiaRb.css → index-CND95LL-.css} +1 -1
- package/dist/web/assets/index-_pI34Lpo.js +225 -0
- package/dist/web/assets/{tsMode-6wpkRoMY.js → tsMode-X6DYzZOw.js} +1 -1
- package/dist/web/index.html +2 -2
- package/package.json +1 -1
- package/src/index.js +5 -0
- package/src/web/config-api.js +18 -1
- package/src/web/git-api.js +2 -2
- package/src/web/prompts/she-api-ref.md +2 -0
- package/src/web/scripts-api.js +39 -0
- package/src/web/server.js +3 -0
- package/dist/web/assets/index-_dyUIPCt.js +0 -225
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{m as O}from"./monaco-langs-BW2J83t5.js";import{t as I}from"./index-
|
|
1
|
+
import{m as O}from"./monaco-langs-BW2J83t5.js";import{t as I}from"./index-_pI34Lpo.js";/*!-----------------------------------------------------------------------------
|
|
2
2
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
3
|
* Version: 0.52.2(404545bded1df6ffa41ea0af4e8ddb219018c6c1)
|
|
4
4
|
* Released under the MIT license
|
package/dist/web/index.html
CHANGED
|
@@ -155,10 +155,10 @@
|
|
|
155
155
|
}
|
|
156
156
|
})();
|
|
157
157
|
</script>
|
|
158
|
-
<script type="module" crossorigin src="/assets/index-
|
|
158
|
+
<script type="module" crossorigin src="/assets/index-_pI34Lpo.js"></script>
|
|
159
159
|
<link rel="modulepreload" crossorigin href="/assets/monaco-langs-BW2J83t5.js">
|
|
160
160
|
<link rel="stylesheet" crossorigin href="/assets/monaco-langs-DyX1CsEw.css">
|
|
161
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
161
|
+
<link rel="stylesheet" crossorigin href="/assets/index-CND95LL-.css">
|
|
162
162
|
</head>
|
|
163
163
|
<body>
|
|
164
164
|
<div id="app"></div>
|
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -985,6 +985,11 @@ function runScript(script, name, origin) {
|
|
|
985
985
|
};
|
|
986
986
|
|
|
987
987
|
const scriptName = path.basename(name, path.extname(name));
|
|
988
|
+
// Expose read-only config values relevant to scripts.
|
|
989
|
+
she.config = Object.freeze({
|
|
990
|
+
latitude: config.latitude,
|
|
991
|
+
longitude: config.longitude,
|
|
992
|
+
});
|
|
988
993
|
// she.setTimeout / she.clearTimeout — tracked versions for use by stdlib and
|
|
989
994
|
// sandbox modules that don't have direct access to the Sandbox context.
|
|
990
995
|
she.setTimeout = (fn, delay, ...args) => {
|
package/src/web/config-api.js
CHANGED
|
@@ -7,6 +7,12 @@ const { getConfigPath } = require('../lib/storage');
|
|
|
7
7
|
|
|
8
8
|
const DEFAULT_CONFIG_PATH = getConfigPath();
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
* Config keys that are consumed only by the frontend (no daemon restart needed).
|
|
12
|
+
* All other keys require a daemon restart when changed.
|
|
13
|
+
*/
|
|
14
|
+
const FRONTEND_ONLY_KEYS = new Set(['gitAutoCommit', 'gitAutoPush']);
|
|
15
|
+
|
|
10
16
|
const router = express.Router();
|
|
11
17
|
|
|
12
18
|
router.get('/', (req, res) => {
|
|
@@ -23,9 +29,20 @@ router.get('/', (req, res) => {
|
|
|
23
29
|
router.put('/', (req, res) => {
|
|
24
30
|
const configPath = req.app.locals.configPath || DEFAULT_CONFIG_PATH;
|
|
25
31
|
try {
|
|
32
|
+
let oldConfig = {};
|
|
33
|
+
try { oldConfig = JSON.parse(fs.readFileSync(configPath, 'utf8')); } catch { /* ok — file may not exist yet */ }
|
|
34
|
+
|
|
26
35
|
fs.mkdirSync(path.dirname(configPath), { recursive: true });
|
|
27
36
|
fs.writeFileSync(configPath, JSON.stringify(req.body, null, 2), 'utf8');
|
|
28
|
-
|
|
37
|
+
|
|
38
|
+
// Restart is only required when a daemon-critical key changed.
|
|
39
|
+
const newConfig = req.body || {};
|
|
40
|
+
const allKeys = new Set([...Object.keys(oldConfig), ...Object.keys(newConfig)]);
|
|
41
|
+
const restartRequired = [...allKeys].some(
|
|
42
|
+
(k) => !FRONTEND_ONLY_KEYS.has(k) && JSON.stringify(oldConfig[k]) !== JSON.stringify(newConfig[k]),
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
res.json({ ok: true, restartRequired, configPath });
|
|
29
46
|
} catch (err) {
|
|
30
47
|
res.status(500).json({ error: err.message });
|
|
31
48
|
}
|
package/src/web/git-api.js
CHANGED
|
@@ -18,7 +18,7 @@ function git(args, cwd, timeout = 30000) {
|
|
|
18
18
|
return new Promise((resolve, reject) => {
|
|
19
19
|
execFile('git', args, { cwd, timeout }, (err, stdout, stderr) => {
|
|
20
20
|
if (err) {
|
|
21
|
-
const e = new Error(stderr.trim() || err.message);
|
|
21
|
+
const e = new Error(stderr.trim() || stdout.trim() || err.message);
|
|
22
22
|
e.stderr = stderr;
|
|
23
23
|
e.stdout = stdout;
|
|
24
24
|
reject(e);
|
|
@@ -198,4 +198,4 @@ router.post('/push', async (req, res) => {
|
|
|
198
198
|
}
|
|
199
199
|
});
|
|
200
200
|
|
|
201
|
-
module.exports = { router };
|
|
201
|
+
module.exports = { router, git, getGitRoot };
|
|
@@ -75,6 +75,8 @@ she.global Shared mutable object across all scripts
|
|
|
75
75
|
she.fetch(url, [opts]) HTTP/HTTPS fetch → Promise<string|object>
|
|
76
76
|
Auto-parses JSON by Content-Type.
|
|
77
77
|
Throws on non-2xx status.
|
|
78
|
+
she.config.latitude Read-only: geographic latitude from daemon config
|
|
79
|
+
she.config.longitude Read-only: geographic longitude from daemon config
|
|
78
80
|
```
|
|
79
81
|
|
|
80
82
|
### Script HTTP API
|
package/src/web/scripts-api.js
CHANGED
|
@@ -3,9 +3,46 @@
|
|
|
3
3
|
const express = require('express');
|
|
4
4
|
const fs = require('fs');
|
|
5
5
|
const path = require('path');
|
|
6
|
+
const { git, getGitRoot } = require('./git-api');
|
|
6
7
|
|
|
7
8
|
const router = express.Router();
|
|
8
9
|
|
|
10
|
+
/**
|
|
11
|
+
* Read gitAutoCommit / gitAutoPush from the live config file.
|
|
12
|
+
* Returns defaults when the file cannot be read.
|
|
13
|
+
*/
|
|
14
|
+
function readGitConfig(req) {
|
|
15
|
+
const configPath = req.app.locals.configPath;
|
|
16
|
+
if (!configPath) return { autoCommit: false, autoPush: false };
|
|
17
|
+
try {
|
|
18
|
+
const cfg = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
19
|
+
return { autoCommit: !!cfg.gitAutoCommit, autoPush: !!cfg.gitAutoPush };
|
|
20
|
+
} catch {
|
|
21
|
+
return { autoCommit: false, autoPush: false };
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Auto-commit all changes in scriptDir if gitAutoCommit is enabled.
|
|
27
|
+
* Optionally pushes. Silent on errors (e.g. nothing to commit).
|
|
28
|
+
*/
|
|
29
|
+
async function maybeAutoCommit(req, message) {
|
|
30
|
+
const { autoCommit, autoPush } = readGitConfig(req);
|
|
31
|
+
if (!autoCommit) return;
|
|
32
|
+
const scriptDir = getRoot(req);
|
|
33
|
+
if (!scriptDir) return;
|
|
34
|
+
const gitRoot = await getGitRoot(scriptDir);
|
|
35
|
+
if (!gitRoot) return;
|
|
36
|
+
try {
|
|
37
|
+
const scriptDirRel = path.relative(gitRoot, scriptDir).replace(/\\/g, '/');
|
|
38
|
+
await git(['add', scriptDirRel + '/'], gitRoot);
|
|
39
|
+
await git(['commit', '-m', message], gitRoot);
|
|
40
|
+
if (autoPush) {
|
|
41
|
+
try { await git(['push', 'origin'], gitRoot, 60000); } catch { /* ignore push errors */ }
|
|
42
|
+
}
|
|
43
|
+
} catch { /* nothing to commit or other transient error — ignore */ }
|
|
44
|
+
}
|
|
45
|
+
|
|
9
46
|
/**
|
|
10
47
|
* Resolve a safe absolute path within the script root.
|
|
11
48
|
* Returns null if the resolved path escapes the root (traversal attempt).
|
|
@@ -158,6 +195,7 @@ router.use((req, res) => {
|
|
|
158
195
|
} else {
|
|
159
196
|
fs.unlinkSync(abs);
|
|
160
197
|
}
|
|
198
|
+
maybeAutoCommit(req, `delete ${filePath}`).catch(() => {});
|
|
161
199
|
return res.json({ ok: true });
|
|
162
200
|
} catch (err) {
|
|
163
201
|
if (err.code === 'ENOENT') return res.status(404).json({ error: 'Not found' });
|
|
@@ -194,6 +232,7 @@ router.use((req, res) => {
|
|
|
194
232
|
try {
|
|
195
233
|
fs.mkdirSync(path.dirname(absNew), { recursive: true });
|
|
196
234
|
fs.renameSync(abs, absNew);
|
|
235
|
+
maybeAutoCommit(req, `rename ${srcPath} \u2192 ${newName}`).catch(() => {});
|
|
197
236
|
return res.json({ ok: true, path: newName });
|
|
198
237
|
} catch (err) {
|
|
199
238
|
if (err.code === 'ENOENT') return res.status(404).json({ error: 'Not found' });
|
package/src/web/server.js
CHANGED
|
@@ -19,6 +19,8 @@ const { init: initAuth, authMiddleware, checkAuth, router: authRouter } = requir
|
|
|
19
19
|
const app = express();
|
|
20
20
|
app.use(express.json());
|
|
21
21
|
|
|
22
|
+
const SERVER_START_TIME = Date.now();
|
|
23
|
+
|
|
22
24
|
// Public auth routes — always accessible regardless of auth mode.
|
|
23
25
|
// Must be mounted BEFORE the auth middleware.
|
|
24
26
|
app.use('/she/auth', authRouter);
|
|
@@ -108,6 +110,7 @@ app.get('/she/status', (req, res) => {
|
|
|
108
110
|
const s = _getStats ? _getStats() : { scripts: 0, topics: 0 };
|
|
109
111
|
if (_latestNpmVersion) s.latestVersion = _latestNpmVersion;
|
|
110
112
|
s.dataDir = require('../lib/storage').STORAGE_ROOT;
|
|
113
|
+
s.startedAt = SERVER_START_TIME;
|
|
111
114
|
res.json(s);
|
|
112
115
|
});
|
|
113
116
|
|