@mebular/mcp 0.0.0-stage → 0.1.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/bin/mebular.mjs +1133 -0
- package/package.json +30 -4
- package/scripts/publish-manifest.mjs +44 -0
- package/src/admin.mjs +1320 -0
- package/src/apply-supervisor.mjs +48 -0
- package/src/build-sha.mjs +36 -0
- package/src/client.mjs +49 -0
- package/src/clients.mjs +1242 -0
- package/src/cloud-switch.mjs +258 -0
- package/src/config-apply.mjs +251 -0
- package/src/config-schema.mjs +690 -0
- package/src/config.mjs +265 -0
- package/src/fleet-events.mjs +207 -0
- package/src/home.mjs +16 -0
- package/src/jointoken.mjs +31 -0
- package/src/lan-host.mjs +36 -0
- package/src/profiles.mjs +681 -0
- package/src/provision.mjs +673 -0
- package/src/qr.mjs +4 -0
- package/src/runtime-file.mjs +91 -0
- package/src/serve.mjs +3478 -0
- package/src/server.mjs +416 -0
- package/src/service-control.mjs +107 -0
- package/src/service-facade.mjs +43 -0
- package/src/task-tools.mjs +45 -0
- package/src/tool-envelope.mjs +50 -0
- package/src/tools.mjs +397 -0
- package/README.md +0 -3
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
// <home>/runtime.json:守护启动后的非敏感发现信息。
|
|
2
|
+
//
|
|
3
|
+
// 只包含版本、pid、实际 HTTP 监听地址、Console/MCP 路径与 embed 协议版本。
|
|
4
|
+
// 不读取也不写入任何 Mebular 配置、身份或密钥。写入在 HTTP listen 成功之后
|
|
5
|
+
// 原子完成;停止时只删除 pid 与当前进程一致的 runtime.json,避免误删新实例。
|
|
6
|
+
|
|
7
|
+
import { readFile, rename, unlink, writeFile } from 'node:fs/promises';
|
|
8
|
+
import { join } from 'node:path';
|
|
9
|
+
|
|
10
|
+
export const RUNTIME_FILE = 'runtime.json';
|
|
11
|
+
|
|
12
|
+
/** @param {string} home */
|
|
13
|
+
export function runtimePath(home) {
|
|
14
|
+
return join(home, RUNTIME_FILE);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Build the exact non-sensitive runtime record.
|
|
19
|
+
* @param {{
|
|
20
|
+
* version: string,
|
|
21
|
+
* pid?: number,
|
|
22
|
+
* host: string,
|
|
23
|
+
* port: number,
|
|
24
|
+
* consolePath?: string,
|
|
25
|
+
* mcpPath?: string,
|
|
26
|
+
* embedProtocol: number,
|
|
27
|
+
* }} input
|
|
28
|
+
*/
|
|
29
|
+
export function buildRuntimeRecord(input) {
|
|
30
|
+
return {
|
|
31
|
+
version: input.version,
|
|
32
|
+
pid: input.pid ?? process.pid,
|
|
33
|
+
http: { host: input.host, port: input.port },
|
|
34
|
+
consolePath: input.consolePath ?? '/console',
|
|
35
|
+
mcpPath: input.mcpPath ?? '/mcp',
|
|
36
|
+
embedProtocol: input.embedProtocol,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Atomically write <home>/runtime.json. Call only after the HTTP listener is bound.
|
|
42
|
+
* @param {string} home
|
|
43
|
+
* @param {Parameters<typeof buildRuntimeRecord>[0]} input
|
|
44
|
+
* @returns {Promise<ReturnType<typeof buildRuntimeRecord>>}
|
|
45
|
+
*/
|
|
46
|
+
export async function writeRuntimeFile(home, input) {
|
|
47
|
+
const record = buildRuntimeRecord(input);
|
|
48
|
+
const path = runtimePath(home);
|
|
49
|
+
const tmp = `${path}.tmp-${process.pid}`;
|
|
50
|
+
try {
|
|
51
|
+
await writeFile(tmp, JSON.stringify(record, null, 2), { encoding: 'utf-8', mode: 0o600 });
|
|
52
|
+
await rename(tmp, path);
|
|
53
|
+
} catch (error) {
|
|
54
|
+
await unlink(tmp).catch(() => undefined);
|
|
55
|
+
throw error;
|
|
56
|
+
}
|
|
57
|
+
return record;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Read <home>/runtime.json without throwing. Returns null for a missing,
|
|
62
|
+
* unreadable, or malformed file.
|
|
63
|
+
* @param {string} home
|
|
64
|
+
* @returns {Promise<Record<string, unknown> | null>}
|
|
65
|
+
*/
|
|
66
|
+
export async function readRuntimeFile(home) {
|
|
67
|
+
try {
|
|
68
|
+
const value = JSON.parse(await readFile(runtimePath(home), 'utf-8'));
|
|
69
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value) ? value : null;
|
|
70
|
+
} catch {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Remove runtime.json only when it still belongs to `pid`. A newer instance that
|
|
77
|
+
* already replaced the file is left untouched.
|
|
78
|
+
* @param {string} home
|
|
79
|
+
* @param {{ pid?: number }} [options]
|
|
80
|
+
* @returns {Promise<boolean>}
|
|
81
|
+
*/
|
|
82
|
+
export async function clearRuntimeFile(home, { pid = process.pid } = {}) {
|
|
83
|
+
const record = await readRuntimeFile(home);
|
|
84
|
+
if (record === null || record.pid !== pid) return false;
|
|
85
|
+
try {
|
|
86
|
+
await unlink(runtimePath(home));
|
|
87
|
+
return true;
|
|
88
|
+
} catch {
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
}
|