Files
clawdbot/src/node-host/config.ts
2026-01-18 07:46:00 +00:00

75 lines
1.9 KiB
TypeScript

import crypto from "node:crypto";
import fs from "node:fs/promises";
import path from "node:path";
import { resolveStateDir } from "../config/paths.js";
export type NodeHostGatewayConfig = {
host?: string;
port?: number;
tls?: boolean;
tlsFingerprint?: string;
};
export type NodeHostConfig = {
version: 1;
nodeId: string;
token?: string;
displayName?: string;
gateway?: NodeHostGatewayConfig;
};
const NODE_HOST_FILE = "node.json";
export function resolveNodeHostConfigPath(): string {
return path.join(resolveStateDir(), NODE_HOST_FILE);
}
function normalizeConfig(config: Partial<NodeHostConfig> | null): NodeHostConfig {
const base: NodeHostConfig = {
version: 1,
nodeId: "",
token: config?.token,
displayName: config?.displayName,
gateway: config?.gateway,
};
if (config?.version === 1 && typeof config.nodeId === "string") {
base.nodeId = config.nodeId.trim();
}
if (!base.nodeId) {
base.nodeId = crypto.randomUUID();
}
return base;
}
export async function loadNodeHostConfig(): Promise<NodeHostConfig | null> {
const filePath = resolveNodeHostConfigPath();
try {
const raw = await fs.readFile(filePath, "utf8");
const parsed = JSON.parse(raw) as Partial<NodeHostConfig>;
return normalizeConfig(parsed);
} catch {
return null;
}
}
export async function saveNodeHostConfig(config: NodeHostConfig): Promise<void> {
const filePath = resolveNodeHostConfigPath();
await fs.mkdir(path.dirname(filePath), { recursive: true });
const payload = JSON.stringify(config, null, 2);
await fs.writeFile(filePath, `${payload}\n`, { mode: 0o600 });
try {
await fs.chmod(filePath, 0o600);
} catch {
// best-effort on platforms without chmod
}
}
export async function ensureNodeHostConfig(): Promise<NodeHostConfig> {
const existing = await loadNodeHostConfig();
const normalized = normalizeConfig(existing);
await saveNodeHostConfig(normalized);
return normalized;
}