@modelzen/feishu-codex-bridge 0.3.12-test.0 → 0.3.12-test.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.
- package/dist/cli.js +132 -126
- package/dist/index.d.ts +3 -0
- package/dist/index.js +4 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -91,7 +91,10 @@ var paths = {
|
|
|
91
91
|
inboundDir: join(appDir, "inbound"),
|
|
92
92
|
/** daemon 内嵌 Web 控制台的发现文件 {port, token, pid}(0600,daemon 退出
|
|
93
93
|
* 清理)——`web` 子命令据此直接打开 daemon 控制台而不是再起只读副本。 */
|
|
94
|
-
webConsoleFile: join(appDir, "web-console.json")
|
|
94
|
+
webConsoleFile: join(appDir, "web-console.json"),
|
|
95
|
+
/** 稳定的 Web 控制台 token(0600,**不随进程退出清理**)——让重启 / 预览→daemon
|
|
96
|
+
* 切换后浏览器里那条带 token 的 URL 始终有效,不再 401。删此文件即轮换 token。 */
|
|
97
|
+
webTokenFile: join(appDir, "web-token")
|
|
95
98
|
};
|
|
96
99
|
|
|
97
100
|
// src/config/bots.ts
|
|
@@ -11886,6 +11889,7 @@ function createAdminService(deps = {}) {
|
|
|
11886
11889
|
return readRecentLogs({ maxBytes: opts?.maxBytes ?? 64 * 1024 });
|
|
11887
11890
|
},
|
|
11888
11891
|
registerBot(input2) {
|
|
11892
|
+
if (deps.readonlyPreview) throw new NotWiredYetError("\u2795 \u6DFB\u52A0\u673A\u5668\u4EBA");
|
|
11889
11893
|
return registerBotFromCredentials({
|
|
11890
11894
|
appId: input2.appId,
|
|
11891
11895
|
appSecret: input2.appSecret,
|
|
@@ -11954,6 +11958,7 @@ function createAdminService(deps = {}) {
|
|
|
11954
11958
|
};
|
|
11955
11959
|
},
|
|
11956
11960
|
async registerBotByQr(opts) {
|
|
11961
|
+
if (deps.readonlyPreview) throw new NotWiredYetError("\u2795 \u6DFB\u52A0\u673A\u5668\u4EBA");
|
|
11957
11962
|
let creds;
|
|
11958
11963
|
try {
|
|
11959
11964
|
creds = await startRegistration({ signal: opts.signal, onQr: opts.onQr, onStatus: opts.onStatus });
|
|
@@ -12167,7 +12172,7 @@ async function catalogEntryStatus(entry, defaultBackend) {
|
|
|
12167
12172
|
}
|
|
12168
12173
|
async function probeAllBackends() {
|
|
12169
12174
|
return Promise.all(
|
|
12170
|
-
|
|
12175
|
+
visibleCatalog().map((e) => e.id).map(async (id) => {
|
|
12171
12176
|
const backend = createBackend(id);
|
|
12172
12177
|
const probe = await backend.doctor({ force: true }).catch(() => void 0);
|
|
12173
12178
|
return {
|
|
@@ -12183,7 +12188,7 @@ async function probeAllBackends() {
|
|
|
12183
12188
|
);
|
|
12184
12189
|
}
|
|
12185
12190
|
function createReadonlyAdminService(deps = {}) {
|
|
12186
|
-
return createAdminService({ startDaemon: deps.startDaemon });
|
|
12191
|
+
return createAdminService({ startDaemon: deps.startDaemon, applyUpdate: deps.applyUpdate, readonlyPreview: true });
|
|
12187
12192
|
}
|
|
12188
12193
|
function isAlive(pid) {
|
|
12189
12194
|
try {
|
|
@@ -12195,6 +12200,7 @@ function isAlive(pid) {
|
|
|
12195
12200
|
}
|
|
12196
12201
|
|
|
12197
12202
|
// src/web/discovery.ts
|
|
12203
|
+
import { randomUUID as randomUUID6 } from "crypto";
|
|
12198
12204
|
import { mkdirSync as mkdirSync2, readFileSync as readFileSync5, unlinkSync, writeFileSync as writeFileSync2 } from "fs";
|
|
12199
12205
|
import { dirname as dirname12 } from "path";
|
|
12200
12206
|
function publishWebConsole(rec, file = paths.webConsoleFile) {
|
|
@@ -12225,6 +12231,25 @@ function clearWebConsole(file = paths.webConsoleFile) {
|
|
|
12225
12231
|
} catch {
|
|
12226
12232
|
}
|
|
12227
12233
|
}
|
|
12234
|
+
function stableWebConsoleToken(file = paths.webTokenFile) {
|
|
12235
|
+
try {
|
|
12236
|
+
const t = readFileSync5(file, "utf8").trim();
|
|
12237
|
+
if (t) return t;
|
|
12238
|
+
} catch {
|
|
12239
|
+
}
|
|
12240
|
+
const token = randomUUID6();
|
|
12241
|
+
try {
|
|
12242
|
+
mkdirSync2(dirname12(file), { recursive: true });
|
|
12243
|
+
try {
|
|
12244
|
+
unlinkSync(file);
|
|
12245
|
+
} catch {
|
|
12246
|
+
}
|
|
12247
|
+
writeFileSync2(file, `${token}
|
|
12248
|
+
`, { mode: 384 });
|
|
12249
|
+
} catch {
|
|
12250
|
+
}
|
|
12251
|
+
return token;
|
|
12252
|
+
}
|
|
12228
12253
|
function isAlive2(pid) {
|
|
12229
12254
|
try {
|
|
12230
12255
|
process.kill(pid, 0);
|
|
@@ -12347,7 +12372,7 @@ async function doRestart(phase) {
|
|
|
12347
12372
|
|
|
12348
12373
|
// src/web/server.ts
|
|
12349
12374
|
import { createServer } from "http";
|
|
12350
|
-
import { randomUUID as
|
|
12375
|
+
import { randomUUID as randomUUID7, timingSafeEqual } from "crypto";
|
|
12351
12376
|
import { mkdirSync as mkdirSync3, watch } from "fs";
|
|
12352
12377
|
import { open as open2, stat as stat5 } from "fs/promises";
|
|
12353
12378
|
import { join as join19 } from "path";
|
|
@@ -13377,7 +13402,7 @@ ${UI_PURE_JS}
|
|
|
13377
13402
|
bots.forEach(function (b) {
|
|
13378
13403
|
nav.appendChild(navItem({ icon: 'bot', label: botTitle(b), on: r.tab === 'bot' && r.botId === b.appId, dot: !!b.running, onClick: function () { go({ tab: 'bot', botId: b.appId }); } }));
|
|
13379
13404
|
});
|
|
13380
|
-
nav.appendChild(navItem({ icon: 'add', label: '\u6DFB\u52A0\u673A\u5668\u4EBA', add: true, onClick: function () {
|
|
13405
|
+
nav.appendChild(navItem({ icon: 'add', label: '\u6DFB\u52A0\u673A\u5668\u4EBA', add: true, onClick: function () { tryAddBot(); } }));
|
|
13381
13406
|
nav.appendChild(el('div', 'nav-sec', '\u914D\u7F6E'));
|
|
13382
13407
|
nav.appendChild(navItem({ icon: 'backend', label: '\u540E\u7AEF Agent', on: r.tab === 'backends', onClick: function () { go({ tab: 'backends' }); } }));
|
|
13383
13408
|
nav.appendChild(navItem({ icon: 'doctor', label: '\u5BBF\u4E3B\u673A\u4F53\u68C0', on: r.tab === 'doctor', onClick: function () { go({ tab: 'doctor' }); } }));
|
|
@@ -13405,7 +13430,7 @@ ${UI_PURE_JS}
|
|
|
13405
13430
|
act.textContent = '';
|
|
13406
13431
|
if (r.tab === 'overview' || r.tab === 'bot') {
|
|
13407
13432
|
var add = el('button', 'btn primary sm', '\u2795 \u6DFB\u52A0\u673A\u5668\u4EBA');
|
|
13408
|
-
add.onclick = function () {
|
|
13433
|
+
add.onclick = function () { tryAddBot(); };
|
|
13409
13434
|
act.appendChild(add);
|
|
13410
13435
|
}
|
|
13411
13436
|
}
|
|
@@ -13479,7 +13504,7 @@ ${UI_PURE_JS}
|
|
|
13479
13504
|
hero.appendChild(el('div', 'home-sub', '\u628A\u98DE\u4E66\u63A5\u5230\u672C\u673A\u7684 Codex / Claude \u2014\u2014 \u4E00\u4E2A\u7FA4\u4E00\u4E2A\u9879\u76EE\uFF0C@\u4E00\u53E5\u8BDD\u5C31\u5F00\u5E72\u3002\u591A\u673A\u5668\u4EBA\u3001\u591A\u540E\u7AEF\uFF0C\u5168\u7A0B\u8DD1\u5728\u4F60\u8FD9\u53F0\u673A\u5668\u4E0A\uFF0C\u79C1\u6709\u53EF\u63A7\u3002'));
|
|
13480
13505
|
var ctaRow = el('div', 'home-cta-row');
|
|
13481
13506
|
var primary = el('button', 'btn primary home-cta', hasBots ? '\u8FDB\u5165\u63A7\u5236\u53F0' : '\u2795 \u626B\u7801\u521B\u5EFA\u7B2C\u4E00\u4E2A\u673A\u5668\u4EBA');
|
|
13482
|
-
primary.onclick = function () { if (hasBots) go({ tab: 'overview' }); else
|
|
13507
|
+
primary.onclick = function () { if (hasBots) go({ tab: 'overview' }); else tryAddBot(); };
|
|
13483
13508
|
ctaRow.appendChild(primary);
|
|
13484
13509
|
if (hasBots) {
|
|
13485
13510
|
var sec = el('button', 'btn home-cta', '\u540E\u7AEF\u7BA1\u7406');
|
|
@@ -13930,6 +13955,10 @@ ${UI_PURE_JS}
|
|
|
13930
13955
|
} else {
|
|
13931
13956
|
var pb = el('button', 'btn sm primary', '\u25B6\uFE0F \u542F\u52A8'); pb.onclick = askStart; acts.appendChild(pb);
|
|
13932
13957
|
}
|
|
13958
|
+
// \u68C0\u67E5\u66F4\u65B0\u5165\u53E3\uFF1A\u59CB\u7EC8\u5728\uFF08\u4E0D\u7BA1\u8DD1\u6CA1\u8DD1\uFF09\u3002\u6CA1\u542F\u52A8\u65F6\u80FD\u505A\u7684\u5C31\u662F\u300C\u542F\u52A8\u300D+\u300C\u66F4\u65B0\u300D\u3002
|
|
13959
|
+
var ub = el('button', 'btn sm', '\u{1F504} \u68C0\u67E5\u66F4\u65B0'); ub.style.marginLeft = '6px';
|
|
13960
|
+
ub.onclick = function () { var bx = $('updateBody'); if (bx) { bx.textContent = '\u7248\u672C\u68C0\u67E5\u4E2D\u2026'; loadUpdate(bx); } toast('\u{1F504} \u6B63\u5728\u68C0\u67E5\u66F4\u65B0\u2026'); };
|
|
13961
|
+
acts.appendChild(ub);
|
|
13933
13962
|
}
|
|
13934
13963
|
var line = el('div', 'statline');
|
|
13935
13964
|
if (d.running) line.appendChild(el('span', 'tag green', '\u2705 \u8FD0\u884C\u4E2D' + (d.pid ? ' \xB7 pid ' + d.pid : '')));
|
|
@@ -14043,7 +14072,7 @@ ${UI_PURE_JS}
|
|
|
14043
14072
|
hero.appendChild(el('div', 'fr-title', '\u6B22\u8FCE\uFF01\u8FD8\u5DEE\u6700\u540E\u4E00\u6B65\uFF1A\u521B\u5EFA\u4F60\u7684\u7B2C\u4E00\u4E2A\u98DE\u4E66\u673A\u5668\u4EBA'));
|
|
14044
14073
|
hero.appendChild(el('div', 'fr-sub', '\u70B9\u4E0B\u9762\u7684\u6309\u94AE\uFF0C\u7528\u98DE\u4E66\u626B\u7801\u5373\u53EF\u521B\u5EFA\u5E76\u6388\u6743\u2014\u2014\u5168\u7A0B\u5728\u8FD9\u4E2A\u7F51\u9875\u91CC\u5B8C\u6210\uFF0C\u4E0D\u7528\u78B0\u7EC8\u7AEF\u3002'));
|
|
14045
14074
|
var cta = el('button', 'btn primary fr-cta', '\u2795 \u626B\u7801\u521B\u5EFA\u7B2C\u4E00\u4E2A\u673A\u5668\u4EBA');
|
|
14046
|
-
cta.onclick = function () {
|
|
14075
|
+
cta.onclick = function () { tryAddBot(); };
|
|
14047
14076
|
hero.appendChild(cta);
|
|
14048
14077
|
box.appendChild(hero);
|
|
14049
14078
|
if (countEl) countEl.textContent = '';
|
|
@@ -14368,7 +14397,7 @@ ${UI_PURE_JS}
|
|
|
14368
14397
|
box.textContent = '';
|
|
14369
14398
|
box.className = 'note';
|
|
14370
14399
|
if (!diag) return;
|
|
14371
|
-
box.appendChild(el('div', null, '\u4E8B\u4EF6\u8BA2\u9605\uFF1A
|
|
14400
|
+
box.appendChild(el('div', null, '\u2139\uFE0F \u4E8B\u4EF6\u8BA2\u9605\uFF1A\u8BF7\u81EA\u884C\u5230\u300C\u4E8B\u4EF6\u4E0E\u56DE\u8C03\u300D\u786E\u8BA4\u5DF2\u8BA2\u9605 im.message.receive_v1\uFF08\u957F\u8FDE\u63A5\uFF09\uFF1B\u6B64\u9879\u7CFB\u7EDF\u65E0\u6CD5\u53EF\u9760\u68C0\u6D4B\uFF0C\u4EC5\u4F5C\u63D0\u9192\u3002'));
|
|
14372
14401
|
var title = el('div', null, '\u{1F9E0} \u540E\u7AEF\u73AF\u5883\uFF1A');
|
|
14373
14402
|
title.style.marginTop = '6px';
|
|
14374
14403
|
box.appendChild(title);
|
|
@@ -14553,9 +14582,27 @@ ${UI_PURE_JS}
|
|
|
14553
14582
|
var wizEs = null; // \u626B\u7801 SSE EventSource
|
|
14554
14583
|
var wizQrSessionId = null;
|
|
14555
14584
|
var wizCountdown = null; // \u4E8C\u7EF4\u7801\u8FC7\u671F\u5012\u8BA1\u65F6
|
|
14585
|
+
var wizAutoEnabled = false; // \u65B0 bot \u662F\u5426\u5DF2\u81EA\u52A8\u52A0\u5165\u6D3B\u8DC3\u96C6\uFF08\u4E00\u6B21\u6027\uFF09
|
|
14586
|
+
var wizRestartPrompted = false; // \u5B8C\u6210\u6B65\u662F\u5426\u5DF2\u5F39\u8FC7\u300C\u91CD\u542F\u62C9\u8D77\u300D\u786E\u8BA4\uFF08\u4E00\u6B21\u6027\uFF09
|
|
14587
|
+
|
|
14588
|
+
// \u6DFB\u52A0\u673A\u5668\u4EBA\u662F\u5199\u64CD\u4F5C\uFF1AFeishu Bridge \u6CA1\u5728\u8DD1\u65F6\u63A7\u5236\u53F0\u4E3A\u53EA\u8BFB\uFF0C\u4E0D\u80FD\u52A0\uFF08\u4E0E\u300C\u6CA1\u542F\u52A8\u53EA\u8BFB\u300D\u4E00\u81F4\uFF09\u3002
|
|
14589
|
+
// \u6CA1\u5728\u8DD1\u5C31\u5F15\u5BFC\u5148\u542F\u52A8\uFF0C\u800C\u4E0D\u662F\u6253\u5F00\u5411\u5BFC\u8BA9\u7528\u6237\u767D\u586B\u4E00\u901A\u518D\u88AB 501 \u6321\u56DE\u3002
|
|
14590
|
+
function tryAddBot() {
|
|
14591
|
+
if (daemon && daemon.running) { openWizard(); return; }
|
|
14592
|
+
confirmDialog({
|
|
14593
|
+
title: '\u9700\u8981\u5148\u542F\u52A8 Feishu Bridge',
|
|
14594
|
+
lines: [
|
|
14595
|
+
'Feishu Bridge \u672A\u5728\u8FD0\u884C\u65F6\u63A7\u5236\u53F0\u4E3A\u53EA\u8BFB\uFF0C\u65E0\u6CD5\u6DFB\u52A0\u673A\u5668\u4EBA\u3002',
|
|
14596
|
+
'\u5148\u542F\u52A8 Feishu Bridge\uFF0C\u518D\u56DE\u6765\u6DFB\u52A0\u3002',
|
|
14597
|
+
],
|
|
14598
|
+
confirmLabel: '\u7ACB\u5373\u542F\u52A8',
|
|
14599
|
+
onConfirm: function () { postAction('/api/daemon/start', '\u542F\u52A8'); },
|
|
14600
|
+
});
|
|
14601
|
+
}
|
|
14556
14602
|
|
|
14557
14603
|
function openWizard() {
|
|
14558
14604
|
wizStep = 1; wizBotId = null; wizSetup = null; wizManualOpen = false;
|
|
14605
|
+
wizAutoEnabled = false; wizRestartPrompted = false;
|
|
14559
14606
|
stopWizPoll(); stopWizQr();
|
|
14560
14607
|
$('wizMask').classList.add('open');
|
|
14561
14608
|
renderWizard();
|
|
@@ -14605,6 +14652,11 @@ ${UI_PURE_JS}
|
|
|
14605
14652
|
qrWrap.appendChild(el('div', 'note', '\u6B63\u5728\u751F\u6210\u4E8C\u7EF4\u7801\u2026'));
|
|
14606
14653
|
w.appendChild(qrWrap);
|
|
14607
14654
|
|
|
14655
|
+
var steps = el('div', 'note');
|
|
14656
|
+
steps.style.cssText = 'margin-top:6px;line-height:1.7';
|
|
14657
|
+
steps.textContent = '\u2460 \u7528\u98DE\u4E66 App \u626B\u7801 \u2192 \u2461 \u5728\u98DE\u4E66\u91CC\u70B9\u300C\u521B\u5EFA\u5E76\u6388\u6743\u300D \u2192 \u2462 \u56DE\u5230\u672C\u9875\uFF08\u65E0\u9700\u624B\u52A8\u5237\u65B0\uFF09\uFF0C\u521B\u5EFA\u6210\u529F\u4F1A\u81EA\u52A8\u8FDB\u5165\u7B2C\u2461\u6B65\u300C\u63A5\u5165\u68C0\u6D4B\u300D\u3002';
|
|
14658
|
+
w.appendChild(steps);
|
|
14659
|
+
|
|
14608
14660
|
var statusLine = el('div', 'note'); statusLine.id = 'wizScanStatus';
|
|
14609
14661
|
statusLine.style.textAlign = 'center';
|
|
14610
14662
|
w.appendChild(statusLine);
|
|
@@ -14773,12 +14825,21 @@ ${UI_PURE_JS}
|
|
|
14773
14825
|
function startWizPoll() { stopWizPoll(); pollWizSetup(); wizPoll = setInterval(pollWizSetup, 5000); }
|
|
14774
14826
|
function pollWizSetup() {
|
|
14775
14827
|
if (!wizBotId) return;
|
|
14828
|
+
// \u65B0 bot \u9ED8\u8BA4\u5C31\u52A0\u5165\u6D3B\u8DC3\u96C6\u2014\u2014\u7528\u6237\u4E0D\u5FC5\u624B\u52A8\u70B9\u6309\u94AE / \u8DD1 bot use\u3002\u4E00\u6B21\u6027\uFF1B\u5931\u8D25\u4E0B\u5468\u671F\u91CD\u8BD5\u3002
|
|
14829
|
+
// \u771F\u6B63\u300C\u62C9\u8D77\u4E0A\u7EBF\u300D\u8981\u91CD\u542F Feishu Bridge\uFF0C\u90A3\u4E00\u6B65\u7559\u5230\u300C\u5B8C\u6210\u300D\u65F6\u5F39\u7A97\u786E\u8BA4\uFF08\u91CD\u542F\u4F1A\u77ED\u6682
|
|
14830
|
+
// \u5F71\u54CD\u5176\u5B83\u5728\u7EBF bot\uFF0C\u6240\u4EE5\u4E0D\u9759\u9ED8\u91CD\u542F\uFF09\u3002
|
|
14831
|
+
if (!wizAutoEnabled) {
|
|
14832
|
+
wizAutoEnabled = true;
|
|
14833
|
+
fetch('/api/bots/' + encodeURIComponent(wizBotId), {
|
|
14834
|
+
method: 'PATCH', headers: { 'Content-Type': 'application/json' },
|
|
14835
|
+
body: JSON.stringify({ enabled: true }),
|
|
14836
|
+
}).catch(function () { wizAutoEnabled = false; });
|
|
14837
|
+
}
|
|
14776
14838
|
fetch('/api/bots/' + encodeURIComponent(wizBotId) + '/setup-status')
|
|
14777
14839
|
.then(function (r) { return r.json(); })
|
|
14778
14840
|
.then(function (s) {
|
|
14779
14841
|
wizSetup = s;
|
|
14780
14842
|
if (wizStep === 2) renderWizChecklist();
|
|
14781
|
-
if (s.event && s.event.state === 'ok') stopWizPoll();
|
|
14782
14843
|
})
|
|
14783
14844
|
.catch(function () { /* \u4E0B\u4E2A\u5468\u671F\u91CD\u8BD5 */ });
|
|
14784
14845
|
}
|
|
@@ -14805,7 +14866,7 @@ ${UI_PURE_JS}
|
|
|
14805
14866
|
var s = wizSetup;
|
|
14806
14867
|
if (!s || !s.credentials) {
|
|
14807
14868
|
w.appendChild(checkItem('spin', '\u6B63\u5728\u68C0\u6D4B\u2026', '\u9996\u6B21\u62C9\u53D6\u7EA6 2~3 \u79D2'));
|
|
14808
|
-
w.appendChild(wizChecklistActions(
|
|
14869
|
+
w.appendChild(wizChecklistActions());
|
|
14809
14870
|
return;
|
|
14810
14871
|
}
|
|
14811
14872
|
w.appendChild(checkItem(
|
|
@@ -14827,89 +14888,31 @@ ${UI_PURE_JS}
|
|
|
14827
14888
|
w.appendChild(checkItem('\u26A0\uFE0F', '\u7F3A ' + miss.length + ' \u9879\u5FC5\u9700\u6743\u9650', miss.join('\u3001'), grant));
|
|
14828
14889
|
}
|
|
14829
14890
|
}
|
|
14830
|
-
|
|
14831
|
-
|
|
14832
|
-
|
|
14833
|
-
|
|
14834
|
-
|
|
14835
|
-
|
|
14836
|
-
|
|
14837
|
-
|
|
14838
|
-
|
|
14839
|
-
|
|
14840
|
-
|
|
14841
|
-
cmd.appendChild(act);
|
|
14842
|
-
cmd.appendChild(el('div', 'note', '\u4E00\u952E\uFF1A\u628A\u5B83\u52A0\u5165\u6D3B\u8DC3\u96C6\u5E76\u81EA\u52A8'
|
|
14843
|
-
+ ((daemon && daemon.running) ? '\u91CD\u542F' : '\u542F\u52A8') + ' Feishu Bridge'
|
|
14844
|
-
+ ((daemon && daemon.running) ? '\uFF08\u7EA6\u6570\u79D2\uFF0C\u5176\u5B83\u5728\u7EBF\u673A\u5668\u4EBA\u4F1A\u77ED\u6682\u65AD\u8FDE\u540E\u81EA\u52A8\u91CD\u8FDE\uFF09' : '') + '\u3002'));
|
|
14845
|
-
cmd.appendChild(el('div', 'note', '\u6216\u624B\u52A8\u5728\u7EC8\u7AEF\u6267\u884C\uFF1A'));
|
|
14846
|
-
cmd.appendChild(copyRow('feishu-codex-bridge bot use ' + (wizBotId || '<appId>')));
|
|
14847
|
-
cmd.appendChild(copyRow('feishu-codex-bridge start'));
|
|
14848
|
-
w.appendChild(checkItem('\u{1F7E0}', '\u957F\u8FDE\u63A5\u672A\u5EFA\u7ACB', '\u9700\u8981 Feishu Bridge \u62C9\u8D77\u8FD9\u4E2A bot', cmd));
|
|
14849
|
-
}
|
|
14850
|
-
var ev = s.event || { state: 'unchecked' };
|
|
14851
|
-
if (ev.state === 'ok') {
|
|
14852
|
-
w.appendChild(checkItem('\u2705', '\u4E8B\u4EF6\u8BA2\u9605\u5DF2\u751F\u6548', eventDiagText(ev)));
|
|
14853
|
-
} else {
|
|
14854
|
-
var evExtra = el('div');
|
|
14855
|
-
evExtra.appendChild(el('div', 'note', ev.state === 'unchecked'
|
|
14856
|
-
? '\uFF08\u7F3A application:app_version \u53EA\u8BFB scope \u6216\u7F51\u7EDC\u4E0D\u901A\u65F6\u65E0\u6CD5\u81EA\u52A8\u68C0\u6D4B\uFF1B\u6309\u4E0B\u65B9\u6DF1\u94FE\u624B\u52A8\u6838\u5BF9\u300C\u4E8B\u4EF6\u914D\u7F6E\u300D\u3002\uFF09'
|
|
14857
|
-
: '\u53BB\u5F00\u53D1\u8005\u540E\u53F0\u300C\u4E8B\u4EF6\u4E0E\u56DE\u8C03\u300D\uFF1A\u4E8B\u4EF6\u914D\u7F6E\u6539\u300C\u957F\u8FDE\u63A5\u300D\u2192 \u6DFB\u52A0 im.message.receive_v1 \u2192 \u5E94\u7528\u53D1\u5E03\u91CC\u521B\u5EFA\u5E76\u53D1\u5E03\u7248\u672C\u3002'));
|
|
14858
|
-
var ea = el('a', null, '\u6253\u5F00\u300C\u4E8B\u4EF6\u4E0E\u56DE\u8C03\u300D\u914D\u7F6E\u9875 \u2197');
|
|
14859
|
-
ea.href = s.eventConfigUrl; ea.target = '_blank'; ea.rel = 'noopener';
|
|
14860
|
-
evExtra.appendChild(ea);
|
|
14861
|
-
evExtra.appendChild(el('div', 'note', '\u914D\u7F6E\u597D\u540E\u65E0\u9700\u624B\u52A8\u5237\u65B0\u2014\u2014\u672C\u9875\u6BCF 5 \u79D2\u81EA\u52A8\u590D\u68C0\uFF0C\u751F\u6548\u4F1A\u53D8 \u2705\u3002'));
|
|
14862
|
-
w.appendChild(checkItem(ev.state === 'unchecked' ? '\u26A0\uFE0F' : 'spin',
|
|
14863
|
-
ev.state === 'unchecked' ? '\u4E8B\u4EF6\u8BA2\u9605\u672A\u80FD\u81EA\u52A8\u68C0\u6D4B' : '\u4E8B\u4EF6\u8BA2\u9605\u5C1A\u672A\u751F\u6548',
|
|
14864
|
-
eventDiagText(ev), evExtra));
|
|
14865
|
-
}
|
|
14866
|
-
w.appendChild(wizChecklistActions(ev.state === 'ok'));
|
|
14891
|
+
// \u300C\u52A0\u5165\u6D3B\u8DC3\u96C6 + \u62C9\u8D77\u4E0A\u7EBF\u300D\u5168\u7A0B\u9759\u9ED8\uFF1A\u65B0 bot \u5DF2\u5728 pollWizSetup \u81EA\u52A8\u52A0\u5165\u6D3B\u8DC3\u96C6\uFF0C\u771F\u6B63\u62C9\u8D77
|
|
14892
|
+
// \u9760\u6700\u540E\u4E00\u6B65\u300C\u5B8C\u6210\u300D\u5F39\u7A97\u786E\u8BA4\u91CD\u542F\u2014\u2014\u8FD9\u91CC\u4E0D\u518D\u663E\u793A\u300C\u5F85\u62C9\u8D77\u4E0A\u7EBF\u300D\u4E4B\u7C7B\u7684\u4E2D\u95F4\u6001\u9879\u3002
|
|
14893
|
+
// \u4E8B\u4EF6\u8BA2\u9605\uFF1A\u7CFB\u7EDF\u65E0\u6CD5\u53EF\u9760\u68C0\u6D4B\uFF08\u957F\u8FDE\u63A5\u8BA2\u9605\u5728\u5DF2\u53D1\u5E03\u7248\u672C\u91CC\u7684\u4F53\u73B0\u4E0D\u7A33\u5B9A\uFF09\uFF0C\u6545\u53EA\u505A\u63D0\u9192\u3001\u4E0D\u4E0B\u7ED3\u8BBA\u3001
|
|
14894
|
+
// \u4E0D\u963B\u585E\u300C\u4E0B\u4E00\u6B65\u300D\u3002\u7528\u6237\u81EA\u884C\u53BB\u540E\u53F0\u6838\u5BF9\u3002
|
|
14895
|
+
var evHint = el('div');
|
|
14896
|
+
var ea = el('a', null, '\u6253\u5F00\u300C\u4E8B\u4EF6\u4E0E\u56DE\u8C03\u300D\u914D\u7F6E\u9875 \u2197');
|
|
14897
|
+
ea.href = (s.eventConfigUrl || '#'); ea.target = '_blank'; ea.rel = 'noopener';
|
|
14898
|
+
evHint.appendChild(ea);
|
|
14899
|
+
w.appendChild(checkItem('\u2139\uFE0F', '\u4E8B\u4EF6\u8BA2\u9605\uFF08\u8BF7\u81EA\u884C\u786E\u8BA4\uFF09',
|
|
14900
|
+
'\u8BF7\u5230\u300C\u4E8B\u4EF6\u4E0E\u56DE\u8C03\u300D\u786E\u8BA4\u5DF2\u8BA2\u9605 im.message.receive_v1\uFF08\u957F\u8FDE\u63A5\u6A21\u5F0F\uFF09\u5E76\u5DF2\u53D1\u5E03\u7248\u672C\uFF0C\u5426\u5219 @\u673A\u5668\u4EBA\u4E0D\u4F1A\u6709\u53CD\u5E94\u3002\u6B64\u9879\u7CFB\u7EDF\u65E0\u6CD5\u53EF\u9760\u68C0\u6D4B\uFF0C\u4EC5\u4F5C\u63D0\u9192\u3002', evHint));
|
|
14901
|
+
w.appendChild(wizChecklistActions());
|
|
14867
14902
|
}
|
|
14868
14903
|
|
|
14869
|
-
function wizChecklistActions(
|
|
14904
|
+
function wizChecklistActions() {
|
|
14870
14905
|
var actions = el('div', 'actions');
|
|
14871
14906
|
var back = el('button', 'btn', '\u7A0D\u540E\u518D\u8BF4');
|
|
14872
14907
|
back.onclick = closeWizard;
|
|
14873
14908
|
actions.appendChild(back);
|
|
14874
14909
|
actions.appendChild(el('div', 'grow'));
|
|
14875
|
-
var next = el('button', 'btn
|
|
14876
|
-
|
|
14877
|
-
else { next.className = 'btn disabled'; next.disabled = true; }
|
|
14910
|
+
var next = el('button', 'btn primary', '\u4E0B\u4E00\u6B65');
|
|
14911
|
+
next.onclick = function () { wizStep = 3; stopWizPoll(); renderWizard(); };
|
|
14878
14912
|
actions.appendChild(next);
|
|
14879
14913
|
return actions;
|
|
14880
14914
|
}
|
|
14881
14915
|
|
|
14882
|
-
// \u300C\u957F\u8FDE\u63A5\u672A\u5EFA\u7ACB\u300D\u4E00\u952E\uFF1A\u542F\u7528\uFF08\u52A0\u5165\u6D3B\u8DC3\u96C6\uFF09\u2192 daemon \u5728\u8DD1\u5C31\u786E\u8BA4\u91CD\u542F\u3001\u6CA1\u8DD1\u5C31\u76F4\u63A5\u542F\u52A8\uFF0C
|
|
14883
|
-
// \u7701\u53BB\u7EC8\u7AEF bot use + start\u3002\u590D\u7528 confirmDialog / postAction\uFF0C\u4E0E\u4EEA\u8868\u76D8\u91CD\u542F\u540C\u4E00\u5957\u3002
|
|
14884
|
-
function wizEnableAndLaunch() {
|
|
14885
|
-
if (!wizBotId) { toast('\u274C \u7F3A\u5C11\u673A\u5668\u4EBA ID'); return; }
|
|
14886
|
-
var who = (wizSetup && wizSetup.botName) || wizBotId;
|
|
14887
|
-
fetch('/api/bots/' + encodeURIComponent(wizBotId), {
|
|
14888
|
-
method: 'PATCH', headers: { 'Content-Type': 'application/json' },
|
|
14889
|
-
body: JSON.stringify({ enabled: true }),
|
|
14890
|
-
}).then(function (r) { return r.json().then(function (j) { return { status: r.status, body: j }; }); })
|
|
14891
|
-
.then(function (resp) {
|
|
14892
|
-
if (resp.status !== 200) { toast('\u274C ' + (resp.body.message || ('HTTP ' + resp.status))); return; }
|
|
14893
|
-
toast('\u2705 \u5DF2\u52A0\u5165\u6D3B\u8DC3\u96C6');
|
|
14894
|
-
if (daemon && daemon.running) {
|
|
14895
|
-
confirmDialog({
|
|
14896
|
-
title: '\u{1F504} \u7ACB\u5373\u91CD\u542F Feishu Bridge \u62C9\u8D77\u300C' + who + '\u300D\uFF1F',
|
|
14897
|
-
lines: [
|
|
14898
|
-
'\u5DF2\u52A0\u5165\u6D3B\u8DC3\u96C6\uFF0C\u91CD\u542F\u540E\u5373\u53EF\u4E0A\u7EBF\u3002',
|
|
14899
|
-
'\u91CD\u542F\u7EA6\u6570\u79D2\uFF0C\u671F\u95F4\u6240\u6709\u5728\u7EBF\u673A\u5668\u4EBA\u7684\u957F\u8FDE\u63A5\u4F1A\u77ED\u6682\u65AD\u5F00\u5E76\u81EA\u52A8\u91CD\u8FDE\u3002',
|
|
14900
|
-
],
|
|
14901
|
-
confirmLabel: '\u7ACB\u5373\u91CD\u542F',
|
|
14902
|
-
onConfirm: function () { postAction('/api/daemon/restart', '\u91CD\u542F'); },
|
|
14903
|
-
});
|
|
14904
|
-
} else {
|
|
14905
|
-
// daemon \u6CA1\u5728\u8DD1\uFF08\u53EA\u8BFB\u9884\u89C8\uFF09\u2192 \u542F\u52A8\u5B83\uFF08read-only preview \u6CE8\u5165\u4E86 startDaemon\uFF09\uFF1B
|
|
14906
|
-
// \u8D77\u6765\u540E /api/console/live \u8F6E\u8BE2\u4F1A\u628A\u9875\u9762\u81EA\u52A8\u5E26\u53BB\u53EF\u5199\u63A7\u5236\u53F0\u3002
|
|
14907
|
-
postAction('/api/daemon/start', '\u542F\u52A8');
|
|
14908
|
-
}
|
|
14909
|
-
})
|
|
14910
|
-
.catch(function () { toast('\u274C \u8BF7\u6C42\u5931\u8D25'); });
|
|
14911
|
-
}
|
|
14912
|
-
|
|
14913
14916
|
function copyRow(text) {
|
|
14914
14917
|
var row = el('div', 'copybox');
|
|
14915
14918
|
row.appendChild(el('code', null, text));
|
|
@@ -14930,33 +14933,20 @@ ${UI_PURE_JS}
|
|
|
14930
14933
|
w.textContent = '';
|
|
14931
14934
|
w.appendChild(el('h3', null, '\u{1F389} \u63A5\u5165\u5B8C\u6210'));
|
|
14932
14935
|
w.appendChild(wizStepBar(3));
|
|
14933
|
-
|
|
14934
|
-
|
|
14935
|
-
|
|
14936
|
-
|
|
14937
|
-
|
|
14938
|
-
|
|
14939
|
-
].forEach(function (line) {
|
|
14940
|
-
var d = el('div'); d.style.padding = '4px 0'; d.textContent = line;
|
|
14941
|
-
ul.appendChild(d);
|
|
14942
|
-
});
|
|
14943
|
-
w.appendChild(ul);
|
|
14944
|
-
w.appendChild(el('div', 'note', '\u63D0\u793A\uFF1A\u79C1\u804A\u673A\u5668\u4EBA\u53D1\u4EFB\u610F\u6D88\u606F\u5373\u53EF\u5524\u51FA\u79C1\u804A\u7BA1\u7406\u53F0\uFF1BWeb \u63A7\u5236\u53F0\u4E0E\u79C1\u804A\u5361\u7247\u5171\u4EAB\u540C\u4E00\u5957\u8BBE\u7F6E\uFF0C\u53CC\u7AEF\u5B9E\u65F6\u4E00\u81F4\u3002'));
|
|
14945
|
-
// \u65B0\u5EFA\u7684\u673A\u5668\u4EBA\u8981\u7B49 daemon \u91CD\u542F\u3001\u88AB supervisor \u63A5\u7BA1\u540E\u624D\u771F\u6B63\u4E0A\u7EBF\uFF08\u5C24\u5176\u300C\u5F15\u5BFC\u63A7\u5236\u53F0\u300D\u662F
|
|
14946
|
-
// \u96F6 bot \u8D77\u7684\uFF0C\u5F97\u91CD\u542F\u624D\u4F1A\u8FDE\u4E0A\u8FD9\u4E2A\u65B0 bot\uFF09\u3002\u7ED9\u4E00\u6761\u9192\u76EE\u63D0\u793A + \u4E00\u952E\u91CD\u542F\uFF08\u786E\u8BA4\u5F39\u7A97\u91CC\u4F1A\u8BF4\u660E
|
|
14947
|
-
// \u91CD\u542F\u4F1A\u77ED\u6682\u6253\u65AD\u5176\u5B83\u5728\u8DD1\u7684\u673A\u5668\u4EBA\uFF09\u3002
|
|
14948
|
-
var liveTip = el('div', 'note');
|
|
14949
|
-
liveTip.style.cssText = 'margin-top:10px;padding:10px 12px;background:var(--blue-tint);border-radius:8px;color:var(--text-2)';
|
|
14950
|
-
liveTip.textContent = '\u26A1 \u8BA9\u5B83\u4E0A\u7EBF\uFF1A\u65B0\u673A\u5668\u4EBA\u9700\u91CD\u542F Feishu Bridge \u540E\u7531\u540E\u53F0\u63A5\u7BA1\u3002\u70B9\u4E0B\u9762\u300C\u91CD\u542F\u4F7F\u5176\u4E0A\u7EBF\u300D\u5373\u53EF\uFF08\u9996\u6B21\u521B\u5EFA\u65F6\u91CD\u542F\u5F88\u5B89\u5168\uFF0C\u4E0D\u5F71\u54CD\u522B\u7684\u673A\u5668\u4EBA\uFF09\u3002';
|
|
14951
|
-
w.appendChild(liveTip);
|
|
14936
|
+
var who = (wizSetup && wizSetup.botName) || wizBotId || '';
|
|
14937
|
+
// \u5230\u8FD9\u4E00\u6B65\u53EA\u5269\u4E00\u4EF6\u4E8B\uFF1A\u91CD\u542F Feishu Bridge \u8BA9\u65B0 bot \u4E0A\u7EBF\u3002\u4E0D\u518D\u5806\u300C\u65B0\u5EFA\u9879\u76EE/\u62C9\u7FA4/@\u300D\u90A3\u5957
|
|
14938
|
+
// \u5F15\u5BFC\uFF08\u90A3\u4F1A\u8BA9\u4EBA\u4EE5\u4E3A\u5F97\u5148\u505A\u5B8C\u624D\u80FD\u7EE7\u7EED\uFF09\u3002\u91CD\u542F\u5165\u53E3**\u53EA\u6B64\u4E00\u5904**\uFF1A\u4E3B\u6309\u94AE\u300C\u91CD\u542F\u4F7F\u5176\u4E0A\u7EBF\u300D\uFF1B
|
|
14939
|
+
// \u60F3\u665A\u70B9\u518D\u8BF4\u5C31\u70B9\u300C\u7A0D\u540E\u518D\u91CD\u542F\u300D\u3002
|
|
14940
|
+
w.appendChild(el('div', 'note', '\u673A\u5668\u4EBA\u300C' + who + '\u300D\u5DF2\u52A0\u5165\u6D3B\u8DC3\u96C6\u3002\u6700\u540E\u4E00\u6B65\uFF1A\u91CD\u542F Feishu Bridge \u8BA9\u5B83\u4E0A\u7EBF\uFF08\u7EA6\u6570\u79D2\uFF0C\u5176\u5B83\u5728\u7EBF\u673A\u5668\u4EBA\u4F1A\u77ED\u6682\u65AD\u8FDE\u540E\u81EA\u52A8\u91CD\u8FDE\uFF09\u3002'));
|
|
14941
|
+
var gotoBot = function () { var id = wizBotId; closeWizard(); if (id) go({ tab: 'bot', botId: id }); };
|
|
14952
14942
|
var actions = el('div', 'actions');
|
|
14953
|
-
var
|
|
14954
|
-
|
|
14955
|
-
actions.appendChild(
|
|
14943
|
+
var later = el('button', 'btn', '\u7A0D\u540E\u518D\u91CD\u542F');
|
|
14944
|
+
later.onclick = gotoBot;
|
|
14945
|
+
actions.appendChild(later);
|
|
14956
14946
|
actions.appendChild(el('div', 'grow'));
|
|
14957
|
-
var
|
|
14958
|
-
|
|
14959
|
-
actions.appendChild(
|
|
14947
|
+
var restart = el('button', 'btn primary', '\u{1F501} \u91CD\u542F\u4F7F\u5176\u4E0A\u7EBF');
|
|
14948
|
+
restart.onclick = function () { postAction('/api/daemon/restart', '\u91CD\u542F'); gotoBot(); };
|
|
14949
|
+
actions.appendChild(restart);
|
|
14960
14950
|
w.appendChild(actions);
|
|
14961
14951
|
}
|
|
14962
14952
|
|
|
@@ -15037,7 +15027,7 @@ var DEFAULT_WEB_PORT = 51847;
|
|
|
15037
15027
|
var COOKIE_NAME = "fcb_console_token";
|
|
15038
15028
|
var SSE_INITIAL_TAIL_BYTES = 16 * 1024;
|
|
15039
15029
|
function createWebServer(opts) {
|
|
15040
|
-
const token = opts.token ??
|
|
15030
|
+
const token = opts.token ?? randomUUID7();
|
|
15041
15031
|
const html = opts.html ?? UI_HTML;
|
|
15042
15032
|
const logDir = opts.logDir ?? join19(paths.appDir, "logs");
|
|
15043
15033
|
const sseCleanups = /* @__PURE__ */ new Set();
|
|
@@ -15360,7 +15350,16 @@ function createWebServer(opts) {
|
|
|
15360
15350
|
const appSecret = typeof body.appSecret === "string" ? body.appSecret : "";
|
|
15361
15351
|
const tenant = body.tenant === "lark" ? "lark" : "feishu";
|
|
15362
15352
|
const desiredName = typeof body.name === "string" && body.name.trim() ? body.name.trim() : void 0;
|
|
15363
|
-
|
|
15353
|
+
let result;
|
|
15354
|
+
try {
|
|
15355
|
+
result = await opts.service.registerBot({ appId, appSecret, tenant, desiredName });
|
|
15356
|
+
} catch (err) {
|
|
15357
|
+
if (err instanceof NotWiredYetError) {
|
|
15358
|
+
sendJson(res, 501, { error: "not_wired_yet", message: err.message });
|
|
15359
|
+
return;
|
|
15360
|
+
}
|
|
15361
|
+
throw err;
|
|
15362
|
+
}
|
|
15364
15363
|
if (result.ok) {
|
|
15365
15364
|
sendJson(res, 201, {
|
|
15366
15365
|
ok: true,
|
|
@@ -15380,7 +15379,7 @@ function createWebServer(opts) {
|
|
|
15380
15379
|
function handleRegisterQrStream(req, res) {
|
|
15381
15380
|
qrSession?.abort.abort();
|
|
15382
15381
|
const abort = new AbortController();
|
|
15383
|
-
const session = { id:
|
|
15382
|
+
const session = { id: randomUUID7(), abort };
|
|
15384
15383
|
qrSession = session;
|
|
15385
15384
|
res.writeHead(200, {
|
|
15386
15385
|
"Content-Type": "text/event-stream",
|
|
@@ -15657,23 +15656,27 @@ async function readJsonBody(req) {
|
|
|
15657
15656
|
}
|
|
15658
15657
|
|
|
15659
15658
|
// src/web/mount.ts
|
|
15659
|
+
async function listenCanonical(web, attempts = 25, gapMs = 200) {
|
|
15660
|
+
for (let i = 0; i < attempts; i++) {
|
|
15661
|
+
try {
|
|
15662
|
+
return await web.listen(DEFAULT_WEB_PORT);
|
|
15663
|
+
} catch (err) {
|
|
15664
|
+
if (err.code !== "EADDRINUSE") throw err;
|
|
15665
|
+
if (i < attempts - 1) await new Promise((r) => setTimeout(r, gapMs));
|
|
15666
|
+
}
|
|
15667
|
+
}
|
|
15668
|
+
log.warn("web", "console-port-busy-fallback", { preferred: DEFAULT_WEB_PORT });
|
|
15669
|
+
return web.listen(0);
|
|
15670
|
+
}
|
|
15660
15671
|
async function mountWebConsole(service) {
|
|
15661
|
-
const web = createWebServer({ service });
|
|
15672
|
+
const web = createWebServer({ service, token: stableWebConsoleToken() });
|
|
15662
15673
|
let port;
|
|
15663
15674
|
let url;
|
|
15664
15675
|
try {
|
|
15665
|
-
({ port, url } = await web
|
|
15676
|
+
({ port, url } = await listenCanonical(web));
|
|
15666
15677
|
} catch (err) {
|
|
15667
|
-
|
|
15668
|
-
|
|
15669
|
-
return void 0;
|
|
15670
|
-
}
|
|
15671
|
-
try {
|
|
15672
|
-
({ port, url } = await web.listen(0));
|
|
15673
|
-
} catch (err2) {
|
|
15674
|
-
log.fail("web", err2, { phase: "console-listen-fallback" });
|
|
15675
|
-
return void 0;
|
|
15676
|
-
}
|
|
15678
|
+
log.fail("web", err, { phase: "console-listen" });
|
|
15679
|
+
return void 0;
|
|
15677
15680
|
}
|
|
15678
15681
|
publishWebConsole({ port, token: web.token, pid: process.pid, startedAt: Date.now() });
|
|
15679
15682
|
const exitCleanup = () => clearWebConsole();
|
|
@@ -16469,14 +16472,17 @@ async function runWeb(opts = {}) {
|
|
|
16469
16472
|
console.log(" \xB7 \u4EC5\u672C\u673A\u53EF\u8BBF\u95EE\uFF08127.0.0.1\uFF09\uFF1BURL \u542B token\uFF0C\u8BF7\u52FF\u5916\u4F20/\u622A\u56FE\u3002");
|
|
16470
16473
|
return;
|
|
16471
16474
|
}
|
|
16472
|
-
const port = opts.port ??
|
|
16475
|
+
const port = opts.port ?? 0;
|
|
16473
16476
|
if (!Number.isInteger(port) || port < 0 || port > 65535) {
|
|
16474
16477
|
console.error(`\u2717 \u65E0\u6548\u7AEF\u53E3\uFF1A${opts.port}`);
|
|
16475
16478
|
process.exitCode = 1;
|
|
16476
16479
|
return;
|
|
16477
16480
|
}
|
|
16478
|
-
const service = createReadonlyAdminService({
|
|
16479
|
-
|
|
16481
|
+
const service = createReadonlyAdminService({
|
|
16482
|
+
startDaemon: () => spawnDaemonControl("start"),
|
|
16483
|
+
applyUpdate: () => spawnDaemonControl("update")
|
|
16484
|
+
});
|
|
16485
|
+
const web = createWebServer({ service, token: stableWebConsoleToken(), liveConsole: () => readWebConsole() });
|
|
16480
16486
|
let url;
|
|
16481
16487
|
try {
|
|
16482
16488
|
({ url } = await web.listen(port));
|
package/dist/index.d.ts
CHANGED
|
@@ -55,6 +55,9 @@ declare const paths: {
|
|
|
55
55
|
/** daemon 内嵌 Web 控制台的发现文件 {port, token, pid}(0600,daemon 退出
|
|
56
56
|
* 清理)——`web` 子命令据此直接打开 daemon 控制台而不是再起只读副本。 */
|
|
57
57
|
webConsoleFile: string;
|
|
58
|
+
/** 稳定的 Web 控制台 token(0600,**不随进程退出清理**)——让重启 / 预览→daemon
|
|
59
|
+
* 切换后浏览器里那条带 token 的 URL 始终有效,不再 401。删此文件即轮换 token。 */
|
|
60
|
+
webTokenFile: string;
|
|
58
61
|
};
|
|
59
62
|
|
|
60
63
|
export { log, newTraceId, paths, withTrace };
|
package/dist/index.js
CHANGED
|
@@ -61,7 +61,10 @@ var paths = {
|
|
|
61
61
|
inboundDir: join(appDir, "inbound"),
|
|
62
62
|
/** daemon 内嵌 Web 控制台的发现文件 {port, token, pid}(0600,daemon 退出
|
|
63
63
|
* 清理)——`web` 子命令据此直接打开 daemon 控制台而不是再起只读副本。 */
|
|
64
|
-
webConsoleFile: join(appDir, "web-console.json")
|
|
64
|
+
webConsoleFile: join(appDir, "web-console.json"),
|
|
65
|
+
/** 稳定的 Web 控制台 token(0600,**不随进程退出清理**)——让重启 / 预览→daemon
|
|
66
|
+
* 切换后浏览器里那条带 token 的 URL 始终有效,不再 401。删此文件即轮换 token。 */
|
|
67
|
+
webTokenFile: join(appDir, "web-token")
|
|
65
68
|
};
|
|
66
69
|
|
|
67
70
|
// src/core/logger.ts
|
package/package.json
CHANGED