@memtensor/memos-cloud-openclaw-plugin 0.1.11-beta.1 → 0.1.12-beta.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/HOOK.md +22 -0
- package/clawdbot.plugin.json +311 -329
- package/lib/config-resolution-schema.js +5 -5
- package/lib/config-ui/app.js +1 -1
- package/lib/config-ui-server.js +7 -239
- package/moltbot.plugin.json +311 -329
- package/openclaw.plugin.json +311 -329
- package/package.json +1 -1
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
export const CONFIG_RESOLUTION_FIELDS = [
|
|
2
2
|
{ key: "baseUrl", configMode: "truthy", envVar: "MEMOS_BASE_URL", envMode: "truthy", fallbackSource: "default", uiDefaultValue: "https://memos.memtensor.cn/api/openmem/v1" },
|
|
3
3
|
{ key: "apiKey", configMode: "truthy", envVar: "MEMOS_API_KEY", envMode: "truthy", fallbackSource: "empty", inheritedFrom: "env", inheritedFallback: "" },
|
|
4
|
-
{ key: "userId", configMode: "truthy", envVar: "MEMOS_USER_ID", envMode: "truthy", fallbackSource: "default", uiDefaultValue: "openclaw-user" },
|
|
4
|
+
{ key: "userId", configMode: "truthy", envVar: "MEMOS_USER_ID", envMode: "truthy", fallbackSource: "default", uiDefaultValue: "openclaw-user", inheritedFrom: "env", inheritedFallback: "openclaw-user" },
|
|
5
5
|
{ key: "useDirectSessionUserId", configMode: "nullish", envVar: "MEMOS_USE_DIRECT_SESSION_USER_ID", envMode: "defined", fallbackSource: "default", uiDefaultValue: false },
|
|
6
|
-
{ key: "conversationId", configMode: "truthy", envVar: "MEMOS_CONVERSATION_ID", envMode: "truthy", fallbackSource: "empty" },
|
|
7
|
-
{ key: "conversationIdPrefix", configMode: "nullish", envVar: "MEMOS_CONVERSATION_PREFIX", envMode: "defined", fallbackSource: "empty" },
|
|
8
|
-
{ key: "conversationIdSuffix", configMode: "nullish", envVar: "MEMOS_CONVERSATION_SUFFIX", envMode: "defined", fallbackSource: "empty" },
|
|
6
|
+
{ key: "conversationId", configMode: "truthy", envVar: "MEMOS_CONVERSATION_ID", envMode: "truthy", fallbackSource: "empty", inheritedFrom: "env", inheritedFallback: "" },
|
|
7
|
+
{ key: "conversationIdPrefix", configMode: "nullish", envVar: "MEMOS_CONVERSATION_PREFIX", envMode: "defined", fallbackSource: "empty", inheritedFrom: "env", inheritedFallback: "" },
|
|
8
|
+
{ key: "conversationIdSuffix", configMode: "nullish", envVar: "MEMOS_CONVERSATION_SUFFIX", envMode: "defined", fallbackSource: "empty", inheritedFrom: "env", inheritedFallback: "" },
|
|
9
9
|
{ key: "conversationSuffixMode", configMode: "nullish", envVar: "MEMOS_CONVERSATION_SUFFIX_MODE", envMode: "truthy", fallbackSource: "default", uiDefaultValue: "none" },
|
|
10
10
|
{ key: "resetOnNew", configMode: "nullish", envVar: "MEMOS_CONVERSATION_RESET_ON_NEW", envMode: "defined", fallbackSource: "default", uiDefaultValue: true },
|
|
11
11
|
{ key: "queryPrefix", configMode: "nullish", envMode: "none", fallbackSource: "empty", inheritedValue: "" },
|
|
@@ -23,7 +23,7 @@ export const CONFIG_RESOLUTION_FIELDS = [
|
|
|
23
23
|
{ key: "knowledgebaseIds", configMode: "nullish", envMode: "none", fallbackSource: "default", uiDefaultValue: [] },
|
|
24
24
|
{ key: "addEnabled", configMode: "nullish", envMode: "none", fallbackSource: "default", uiDefaultValue: true },
|
|
25
25
|
{ key: "captureStrategy", configMode: "nullish", envVar: "MEMOS_CAPTURE_STRATEGY", envMode: "truthy", fallbackSource: "default", uiDefaultValue: "last_turn" },
|
|
26
|
-
{ key: "maxMessageChars", configMode: "nullish", envVar: "MEMOS_MAX_MESSAGE_CHARS", envMode: "defined", fallbackSource: "default", uiDefaultValue: 20000 },
|
|
26
|
+
{ key: "maxMessageChars", configMode: "nullish", envVar: "MEMOS_MAX_MESSAGE_CHARS", envMode: "defined", fallbackSource: "default", uiDefaultValue: 20000, inheritedFrom: "env", inheritedFallback: 20000 },
|
|
27
27
|
{ key: "includeAssistant", configMode: "nullish", envVar: "MEMOS_INCLUDE_ASSISTANT", envMode: "defined", fallbackSource: "default", uiDefaultValue: true },
|
|
28
28
|
{ key: "tags", configMode: "nullish", envMode: "none", fallbackSource: "default", uiDefaultValue: ["openclaw"] },
|
|
29
29
|
{ key: "info", configMode: "nullish", envMode: "none", fallbackSource: "default", uiDefaultValue: {} },
|
package/lib/config-ui/app.js
CHANGED
|
@@ -244,7 +244,7 @@ const GROUP_TRANSLATIONS = {
|
|
|
244
244
|
const FIELD_TRANSLATIONS = {
|
|
245
245
|
zh: {
|
|
246
246
|
baseUrl: { label: "MemOS 地址", description: "MemOS OpenMem API 的基础地址。" },
|
|
247
|
-
apiKey: { label: "MemOS API Key", description: "Token
|
|
247
|
+
apiKey: { label: "MemOS API Key", description: "Token 鉴权密钥。未在此处填写时,将从 .env 文件中读取。" },
|
|
248
248
|
userId: { label: "用户 ID", description: "消息添加与记忆查询关联的用户唯一标识符。" },
|
|
249
249
|
useDirectSessionUserId: { label: "使用 Direct 会话用户 ID", description: "可用时从 session key 的 direct 段提取用户 ID,覆盖默认 userId。" },
|
|
250
250
|
conversationId: { label: "会话 ID 覆盖", description: "消息添加与记忆查询关联的会话唯一标识符;同一 ID 会被视为同一上下文。" },
|
package/lib/config-ui-server.js
CHANGED
|
@@ -20,10 +20,6 @@ const ANSI_BOLD = "\x1b[1m";
|
|
|
20
20
|
const ANSI_CYAN = "\x1b[36m";
|
|
21
21
|
const ANSI_GREEN = "\x1b[32m";
|
|
22
22
|
const ANSI_RESET = "\x1b[0m";
|
|
23
|
-
const CHILD_ENTRY = fileURLToPath(new URL("./config-ui-child.js", import.meta.url));
|
|
24
|
-
const CHILD_ENV_KEY = "MEMOS_CLOUD_CONFIG_UI_CHILD";
|
|
25
|
-
const HOST_EXEC_PATH_ENV_KEY = "MEMOS_CLOUD_HOST_EXEC_PATH";
|
|
26
|
-
const HOST_ARGV_ENV_KEY = "MEMOS_CLOUD_HOST_ARGV_JSON";
|
|
27
23
|
const DEFAULT_GATEWAY_READY_PORT = 18789;
|
|
28
24
|
|
|
29
25
|
const FIELD_GROUPS = [
|
|
@@ -37,7 +33,7 @@ const FIELD_GROUPS = [
|
|
|
37
33
|
|
|
38
34
|
const FIELD_DEFINITIONS = [
|
|
39
35
|
{ key: "baseUrl", group: "connection", type: "string", label: "MemOS Base URL", description: "Base URL for the MemOS OpenMem API.", placeholder: "https://memos.memtensor.cn/api/openmem/v1" },
|
|
40
|
-
{ key: "apiKey", group: "connection", type: "secret", label: "MemOS API Key", description: "Token auth key. Leave inherited to use env files
|
|
36
|
+
{ key: "apiKey", group: "connection", type: "secret", label: "MemOS API Key", description: "Token auth key. Leave inherited to use env files.", placeholder: "mpg-..." },
|
|
41
37
|
{ key: "userId", group: "connection", type: "string", label: "User ID", description: "Unique identifier of the user associated with added messages and queried memories.", placeholder: "openclaw-user" },
|
|
42
38
|
{ key: "useDirectSessionUserId", group: "connection", type: "boolean", label: "Use Direct Session User ID", description: "Use direct-session user id from session key when available." },
|
|
43
39
|
{ key: "conversationId", group: "session", type: "string", label: "Conversation ID Override", description: "Unique identifier of the conversation. Reusing the same value keeps turns in the same context." },
|
|
@@ -155,12 +151,12 @@ function detectRuntimeProfile() {
|
|
|
155
151
|
const execPath = String(process.execPath || "").toLowerCase();
|
|
156
152
|
|
|
157
153
|
if (scriptPath.includes("moltbot") || execPath.includes("moltbot")) {
|
|
158
|
-
return { id: "moltbot", displayName: "Moltbot", cliName: "moltbot", configPath:
|
|
154
|
+
return { id: "moltbot", displayName: "Moltbot", cliName: "moltbot", configPath: join(homedir(), ".moltbot", "moltbot.json") };
|
|
159
155
|
}
|
|
160
156
|
if (scriptPath.includes("clawdbot") || execPath.includes("clawdbot")) {
|
|
161
|
-
return { id: "clawdbot", displayName: "ClawDBot", cliName: "clawdbot", configPath:
|
|
157
|
+
return { id: "clawdbot", displayName: "ClawDBot", cliName: "clawdbot", configPath: join(homedir(), ".clawdbot", "clawdbot.json") };
|
|
162
158
|
}
|
|
163
|
-
return { id: "openclaw", displayName: "OpenClaw", cliName: "openclaw", configPath:
|
|
159
|
+
return { id: "openclaw", displayName: "OpenClaw", cliName: "openclaw", configPath: join(homedir(), ".openclaw", "openclaw.json") };
|
|
164
160
|
}
|
|
165
161
|
|
|
166
162
|
function parsePositiveInteger(value, fallback) {
|
|
@@ -171,11 +167,7 @@ function parsePositiveInteger(value, fallback) {
|
|
|
171
167
|
|
|
172
168
|
function resolveGatewayReadyProbeTarget(rootConfig = {}) {
|
|
173
169
|
const gateway = isPlainObject(rootConfig?.gateway) ? rootConfig.gateway : {};
|
|
174
|
-
const
|
|
175
|
-
process.env.OPENCLAW_GATEWAY_PORT ||
|
|
176
|
-
process.env.MOLTBOT_GATEWAY_PORT ||
|
|
177
|
-
process.env.CLAWDBOT_GATEWAY_PORT;
|
|
178
|
-
const port = parsePositiveInteger(gateway.port ?? envPort, DEFAULT_GATEWAY_READY_PORT);
|
|
170
|
+
const port = parsePositiveInteger(gateway.port, DEFAULT_GATEWAY_READY_PORT);
|
|
179
171
|
const bind = typeof gateway.bind === "string" ? gateway.bind.trim().toLowerCase() : "";
|
|
180
172
|
const customBindHost = typeof gateway.customBindHost === "string" ? gateway.customBindHost.trim() : "";
|
|
181
173
|
const host = bind === "custom" && customBindHost ? customBindHost : "127.0.0.1";
|
|
@@ -492,194 +484,7 @@ function renderAppJs(service) {
|
|
|
492
484
|
});
|
|
493
485
|
}
|
|
494
486
|
|
|
495
|
-
|
|
496
|
-
const globalState = getGlobalState();
|
|
497
|
-
if (globalState.cleanupInstalled) return;
|
|
498
|
-
globalState.cleanupInstalled = true;
|
|
499
|
-
|
|
500
|
-
const terminateChildImmediately = () => {
|
|
501
|
-
const { child } = getGlobalState();
|
|
502
|
-
if (!child?.pid) return;
|
|
503
|
-
|
|
504
|
-
if (process.platform === "win32") {
|
|
505
|
-
exec(`taskkill /pid ${child.pid} /T /F`, () => {});
|
|
506
|
-
return;
|
|
507
|
-
}
|
|
508
|
-
|
|
509
|
-
try {
|
|
510
|
-
process.kill(-child.pid, "SIGKILL");
|
|
511
|
-
} catch {
|
|
512
|
-
try {
|
|
513
|
-
child.kill("SIGKILL");
|
|
514
|
-
} catch {
|
|
515
|
-
// Ignore kill races during shutdown.
|
|
516
|
-
}
|
|
517
|
-
}
|
|
518
|
-
};
|
|
519
|
-
|
|
520
|
-
const closeSynchronously = () => {
|
|
521
|
-
const globalState = getGlobalState();
|
|
522
|
-
globalState.shuttingDown = true;
|
|
523
|
-
const { service, child } = globalState;
|
|
524
|
-
if (service?.server) {
|
|
525
|
-
try {
|
|
526
|
-
service.server.close();
|
|
527
|
-
} catch {
|
|
528
|
-
// Ignore close races during shutdown.
|
|
529
|
-
}
|
|
530
|
-
}
|
|
531
|
-
if (child?.pid) {
|
|
532
|
-
terminateChildImmediately();
|
|
533
|
-
}
|
|
534
|
-
};
|
|
535
|
-
|
|
536
|
-
for (const signal of ["SIGINT", "SIGTERM", "SIGBREAK"]) {
|
|
537
|
-
process.once(signal, closeSynchronously);
|
|
538
|
-
}
|
|
539
|
-
process.once("beforeExit", closeSynchronously);
|
|
540
|
-
process.once("exit", closeSynchronously);
|
|
541
|
-
}
|
|
542
|
-
|
|
543
|
-
function installGatewayRestartHook(log = console) {
|
|
544
|
-
const globalState = getGlobalState();
|
|
545
|
-
if (globalState.restartHookInstalled || process.env[CHILD_ENV_KEY] === "1") return;
|
|
546
|
-
globalState.restartHookInstalled = true;
|
|
547
|
-
|
|
548
|
-
process.on("SIGUSR1", () => {
|
|
549
|
-
const state = getGlobalState();
|
|
550
|
-
if (state.shuttingDown) return;
|
|
551
|
-
if (state.recyclePromise) return;
|
|
552
|
-
|
|
553
|
-
log.info?.("[memos-cloud] Gateway restart detected; recycling config UI service.");
|
|
554
|
-
state.recyclePromise = closeConfigUiService({ clearRestartPending: false })
|
|
555
|
-
.catch((error) => {
|
|
556
|
-
log.warn?.(`[memos-cloud] Failed to close config UI during gateway restart: ${String(error?.message || error)}`);
|
|
557
|
-
})
|
|
558
|
-
.then(
|
|
559
|
-
() =>
|
|
560
|
-
new Promise((resolve) => {
|
|
561
|
-
setTimeout(resolve, 500);
|
|
562
|
-
}),
|
|
563
|
-
)
|
|
564
|
-
.then(() => {
|
|
565
|
-
const latestState = getGlobalState();
|
|
566
|
-
if (latestState.shuttingDown) return null;
|
|
567
|
-
latestState.recyclePromise = null;
|
|
568
|
-
return waitForGatewayReady({}, log, { timeoutMs: 15000, intervalMs: 250 });
|
|
569
|
-
})
|
|
570
|
-
.then((ready) => {
|
|
571
|
-
if (!ready) return null;
|
|
572
|
-
log.info?.("[memos-cloud] Restarting config UI service after gateway recycle.");
|
|
573
|
-
return ensureConfigUiService(log);
|
|
574
|
-
})
|
|
575
|
-
.catch((error) => {
|
|
576
|
-
log.warn?.(`[memos-cloud] Failed to restart config UI after gateway recycle: ${String(error?.message || error)}`);
|
|
577
|
-
return null;
|
|
578
|
-
})
|
|
579
|
-
.finally(() => {
|
|
580
|
-
const latestState = getGlobalState();
|
|
581
|
-
latestState.recyclePromise = null;
|
|
582
|
-
});
|
|
583
|
-
});
|
|
584
|
-
}
|
|
585
|
-
|
|
586
|
-
function markRestartPending(durationMs = 15000) {
|
|
587
|
-
const globalState = getGlobalState();
|
|
588
|
-
globalState.restartPending = true;
|
|
589
|
-
if (globalState.restartTimer) {
|
|
590
|
-
clearTimeout(globalState.restartTimer);
|
|
591
|
-
}
|
|
592
|
-
globalState.restartTimer = setTimeout(() => {
|
|
593
|
-
const latestState = getGlobalState();
|
|
594
|
-
latestState.restartPending = false;
|
|
595
|
-
latestState.restartTimer = null;
|
|
596
|
-
}, durationMs);
|
|
597
|
-
}
|
|
598
|
-
|
|
599
|
-
function clearRestartPending() {
|
|
600
|
-
const globalState = getGlobalState();
|
|
601
|
-
globalState.restartPending = false;
|
|
602
|
-
if (globalState.restartTimer) {
|
|
603
|
-
clearTimeout(globalState.restartTimer);
|
|
604
|
-
globalState.restartTimer = null;
|
|
605
|
-
}
|
|
606
|
-
}
|
|
607
|
-
|
|
608
|
-
function readHostLaunchContext() {
|
|
609
|
-
const execPath = process.env[HOST_EXEC_PATH_ENV_KEY] || process.execPath;
|
|
610
|
-
const fallbackArgv = Array.isArray(process.argv) ? [...process.argv] : [];
|
|
611
|
-
|
|
612
|
-
try {
|
|
613
|
-
const parsed = JSON.parse(process.env[HOST_ARGV_ENV_KEY] || "null");
|
|
614
|
-
if (Array.isArray(parsed) && parsed.length > 0) {
|
|
615
|
-
return { execPath, argv: parsed.map((value) => String(value ?? "")) };
|
|
616
|
-
}
|
|
617
|
-
} catch {
|
|
618
|
-
// Ignore malformed env and fall back to the current process argv.
|
|
619
|
-
}
|
|
620
|
-
|
|
621
|
-
return { execPath, argv: fallbackArgv.map((value) => String(value ?? "")) };
|
|
622
|
-
}
|
|
623
|
-
|
|
624
|
-
function buildGatewayRestartLaunch() {
|
|
625
|
-
const { execPath, argv } = readHostLaunchContext();
|
|
626
|
-
const args = argv.slice(1);
|
|
627
|
-
const gatewayIndex = args.findIndex((value) => value.toLowerCase() === "gateway");
|
|
628
|
-
const prefixArgs = gatewayIndex >= 0 ? args.slice(0, gatewayIndex) : args;
|
|
629
|
-
return {
|
|
630
|
-
filePath: execPath,
|
|
631
|
-
args: [...prefixArgs, "gateway", "restart"],
|
|
632
|
-
};
|
|
633
|
-
}
|
|
634
|
-
|
|
635
|
-
function requestGatewayRestartFromParent(log) {
|
|
636
|
-
if (process.env[CHILD_ENV_KEY] !== "1") return false;
|
|
637
|
-
if (typeof process.send !== "function") return false;
|
|
638
|
-
|
|
639
|
-
try {
|
|
640
|
-
process.send({ type: "request-restart" });
|
|
641
|
-
log.info?.("[memos-cloud] Requested in-process gateway restart from parent process.");
|
|
642
|
-
return true;
|
|
643
|
-
} catch (error) {
|
|
644
|
-
log.warn?.(`[memos-cloud] Failed to request in-process gateway restart: ${String(error?.message || error)}`);
|
|
645
|
-
return false;
|
|
646
|
-
}
|
|
647
|
-
}
|
|
648
|
-
|
|
649
|
-
function launchGatewayRestartInBackground(service, log) {
|
|
650
|
-
try {
|
|
651
|
-
const launch = buildGatewayRestartLaunch();
|
|
652
|
-
const child = spawn(launch.filePath, launch.args, {
|
|
653
|
-
detached: true,
|
|
654
|
-
stdio: "ignore",
|
|
655
|
-
windowsHide: process.platform === "win32",
|
|
656
|
-
shell: false,
|
|
657
|
-
cwd: process.cwd(),
|
|
658
|
-
env: { ...process.env, [CHILD_ENV_KEY]: "0" },
|
|
659
|
-
});
|
|
660
|
-
child.once("error", (error) => {
|
|
661
|
-
clearRestartPending();
|
|
662
|
-
log.warn?.(
|
|
663
|
-
`[memos-cloud] Restart launcher failed for ${service.profile.displayName} gateway: ${String(error?.message || error)}`,
|
|
664
|
-
);
|
|
665
|
-
});
|
|
666
|
-
child.once("exit", (code, signal) => {
|
|
667
|
-
if (code && code !== 0) {
|
|
668
|
-
clearRestartPending();
|
|
669
|
-
log.warn?.(
|
|
670
|
-
`[memos-cloud] Restart launcher exited early for ${service.profile.displayName} gateway (code=${code}, signal=${signal ?? "null"}).`,
|
|
671
|
-
);
|
|
672
|
-
}
|
|
673
|
-
});
|
|
674
|
-
child.unref();
|
|
675
|
-
log.info?.(
|
|
676
|
-
`[memos-cloud] Background restart command launched for ${service.profile.displayName} gateway using ${launch.filePath} ${launch.args.join(" ")}`,
|
|
677
|
-
);
|
|
678
|
-
} catch (error) {
|
|
679
|
-
log.warn?.(`[memos-cloud] Failed to launch restart for ${service.profile.displayName} gateway: ${String(error)}`);
|
|
680
|
-
throw error;
|
|
681
|
-
}
|
|
682
|
-
}
|
|
487
|
+
// Legacy restart functions removed for sandbox compliance
|
|
683
488
|
|
|
684
489
|
function listenOnPort(server, host, port) {
|
|
685
490
|
return new Promise((resolve, reject) => {
|
|
@@ -745,7 +550,6 @@ function isAuthorized(req, service) {
|
|
|
745
550
|
}
|
|
746
551
|
|
|
747
552
|
async function createService(log) {
|
|
748
|
-
installCleanupHooks();
|
|
749
553
|
const profile = detectRuntimeProfile();
|
|
750
554
|
const token = randomBytes(24).toString("hex");
|
|
751
555
|
const bootId = randomBytes(10).toString("hex");
|
|
@@ -828,27 +632,7 @@ async function createService(log) {
|
|
|
828
632
|
return;
|
|
829
633
|
}
|
|
830
634
|
|
|
831
|
-
|
|
832
|
-
const globalState = getGlobalState();
|
|
833
|
-
if (globalState.restartPending) {
|
|
834
|
-
sendJson(res, 200, { ok: true, deduped: true });
|
|
835
|
-
return;
|
|
836
|
-
}
|
|
837
|
-
|
|
838
|
-
markRestartPending();
|
|
839
|
-
sendJson(res, 200, { ok: true });
|
|
840
|
-
setTimeout(() => {
|
|
841
|
-
try {
|
|
842
|
-
if (requestGatewayRestartFromParent(log)) return;
|
|
843
|
-
launchGatewayRestartInBackground(service, log);
|
|
844
|
-
} catch (error) {
|
|
845
|
-
clearRestartPending();
|
|
846
|
-
log.warn?.(`[memos-cloud] Restart launch failed: ${String(error?.message || error)}`);
|
|
847
|
-
}
|
|
848
|
-
}, 120);
|
|
849
|
-
return;
|
|
850
|
-
}
|
|
851
|
-
|
|
635
|
+
// Legacy `/api/restart` has been entirely removed
|
|
852
636
|
sendText(res, 404, "Not found");
|
|
853
637
|
return;
|
|
854
638
|
}
|
|
@@ -880,19 +664,11 @@ async function createService(log) {
|
|
|
880
664
|
}
|
|
881
665
|
|
|
882
666
|
export function ensureConfigUiService(log = console) {
|
|
883
|
-
if (process.env[CHILD_ENV_KEY] === "1") {
|
|
884
|
-
return Promise.resolve(null);
|
|
885
|
-
}
|
|
886
667
|
if (!shouldStartConfigUi()) {
|
|
887
668
|
return Promise.resolve(null);
|
|
888
669
|
}
|
|
889
|
-
installCleanupHooks();
|
|
890
|
-
installGatewayRestartHook(log);
|
|
891
670
|
|
|
892
671
|
const globalState = getGlobalState();
|
|
893
|
-
if (globalState.recyclePromise) {
|
|
894
|
-
return globalState.recyclePromise.then(() => ensureConfigUiService(log));
|
|
895
|
-
}
|
|
896
672
|
if (globalState.promise) return globalState.promise;
|
|
897
673
|
|
|
898
674
|
globalState.promise = createService(log)
|
|
@@ -911,14 +687,6 @@ export function ensureConfigUiService(log = console) {
|
|
|
911
687
|
|
|
912
688
|
export async function closeConfigUiService(options = {}) {
|
|
913
689
|
const globalState = getGlobalState();
|
|
914
|
-
const clearRestartPending = options.clearRestartPending !== false;
|
|
915
|
-
if (clearRestartPending) {
|
|
916
|
-
if (globalState.restartTimer) {
|
|
917
|
-
clearTimeout(globalState.restartTimer);
|
|
918
|
-
globalState.restartTimer = null;
|
|
919
|
-
}
|
|
920
|
-
globalState.restartPending = false;
|
|
921
|
-
}
|
|
922
690
|
|
|
923
691
|
if (!globalState.service) {
|
|
924
692
|
globalState.promise = null;
|