mirror of
https://github.com/moltbot/moltbot.git
synced 2026-04-24 07:01:49 +00:00
refactor: dedupe ui trimmed readers
This commit is contained in:
@@ -72,7 +72,7 @@ import type { GatewayBrowserClient, GatewayHelloOk } from "./gateway.ts";
|
||||
import type { Tab } from "./navigation.ts";
|
||||
import { resolveAgentIdFromSessionKey } from "./session-key.ts";
|
||||
import { loadSettings, type UiSettings } from "./storage.ts";
|
||||
import { normalizeLowercaseStringOrEmpty } from "./string-coerce.ts";
|
||||
import { normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "./string-coerce.ts";
|
||||
import { VALID_THEME_NAMES, type ResolvedTheme, type ThemeMode, type ThemeName } from "./theme.ts";
|
||||
import type {
|
||||
AgentsListResult,
|
||||
@@ -737,7 +737,7 @@ export class OpenClawApp extends LitElement {
|
||||
if (!nextGatewayUrl) {
|
||||
return;
|
||||
}
|
||||
const nextToken = this.pendingGatewayToken?.trim() || "";
|
||||
const nextToken = normalizeOptionalString(this.pendingGatewayToken) ?? "";
|
||||
this.pendingGatewayUrl = null;
|
||||
this.pendingGatewayToken = null;
|
||||
applySettingsInternal(this as unknown as Parameters<typeof applySettingsInternal>[0], {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { normalizeOptionalString } from "../string-coerce.ts";
|
||||
|
||||
export type ExecApprovalRequestPayload = {
|
||||
command: string;
|
||||
cwd?: string | null;
|
||||
@@ -36,12 +38,12 @@ export function parseExecApprovalRequested(payload: unknown): ExecApprovalReques
|
||||
if (!isRecord(payload)) {
|
||||
return null;
|
||||
}
|
||||
const id = typeof payload.id === "string" ? payload.id.trim() : "";
|
||||
const id = normalizeOptionalString(payload.id) ?? "";
|
||||
const request = payload.request;
|
||||
if (!id || !isRecord(request)) {
|
||||
return null;
|
||||
}
|
||||
const command = typeof request.command === "string" ? request.command.trim() : "";
|
||||
const command = normalizeOptionalString(request.command) ?? "";
|
||||
if (!command) {
|
||||
return null;
|
||||
}
|
||||
@@ -72,7 +74,7 @@ export function parseExecApprovalResolved(payload: unknown): ExecApprovalResolve
|
||||
if (!isRecord(payload)) {
|
||||
return null;
|
||||
}
|
||||
const id = typeof payload.id === "string" ? payload.id.trim() : "";
|
||||
const id = normalizeOptionalString(payload.id) ?? "";
|
||||
if (!id) {
|
||||
return null;
|
||||
}
|
||||
@@ -88,7 +90,7 @@ export function parsePluginApprovalRequested(payload: unknown): ExecApprovalRequ
|
||||
if (!isRecord(payload)) {
|
||||
return null;
|
||||
}
|
||||
const id = typeof payload.id === "string" ? payload.id.trim() : "";
|
||||
const id = normalizeOptionalString(payload.id) ?? "";
|
||||
if (!id) {
|
||||
return null;
|
||||
}
|
||||
@@ -99,7 +101,7 @@ export function parsePluginApprovalRequested(payload: unknown): ExecApprovalRequ
|
||||
}
|
||||
// title, description, severity, pluginId, agentId, sessionKey live inside payload.request
|
||||
const request = isRecord(payload.request) ? payload.request : {};
|
||||
const title = typeof request.title === "string" ? request.title.trim() : "";
|
||||
const title = normalizeOptionalString(request.title) ?? "";
|
||||
if (!title) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
} from "../../../src/gateway/protocol/connect-error-details.js";
|
||||
import { clearDeviceAuthToken, loadDeviceAuthToken, storeDeviceAuthToken } from "./device-auth.ts";
|
||||
import { loadOrCreateDeviceIdentity, signDevicePayload } from "./device-identity.ts";
|
||||
import { normalizeLowercaseStringOrEmpty } from "./string-coerce.ts";
|
||||
import { normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "./string-coerce.ts";
|
||||
import { generateUUID } from "./uuid.ts";
|
||||
|
||||
export type GatewayEventFrame = {
|
||||
@@ -387,8 +387,8 @@ export class GatewayBrowserClient {
|
||||
const role = CONTROL_UI_OPERATOR_ROLE;
|
||||
const scopes = [...CONTROL_UI_OPERATOR_SCOPES];
|
||||
const client = this.buildConnectClient();
|
||||
const explicitGatewayToken = this.opts.token?.trim() || undefined;
|
||||
const explicitPassword = this.opts.password?.trim() || undefined;
|
||||
const explicitGatewayToken = normalizeOptionalString(this.opts.token);
|
||||
const explicitPassword = normalizeOptionalString(this.opts.password);
|
||||
|
||||
// crypto.subtle is only available in secure contexts (HTTPS, localhost).
|
||||
// Over plain HTTP, we skip device identity and fall back to token-only auth.
|
||||
@@ -565,8 +565,8 @@ export class GatewayBrowserClient {
|
||||
}
|
||||
|
||||
private selectConnectAuth(params: { role: string; deviceId: string }): SelectedConnectAuth {
|
||||
const explicitGatewayToken = this.opts.token?.trim() || undefined;
|
||||
const authPassword = this.opts.password?.trim() || undefined;
|
||||
const explicitGatewayToken = normalizeOptionalString(this.opts.token);
|
||||
const authPassword = normalizeOptionalString(this.opts.password);
|
||||
const storedEntry = loadDeviceAuthToken({
|
||||
deviceId: params.deviceId,
|
||||
role: params.role,
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { normalizeOptionalString } from "../string-coerce.ts";
|
||||
|
||||
export type NodeTargetOption = {
|
||||
id: string;
|
||||
label: string;
|
||||
@@ -21,13 +23,13 @@ export function resolveConfigAgents(config: Record<string, unknown> | null): Con
|
||||
return;
|
||||
}
|
||||
const record = entry as Record<string, unknown>;
|
||||
const id = typeof record.id === "string" ? record.id.trim() : "";
|
||||
const id = normalizeOptionalString(record.id) ?? "";
|
||||
if (!id) {
|
||||
return;
|
||||
}
|
||||
const name = typeof record.name === "string" ? record.name.trim() : undefined;
|
||||
const name = normalizeOptionalString(record.name);
|
||||
const isDefault = record.default === true;
|
||||
agents.push({ id, name: name || undefined, isDefault, index, record });
|
||||
agents.push({ id, name, isDefault, index, record });
|
||||
});
|
||||
|
||||
return agents;
|
||||
@@ -47,15 +49,11 @@ export function resolveNodeTargets(
|
||||
continue;
|
||||
}
|
||||
|
||||
const nodeId = typeof node.nodeId === "string" ? node.nodeId.trim() : "";
|
||||
const nodeId = normalizeOptionalString(node.nodeId) ?? "";
|
||||
if (!nodeId) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const displayName =
|
||||
typeof node.displayName === "string" && node.displayName.trim()
|
||||
? node.displayName.trim()
|
||||
: nodeId;
|
||||
const displayName = normalizeOptionalString(node.displayName) ?? nodeId;
|
||||
list.push({
|
||||
id: nodeId,
|
||||
label: displayName === nodeId ? nodeId : `${displayName} · ${nodeId}`,
|
||||
|
||||
@@ -4,7 +4,7 @@ import { formatRelativeTimestamp } from "../format.ts";
|
||||
import { icons } from "../icons.ts";
|
||||
import { pathForTab } from "../navigation.ts";
|
||||
import { formatSessionTokens } from "../presenter.ts";
|
||||
import { normalizeLowercaseStringOrEmpty } from "../string-coerce.ts";
|
||||
import { normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "../string-coerce.ts";
|
||||
import type {
|
||||
GatewaySessionRow,
|
||||
SessionCompactionCheckpoint,
|
||||
@@ -467,14 +467,10 @@ function renderRows(row: GatewaySessionRow, props: SessionsProps) {
|
||||
const isExpanded = props.expandedCheckpointKey === row.key;
|
||||
const checkpointItems = props.checkpointItemsByKey[row.key] ?? [];
|
||||
const checkpointError = props.checkpointErrorByKey[row.key];
|
||||
const displayName =
|
||||
typeof row.displayName === "string" && row.displayName.trim().length > 0
|
||||
? row.displayName.trim()
|
||||
: null;
|
||||
const displayName = normalizeOptionalString(row.displayName) ?? null;
|
||||
const trimmedLabel = normalizeOptionalString(row.label) ?? "";
|
||||
const showDisplayName = Boolean(
|
||||
displayName &&
|
||||
displayName !== row.key &&
|
||||
displayName !== (typeof row.label === "string" ? row.label.trim() : ""),
|
||||
displayName && displayName !== row.key && displayName !== trimmedLabel,
|
||||
);
|
||||
const canLink = row.kind !== "global";
|
||||
const chatUrl = canLink
|
||||
@@ -536,8 +532,8 @@ function renderRows(row: GatewaySessionRow, props: SessionsProps) {
|
||||
placeholder="(optional)"
|
||||
style="width: 100%; max-width: 140px; padding: 6px 10px; font-size: 13px; border: 1px solid var(--border); border-radius: var(--radius-sm);"
|
||||
@change=${(e: Event) => {
|
||||
const value = (e.target as HTMLInputElement).value.trim();
|
||||
props.onPatch(row.key, { label: value || null });
|
||||
const value = normalizeOptionalString((e.target as HTMLInputElement).value) ?? null;
|
||||
props.onPatch(row.key, { label: value });
|
||||
}}
|
||||
/>
|
||||
</td>
|
||||
|
||||
Reference in New Issue
Block a user