@wendongfly/myhi 1.3.103 → 1.3.105
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/bin/myhi.js +25 -0
- package/dist/chat.html +33 -5
- package/dist/index.js +1 -1
- package/dist/index.min.js +1 -1
- package/package.json +1 -1
package/bin/myhi.js
CHANGED
|
@@ -11,6 +11,7 @@ const __dirname = dirname(__filename);
|
|
|
11
11
|
// 解析 -p / --port 参数
|
|
12
12
|
const args = process.argv.slice(2);
|
|
13
13
|
let cmd = null;
|
|
14
|
+
let httpOnlyFlag = null; // null=不改;true=切 HTTP-only;false=切回 HTTPS
|
|
14
15
|
for (let i = 0; i < args.length; i++) {
|
|
15
16
|
if ((args[i] === '-p' || args[i] === '--port') && args[i + 1]) {
|
|
16
17
|
process.env.PORT = args[i + 1];
|
|
@@ -18,6 +19,10 @@ for (let i = 0; i < args.length; i++) {
|
|
|
18
19
|
} else if (args[i].startsWith('--port=')) {
|
|
19
20
|
process.env.PORT = args[i].split('=')[1];
|
|
20
21
|
args.splice(i, 1); i--;
|
|
22
|
+
} else if (args[i] === '--http' || args[i] === '--no-https') {
|
|
23
|
+
httpOnlyFlag = true; args.splice(i, 1); i--;
|
|
24
|
+
} else if (args[i] === '--https') {
|
|
25
|
+
httpOnlyFlag = false; args.splice(i, 1); i--;
|
|
21
26
|
} else if (!cmd && !args[i].startsWith('-')) {
|
|
22
27
|
cmd = args[i];
|
|
23
28
|
}
|
|
@@ -39,6 +44,24 @@ if (cmd === '--version' || cmd === '-v' || cmd === 'version') {
|
|
|
39
44
|
const configDir = join(homedir(), '.myhi');
|
|
40
45
|
const pidFile = join(configDir, 'daemon.pid');
|
|
41
46
|
const logFile = join(configDir, 'daemon.log');
|
|
47
|
+
const configFile = join(configDir, 'config.json');
|
|
48
|
+
|
|
49
|
+
// --http / --https:持久化 HTTP-only 开关到 config.json,server 启动时读取(任何重启都保留,
|
|
50
|
+
// 不依赖环境变量从 daemon 往下传)。设完若没显式命令,就自动 restart 让它立刻生效。
|
|
51
|
+
if (httpOnlyFlag !== null) {
|
|
52
|
+
try {
|
|
53
|
+
mkdirSync(configDir, { recursive: true });
|
|
54
|
+
let cfg = {};
|
|
55
|
+
try { cfg = JSON.parse(readFileSync(configFile, 'utf8')); } catch {}
|
|
56
|
+
cfg.httpOnly = httpOnlyFlag;
|
|
57
|
+
writeFileSync(configFile, JSON.stringify(cfg, null, 2));
|
|
58
|
+
console.log(`[myhi] 已切换为 ${httpOnlyFlag ? 'HTTP(无 TLS,麦克风/摄像头等在非 localhost 会受限)' : 'HTTPS'} 模式`);
|
|
59
|
+
} catch (e) {
|
|
60
|
+
console.error('[myhi] 写入 config.json 失败:', e.message);
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
if (!cmd) cmd = 'restart'; // 无显式命令 → 切完直接重启使其生效
|
|
64
|
+
}
|
|
42
65
|
|
|
43
66
|
// ── 工具函数 ──────────────────────────────────────────────
|
|
44
67
|
|
|
@@ -585,6 +608,8 @@ myhi — 基于 Web 的终端共享工具 (${platform})
|
|
|
585
608
|
myhi start 前台启动服务器
|
|
586
609
|
myhi -p <port> 指定监听端口(默认 12300)
|
|
587
610
|
myhi -d 后台启动(日志写入 ${configPath}daemon.log)
|
|
611
|
+
myhi --http 切为纯 HTTP(无 TLS)并重启,持久生效
|
|
612
|
+
myhi --https 切回 HTTPS(默认)并重启
|
|
588
613
|
myhi stop 停止后台服务器
|
|
589
614
|
myhi restart 重启后台服务器
|
|
590
615
|
myhi status 查看运行状态
|
package/dist/chat.html
CHANGED
|
@@ -2622,15 +2622,43 @@
|
|
|
2622
2622
|
let _askQuestions = [];
|
|
2623
2623
|
let askMultiState = null; // { answers: [{question,label}|null] },下标与 _askQuestions 对齐
|
|
2624
2624
|
|
|
2625
|
+
// 解 \uXXXX / \n / \t 转义:有些网关把 AskUserQuestion input 用 ensure_ascii 序列化下发,
|
|
2626
|
+
// 文本里就是字面的反斜杠-u,直接 textContent 会显示成 优化...,这里解回真字符。
|
|
2627
|
+
function _decodeU(s) {
|
|
2628
|
+
if (typeof s !== 'string') return s;
|
|
2629
|
+
if (s.indexOf('\\u') < 0 && s.indexOf('\\n') < 0 && s.indexOf('\\t') < 0) return s;
|
|
2630
|
+
return s.replace(/\\u([0-9a-fA-F]{4})/g, (_, h) => String.fromCharCode(parseInt(h, 16)))
|
|
2631
|
+
.replace(/\\n/g, '\n').replace(/\\t/g, '\t');
|
|
2632
|
+
}
|
|
2633
|
+
// input 可能是对象,也可能是被整段序列化的 JSON 字符串(网关双重编码)→ 尽力还原成对象
|
|
2634
|
+
function _coerceAsk(v) {
|
|
2635
|
+
if (typeof v === 'string') {
|
|
2636
|
+
const t = v.trim();
|
|
2637
|
+
if (t[0] === '{' || t[0] === '[') { try { return JSON.parse(t); } catch {} }
|
|
2638
|
+
try { return JSON.parse(_decodeU(t)); } catch {}
|
|
2639
|
+
return { question: v };
|
|
2640
|
+
}
|
|
2641
|
+
return v || {};
|
|
2642
|
+
}
|
|
2625
2643
|
function _normalizeAsk(input) {
|
|
2626
|
-
|
|
2644
|
+
input = _coerceAsk(input);
|
|
2645
|
+
let q = input.questions || input.question;
|
|
2646
|
+
// question/questions 本身又是序列化 JSON 字符串时,再解一层
|
|
2647
|
+
if (typeof q === 'string' && (q.trim()[0] === '{' || q.trim()[0] === '[' || q.indexOf('\\u') >= 0)) {
|
|
2648
|
+
const p = _coerceAsk(q);
|
|
2649
|
+
if (p && (p.questions || p.options || Array.isArray(p))) q = p.questions || p;
|
|
2650
|
+
}
|
|
2627
2651
|
const list = Array.isArray(q)
|
|
2628
2652
|
? q
|
|
2629
|
-
: [{ question: (typeof q === 'string' ? q : '') ||
|
|
2653
|
+
: [{ question: (typeof q === 'string' ? q : '') || '请选择', options: input.options, header: input.header }];
|
|
2630
2654
|
return list.map((x) => ({
|
|
2631
|
-
question: x.question || x.text || '',
|
|
2632
|
-
options: x.options || x.choices || []
|
|
2633
|
-
|
|
2655
|
+
question: _decodeU(x.question || x.text || ''),
|
|
2656
|
+
options: (x.options || x.choices || []).map((o) =>
|
|
2657
|
+
(typeof o === 'string' || typeof o === 'number')
|
|
2658
|
+
? { label: _decodeU(String(o)) }
|
|
2659
|
+
: { ...o, label: _decodeU(o.label || o.value || ''), description: _decodeU(o.description || '') }
|
|
2660
|
+
),
|
|
2661
|
+
header: _decodeU(x.header),
|
|
2634
2662
|
}));
|
|
2635
2663
|
}
|
|
2636
2664
|
|