Files
openclaw/src/node-host/config.ts
Peter Steinberger 538605ff44 [codex] Extract filesystem safety primitives (#77918)
* refactor: extract filesystem safety primitives

* refactor: use fs-safe for file access helpers

* refactor: reuse fs-safe for media reads

* refactor: use fs-safe for image reads

* refactor: reuse fs-safe in qqbot media opener

* refactor: reuse fs-safe for local media checks

* refactor: consume cleaner fs-safe api

* refactor: align fs-safe json option names

* fix: preserve fs-safe migration contracts

* refactor: use fs-safe primitive subpaths

* refactor: use grouped fs-safe subpaths

* refactor: align fs-safe api usage

* refactor: adapt private state store api

* chore: refresh proof gate

* refactor: follow fs-safe json api split

* refactor: follow reduced fs-safe surface

* build: default fs-safe python helper off

* fix: preserve fs-safe plugin sdk aliases

* refactor: consolidate fs-safe usage

* refactor: unify fs-safe store usage

* refactor: trim fs-safe temp workspace usage

* refactor: hide low-level fs-safe primitives

* build: use published fs-safe package

* fix: preserve outbound recovery durability after rebase

* chore: refresh pr checks
2026-05-06 02:15:17 +01:00

67 lines
1.7 KiB
TypeScript

import crypto from "node:crypto";
import fs from "node:fs/promises";
import path from "node:path";
import { resolveStateDir } from "../config/paths.js";
import { writeJson } from "../infra/json-files.js";
export type NodeHostGatewayConfig = {
host?: string;
port?: number;
tls?: boolean;
tlsFingerprint?: string;
};
type NodeHostConfig = {
version: 1;
nodeId: string;
token?: string;
displayName?: string;
gateway?: NodeHostGatewayConfig;
};
const NODE_HOST_FILE = "node.json";
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 writeJson(filePath, config, { mode: 0o600 });
}
export async function ensureNodeHostConfig(): Promise<NodeHostConfig> {
const existing = await loadNodeHostConfig();
const normalized = normalizeConfig(existing);
await saveNodeHostConfig(normalized);
return normalized;
}