mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-08 12:21:24 +00:00
chore: Enable "curly" rule to avoid single-statement if confusion/errors.
This commit is contained in:
@@ -28,18 +28,26 @@ function recordAgentRunSnapshot(entry: AgentRunSnapshot) {
|
||||
}
|
||||
|
||||
function ensureAgentRunListener() {
|
||||
if (agentRunListenerStarted) return;
|
||||
if (agentRunListenerStarted) {
|
||||
return;
|
||||
}
|
||||
agentRunListenerStarted = true;
|
||||
onAgentEvent((evt) => {
|
||||
if (!evt) return;
|
||||
if (evt.stream !== "lifecycle") return;
|
||||
if (!evt) {
|
||||
return;
|
||||
}
|
||||
if (evt.stream !== "lifecycle") {
|
||||
return;
|
||||
}
|
||||
const phase = evt.data?.phase;
|
||||
if (phase === "start") {
|
||||
const startedAt = typeof evt.data?.startedAt === "number" ? evt.data.startedAt : undefined;
|
||||
agentRunStarts.set(evt.runId, startedAt ?? Date.now());
|
||||
return;
|
||||
}
|
||||
if (phase !== "end" && phase !== "error") return;
|
||||
if (phase !== "end" && phase !== "error") {
|
||||
return;
|
||||
}
|
||||
const startedAt =
|
||||
typeof evt.data?.startedAt === "number" ? evt.data.startedAt : agentRunStarts.get(evt.runId);
|
||||
const endedAt = typeof evt.data?.endedAt === "number" ? evt.data.endedAt : undefined;
|
||||
@@ -68,23 +76,35 @@ export async function waitForAgentJob(params: {
|
||||
const { runId, timeoutMs } = params;
|
||||
ensureAgentRunListener();
|
||||
const cached = getCachedAgentRun(runId);
|
||||
if (cached) return cached;
|
||||
if (timeoutMs <= 0) return null;
|
||||
if (cached) {
|
||||
return cached;
|
||||
}
|
||||
if (timeoutMs <= 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return await new Promise((resolve) => {
|
||||
let settled = false;
|
||||
const finish = (entry: AgentRunSnapshot | null) => {
|
||||
if (settled) return;
|
||||
if (settled) {
|
||||
return;
|
||||
}
|
||||
settled = true;
|
||||
clearTimeout(timer);
|
||||
unsubscribe();
|
||||
resolve(entry);
|
||||
};
|
||||
const unsubscribe = onAgentEvent((evt) => {
|
||||
if (!evt || evt.stream !== "lifecycle") return;
|
||||
if (evt.runId !== runId) return;
|
||||
if (!evt || evt.stream !== "lifecycle") {
|
||||
return;
|
||||
}
|
||||
if (evt.runId !== runId) {
|
||||
return;
|
||||
}
|
||||
const phase = evt.data?.phase;
|
||||
if (phase !== "end" && phase !== "error") return;
|
||||
if (phase !== "end" && phase !== "error") {
|
||||
return;
|
||||
}
|
||||
const cached = getCachedAgentRun(runId);
|
||||
if (cached) {
|
||||
finish(cached);
|
||||
|
||||
@@ -46,18 +46,32 @@ function normalizeNodeKey(value: string) {
|
||||
|
||||
function resolveBrowserNode(nodes: NodeSession[], query: string): NodeSession | null {
|
||||
const q = query.trim();
|
||||
if (!q) return null;
|
||||
if (!q) {
|
||||
return null;
|
||||
}
|
||||
const qNorm = normalizeNodeKey(q);
|
||||
const matches = nodes.filter((node) => {
|
||||
if (node.nodeId === q) return true;
|
||||
if (typeof node.remoteIp === "string" && node.remoteIp === q) return true;
|
||||
if (node.nodeId === q) {
|
||||
return true;
|
||||
}
|
||||
if (typeof node.remoteIp === "string" && node.remoteIp === q) {
|
||||
return true;
|
||||
}
|
||||
const name = typeof node.displayName === "string" ? node.displayName : "";
|
||||
if (name && normalizeNodeKey(name) === qNorm) return true;
|
||||
if (q.length >= 6 && node.nodeId.startsWith(q)) return true;
|
||||
if (name && normalizeNodeKey(name) === qNorm) {
|
||||
return true;
|
||||
}
|
||||
if (q.length >= 6 && node.nodeId.startsWith(q)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
if (matches.length === 1) return matches[0] ?? null;
|
||||
if (matches.length === 0) return null;
|
||||
if (matches.length === 1) {
|
||||
return matches[0] ?? null;
|
||||
}
|
||||
if (matches.length === 0) {
|
||||
return null;
|
||||
}
|
||||
throw new Error(
|
||||
`ambiguous node: ${q} (matches: ${matches
|
||||
.map((node) => node.displayName || node.remoteIp || node.nodeId)
|
||||
@@ -71,7 +85,9 @@ function resolveBrowserNodeTarget(params: {
|
||||
}): NodeSession | null {
|
||||
const policy = params.cfg.gateway?.nodes?.browser;
|
||||
const mode = policy?.mode ?? "auto";
|
||||
if (mode === "off") return null;
|
||||
if (mode === "off") {
|
||||
return null;
|
||||
}
|
||||
const browserNodes = params.nodes.filter((node) => isBrowserNode(node));
|
||||
if (browserNodes.length === 0) {
|
||||
if (policy?.node?.trim()) {
|
||||
@@ -87,13 +103,19 @@ function resolveBrowserNodeTarget(params: {
|
||||
}
|
||||
return resolved;
|
||||
}
|
||||
if (mode === "manual") return null;
|
||||
if (browserNodes.length === 1) return browserNodes[0] ?? null;
|
||||
if (mode === "manual") {
|
||||
return null;
|
||||
}
|
||||
if (browserNodes.length === 1) {
|
||||
return browserNodes[0] ?? null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
async function persistProxyFiles(files: BrowserProxyFile[] | undefined) {
|
||||
if (!files || files.length === 0) return new Map<string, string>();
|
||||
if (!files || files.length === 0) {
|
||||
return new Map<string, string>();
|
||||
}
|
||||
const mapping = new Map<string, string>();
|
||||
for (const file of files) {
|
||||
const buffer = Buffer.from(file.base64, "base64");
|
||||
@@ -104,7 +126,9 @@ async function persistProxyFiles(files: BrowserProxyFile[] | undefined) {
|
||||
}
|
||||
|
||||
function applyProxyPaths(result: unknown, mapping: Map<string, string>) {
|
||||
if (!result || typeof result !== "object") return;
|
||||
if (!result || typeof result !== "object") {
|
||||
return;
|
||||
}
|
||||
const obj = result as Record<string, unknown>;
|
||||
if (typeof obj.path === "string" && mapping.has(obj.path)) {
|
||||
obj.path = mapping.get(obj.path);
|
||||
|
||||
@@ -98,7 +98,9 @@ export const channelsHandlers: GatewayRequestHandlers = {
|
||||
const defaultRuntime = runtime.channels[channelId];
|
||||
const raw =
|
||||
accounts?.[accountId] ?? (accountId === defaultAccountId ? defaultRuntime : undefined);
|
||||
if (!raw) return undefined;
|
||||
if (!raw) {
|
||||
return undefined;
|
||||
}
|
||||
return raw;
|
||||
};
|
||||
|
||||
@@ -171,7 +173,9 @@ export const channelsHandlers: GatewayRequestHandlers = {
|
||||
probe: probeResult,
|
||||
audit: auditResult,
|
||||
});
|
||||
if (lastProbeAt) snapshot.lastProbeAt = lastProbeAt;
|
||||
if (lastProbeAt) {
|
||||
snapshot.lastProbeAt = lastProbeAt;
|
||||
}
|
||||
const activity = getChannelActivity({
|
||||
channel: channelId as never,
|
||||
accountId,
|
||||
|
||||
@@ -56,8 +56,12 @@ function resolveTranscriptPath(params: {
|
||||
sessionFile?: string;
|
||||
}): string | null {
|
||||
const { sessionId, storePath, sessionFile } = params;
|
||||
if (sessionFile) return sessionFile;
|
||||
if (!storePath) return null;
|
||||
if (sessionFile) {
|
||||
return sessionFile;
|
||||
}
|
||||
if (!storePath) {
|
||||
return null;
|
||||
}
|
||||
return path.join(path.dirname(storePath), `${sessionId}.jsonl`);
|
||||
}
|
||||
|
||||
@@ -65,7 +69,9 @@ function ensureTranscriptFile(params: { transcriptPath: string; sessionId: strin
|
||||
ok: boolean;
|
||||
error?: string;
|
||||
} {
|
||||
if (fs.existsSync(params.transcriptPath)) return { ok: true };
|
||||
if (fs.existsSync(params.transcriptPath)) {
|
||||
return { ok: true };
|
||||
}
|
||||
try {
|
||||
fs.mkdirSync(path.dirname(params.transcriptPath), { recursive: true });
|
||||
const header = {
|
||||
@@ -476,9 +482,13 @@ export const chatHandlers: GatewayRequestHandlers = {
|
||||
context.logGateway.warn(`webchat dispatch failed: ${formatForLog(err)}`);
|
||||
},
|
||||
deliver: async (payload, info) => {
|
||||
if (info.kind !== "final") return;
|
||||
if (info.kind !== "final") {
|
||||
return;
|
||||
}
|
||||
const text = payload.text?.trim() ?? "";
|
||||
if (!text) return;
|
||||
if (!text) {
|
||||
return;
|
||||
}
|
||||
finalReplyParts.push(text);
|
||||
},
|
||||
});
|
||||
|
||||
@@ -33,7 +33,9 @@ import type { GatewayRequestHandlers, RespondFn } from "./types.js";
|
||||
|
||||
function resolveBaseHash(params: unknown): string | null {
|
||||
const raw = (params as { baseHash?: unknown })?.baseHash;
|
||||
if (typeof raw !== "string") return null;
|
||||
if (typeof raw !== "string") {
|
||||
return null;
|
||||
}
|
||||
const trimmed = raw.trim();
|
||||
return trimmed ? trimmed : null;
|
||||
}
|
||||
@@ -43,7 +45,9 @@ function requireConfigBaseHash(
|
||||
snapshot: Awaited<ReturnType<typeof readConfigFileSnapshot>>,
|
||||
respond: RespondFn,
|
||||
): boolean {
|
||||
if (!snapshot.exists) return true;
|
||||
if (!snapshot.exists) {
|
||||
return true;
|
||||
}
|
||||
const snapshotHash = resolveConfigSnapshotHash(snapshot);
|
||||
if (!snapshotHash) {
|
||||
respond(
|
||||
|
||||
@@ -117,7 +117,9 @@ describe("exec approval handlers", () => {
|
||||
|
||||
const context = {
|
||||
broadcast: (event: string, payload: unknown) => {
|
||||
if (event !== "exec.approval.requested") return;
|
||||
if (event !== "exec.approval.requested") {
|
||||
return;
|
||||
}
|
||||
const id = (payload as { id?: string })?.id ?? "";
|
||||
void handlers["exec.approval.resolve"]({
|
||||
params: { id, decision: "allow-once" },
|
||||
|
||||
@@ -21,7 +21,9 @@ import type { GatewayRequestHandlers, RespondFn } from "./types.js";
|
||||
|
||||
function resolveBaseHash(params: unknown): string | null {
|
||||
const raw = (params as { baseHash?: unknown })?.baseHash;
|
||||
if (typeof raw !== "string") return null;
|
||||
if (typeof raw !== "string") {
|
||||
return null;
|
||||
}
|
||||
const trimmed = raw.trim();
|
||||
return trimmed ? trimmed : null;
|
||||
}
|
||||
@@ -31,7 +33,9 @@ function requireApprovalsBaseHash(
|
||||
snapshot: ExecApprovalsSnapshot,
|
||||
respond: RespondFn,
|
||||
): boolean {
|
||||
if (!snapshot.exists) return true;
|
||||
if (!snapshot.exists) {
|
||||
return true;
|
||||
}
|
||||
if (!snapshot.hash) {
|
||||
respond(
|
||||
false,
|
||||
|
||||
@@ -25,12 +25,18 @@ function isRollingLogFile(file: string): boolean {
|
||||
|
||||
async function resolveLogFile(file: string): Promise<string> {
|
||||
const stat = await fs.stat(file).catch(() => null);
|
||||
if (stat) return file;
|
||||
if (!isRollingLogFile(file)) return file;
|
||||
if (stat) {
|
||||
return file;
|
||||
}
|
||||
if (!isRollingLogFile(file)) {
|
||||
return file;
|
||||
}
|
||||
|
||||
const dir = path.dirname(file);
|
||||
const entries = await fs.readdir(dir, { withFileTypes: true }).catch(() => null);
|
||||
if (!entries) return file;
|
||||
if (!entries) {
|
||||
return file;
|
||||
}
|
||||
|
||||
const candidates = await Promise.all(
|
||||
entries
|
||||
|
||||
@@ -38,9 +38,13 @@ export function uniqueSortedStrings(values: unknown[]) {
|
||||
}
|
||||
|
||||
export function safeParseJson(value: string | null | undefined): unknown {
|
||||
if (typeof value !== "string") return undefined;
|
||||
if (typeof value !== "string") {
|
||||
return undefined;
|
||||
}
|
||||
const trimmed = value.trim();
|
||||
if (!trimmed) return undefined;
|
||||
if (!trimmed) {
|
||||
return undefined;
|
||||
}
|
||||
try {
|
||||
return JSON.parse(trimmed) as unknown;
|
||||
} catch {
|
||||
|
||||
@@ -33,13 +33,19 @@ import { isNodeCommandAllowed, resolveNodeCommandAllowlist } from "../node-comma
|
||||
import type { GatewayRequestHandlers } from "./types.js";
|
||||
|
||||
function isNodeEntry(entry: { role?: string; roles?: string[] }) {
|
||||
if (entry.role === "node") return true;
|
||||
if (Array.isArray(entry.roles) && entry.roles.includes("node")) return true;
|
||||
if (entry.role === "node") {
|
||||
return true;
|
||||
}
|
||||
if (Array.isArray(entry.roles) && entry.roles.includes("node")) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function normalizeNodeInvokeResultParams(params: unknown): unknown {
|
||||
if (!params || typeof params !== "object") return params;
|
||||
if (!params || typeof params !== "object") {
|
||||
return params;
|
||||
}
|
||||
const raw = params as Record<string, unknown>;
|
||||
const normalized: Record<string, unknown> = { ...raw };
|
||||
if (normalized.payloadJSON === null) {
|
||||
@@ -284,11 +290,17 @@ export const nodeHandlers: GatewayRequestHandlers = {
|
||||
});
|
||||
|
||||
nodes.sort((a, b) => {
|
||||
if (a.connected !== b.connected) return a.connected ? -1 : 1;
|
||||
if (a.connected !== b.connected) {
|
||||
return a.connected ? -1 : 1;
|
||||
}
|
||||
const an = (a.displayName ?? a.nodeId).toLowerCase();
|
||||
const bn = (b.displayName ?? b.nodeId).toLowerCase();
|
||||
if (an < bn) return -1;
|
||||
if (an > bn) return 1;
|
||||
if (an < bn) {
|
||||
return -1;
|
||||
}
|
||||
if (an > bn) {
|
||||
return 1;
|
||||
}
|
||||
return a.nodeId.localeCompare(b.nodeId);
|
||||
});
|
||||
|
||||
|
||||
@@ -199,9 +199,15 @@ export const sendHandlers: GatewayRequestHandlers = {
|
||||
messageId: result.messageId,
|
||||
channel,
|
||||
};
|
||||
if ("chatId" in result) payload.chatId = result.chatId;
|
||||
if ("channelId" in result) payload.channelId = result.channelId;
|
||||
if ("toJid" in result) payload.toJid = result.toJid;
|
||||
if ("chatId" in result) {
|
||||
payload.chatId = result.chatId;
|
||||
}
|
||||
if ("channelId" in result) {
|
||||
payload.channelId = result.channelId;
|
||||
}
|
||||
if ("toJid" in result) {
|
||||
payload.toJid = result.toJid;
|
||||
}
|
||||
if ("conversationId" in result) {
|
||||
payload.conversationId = result.conversationId;
|
||||
}
|
||||
@@ -324,10 +330,18 @@ export const sendHandlers: GatewayRequestHandlers = {
|
||||
messageId: result.messageId,
|
||||
channel,
|
||||
};
|
||||
if (result.toJid) payload.toJid = result.toJid;
|
||||
if (result.channelId) payload.channelId = result.channelId;
|
||||
if (result.conversationId) payload.conversationId = result.conversationId;
|
||||
if (result.pollId) payload.pollId = result.pollId;
|
||||
if (result.toJid) {
|
||||
payload.toJid = result.toJid;
|
||||
}
|
||||
if (result.channelId) {
|
||||
payload.channelId = result.channelId;
|
||||
}
|
||||
if (result.conversationId) {
|
||||
payload.conversationId = result.conversationId;
|
||||
}
|
||||
if (result.pollId) {
|
||||
payload.pollId = result.pollId;
|
||||
}
|
||||
context.dedupe.set(`poll:${idem}`, {
|
||||
ts: Date.now(),
|
||||
ok: true,
|
||||
|
||||
@@ -300,7 +300,9 @@ export const sessionsHandlers: GatewayRequestHandlers = {
|
||||
const existed = Boolean(entry);
|
||||
const queueKeys = new Set<string>(target.storeKeys);
|
||||
queueKeys.add(target.canonicalKey);
|
||||
if (sessionId) queueKeys.add(sessionId);
|
||||
if (sessionId) {
|
||||
queueKeys.add(sessionId);
|
||||
}
|
||||
clearSessionQueues([...queueKeys]);
|
||||
stopSubagentsForRequester({ cfg, requesterSessionKey: target.canonicalKey });
|
||||
if (sessionId) {
|
||||
@@ -325,7 +327,9 @@ export const sessionsHandlers: GatewayRequestHandlers = {
|
||||
store[primaryKey] = store[existingKey];
|
||||
delete store[existingKey];
|
||||
}
|
||||
if (store[primaryKey]) delete store[primaryKey];
|
||||
if (store[primaryKey]) {
|
||||
delete store[primaryKey];
|
||||
}
|
||||
});
|
||||
|
||||
const archived: string[] = [];
|
||||
@@ -336,7 +340,9 @@ export const sessionsHandlers: GatewayRequestHandlers = {
|
||||
entry?.sessionFile,
|
||||
target.agentId,
|
||||
)) {
|
||||
if (!fs.existsSync(candidate)) continue;
|
||||
if (!fs.existsSync(candidate)) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
archived.push(archiveFileOnDisk(candidate, "deleted"));
|
||||
} catch {
|
||||
@@ -443,7 +449,9 @@ export const sessionsHandlers: GatewayRequestHandlers = {
|
||||
await updateSessionStore(storePath, (store) => {
|
||||
const entryKey = compactTarget.primaryKey;
|
||||
const entryToUpdate = store[entryKey];
|
||||
if (!entryToUpdate) return;
|
||||
if (!entryToUpdate) {
|
||||
return;
|
||||
}
|
||||
delete entryToUpdate.inputTokens;
|
||||
delete entryToUpdate.outputTokens;
|
||||
delete entryToUpdate.totalTokens;
|
||||
|
||||
@@ -38,17 +38,23 @@ function collectSkillBins(entries: SkillEntry[]): string[] {
|
||||
const install = entry.metadata?.install ?? [];
|
||||
for (const bin of required) {
|
||||
const trimmed = bin.trim();
|
||||
if (trimmed) bins.add(trimmed);
|
||||
if (trimmed) {
|
||||
bins.add(trimmed);
|
||||
}
|
||||
}
|
||||
for (const bin of anyBins) {
|
||||
const trimmed = bin.trim();
|
||||
if (trimmed) bins.add(trimmed);
|
||||
if (trimmed) {
|
||||
bins.add(trimmed);
|
||||
}
|
||||
}
|
||||
for (const spec of install) {
|
||||
const specBins = spec?.bins ?? [];
|
||||
for (const bin of specBins) {
|
||||
const trimmed = String(bin).trim();
|
||||
if (trimmed) bins.add(trimmed);
|
||||
if (trimmed) {
|
||||
bins.add(trimmed);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -93,7 +99,9 @@ export const skillsHandlers: GatewayRequestHandlers = {
|
||||
const bins = new Set<string>();
|
||||
for (const workspaceDir of workspaceDirs) {
|
||||
const entries = loadWorkspaceSkillEntries(workspaceDir, { config: cfg });
|
||||
for (const bin of collectSkillBins(entries)) bins.add(bin);
|
||||
for (const bin of collectSkillBins(entries)) {
|
||||
bins.add(bin);
|
||||
}
|
||||
}
|
||||
respond(true, { bins: [...bins].toSorted() }, undefined);
|
||||
},
|
||||
@@ -156,17 +164,25 @@ export const skillsHandlers: GatewayRequestHandlers = {
|
||||
}
|
||||
if (typeof p.apiKey === "string") {
|
||||
const trimmed = p.apiKey.trim();
|
||||
if (trimmed) current.apiKey = trimmed;
|
||||
else delete current.apiKey;
|
||||
if (trimmed) {
|
||||
current.apiKey = trimmed;
|
||||
} else {
|
||||
delete current.apiKey;
|
||||
}
|
||||
}
|
||||
if (p.env && typeof p.env === "object") {
|
||||
const nextEnv = current.env ? { ...current.env } : {};
|
||||
for (const [key, value] of Object.entries(p.env)) {
|
||||
const trimmedKey = key.trim();
|
||||
if (!trimmedKey) continue;
|
||||
if (!trimmedKey) {
|
||||
continue;
|
||||
}
|
||||
const trimmedVal = value.trim();
|
||||
if (!trimmedVal) delete nextEnv[trimmedKey];
|
||||
else nextEnv[trimmedKey] = trimmedVal;
|
||||
if (!trimmedVal) {
|
||||
delete nextEnv[trimmedKey];
|
||||
} else {
|
||||
nextEnv[trimmedKey] = trimmedVal;
|
||||
}
|
||||
}
|
||||
current.env = nextEnv;
|
||||
}
|
||||
|
||||
@@ -15,10 +15,14 @@ type CostUsageCacheEntry = {
|
||||
const costUsageCache = new Map<number, CostUsageCacheEntry>();
|
||||
|
||||
const parseDays = (raw: unknown): number => {
|
||||
if (typeof raw === "number" && Number.isFinite(raw)) return Math.floor(raw);
|
||||
if (typeof raw === "number" && Number.isFinite(raw)) {
|
||||
return Math.floor(raw);
|
||||
}
|
||||
if (typeof raw === "string" && raw.trim() !== "") {
|
||||
const parsed = Number(raw);
|
||||
if (Number.isFinite(parsed)) return Math.floor(parsed);
|
||||
if (Number.isFinite(parsed)) {
|
||||
return Math.floor(parsed);
|
||||
}
|
||||
}
|
||||
return 30;
|
||||
};
|
||||
@@ -35,7 +39,9 @@ async function loadCostUsageSummaryCached(params: {
|
||||
}
|
||||
|
||||
if (cached?.inFlight) {
|
||||
if (cached.summary) return cached.summary;
|
||||
if (cached.summary) {
|
||||
return cached.summary;
|
||||
}
|
||||
return await cached.inFlight;
|
||||
}
|
||||
|
||||
@@ -46,7 +52,9 @@ async function loadCostUsageSummaryCached(params: {
|
||||
return summary;
|
||||
})
|
||||
.catch((err) => {
|
||||
if (entry.summary) return entry.summary;
|
||||
if (entry.summary) {
|
||||
return entry.summary;
|
||||
}
|
||||
throw err;
|
||||
})
|
||||
.finally(() => {
|
||||
@@ -60,7 +68,9 @@ async function loadCostUsageSummaryCached(params: {
|
||||
entry.inFlight = inFlight;
|
||||
costUsageCache.set(days, entry);
|
||||
|
||||
if (entry.summary) return entry.summary;
|
||||
if (entry.summary) {
|
||||
return entry.summary;
|
||||
}
|
||||
return await inFlight;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user