Files
openclaw/src/channels/chat-meta-shared.ts
Peter Steinberger 00d8d7ead0 refactor: extract normalization core package
Extract shared normalization/coercion helpers into private @openclaw/normalization-core workspace package while preserving existing plugin SDK helper subpaths.\n\nAlso keeps direct normalization-core imports internal, wires UI/build/loader resolution, and replaces the slow PR network CodeQL lane with a fast added-line boundary scan while retaining full CodeQL for scheduled/manual runs.\n\nVerification: local moved tests, plugin SDK boundary tests, extension loader tests, agents-support shard, UI build/test, build artifacts, lint, workflow guards, autoreview, and GitHub CI passed on PR head 963d893715.
2026-05-31 01:33:00 +01:00

56 lines
2.0 KiB
TypeScript

import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce";
import type { PluginPackageChannel } from "../plugins/manifest.js";
import { listBundledChannelCatalogEntries } from "./bundled-channel-catalog-read.js";
import { CHAT_CHANNEL_ORDER, type ChatChannelId } from "./ids.js";
import { buildManifestChannelMeta } from "./plugins/channel-meta.js";
import type { ChannelMeta } from "./plugins/types.core.js";
export type ChatChannelMeta = ChannelMeta;
const CHAT_CHANNEL_ID_SET = new Set<string>(CHAT_CHANNEL_ORDER);
function toChatChannelMeta(params: {
id: ChatChannelId;
channel: PluginPackageChannel;
}): ChatChannelMeta {
const label = normalizeOptionalString(params.channel.label);
if (!label) {
throw new Error(`Missing label for bundled chat channel "${params.id}"`);
}
return buildManifestChannelMeta({
id: params.id,
channel: params.channel,
label,
selectionLabel: normalizeOptionalString(params.channel.selectionLabel) || label,
docsPath: normalizeOptionalString(params.channel.docsPath) || `/channels/${params.id}`,
docsLabel: normalizeOptionalString(params.channel.docsLabel),
blurb: normalizeOptionalString(params.channel.blurb) || "",
detailLabel: normalizeOptionalString(params.channel.detailLabel),
systemImage: normalizeOptionalString(params.channel.systemImage),
arrayFieldMode: "non-empty",
selectionDocsPrefixMode: "defined",
});
}
export function buildChatChannelMetaById(): Record<ChatChannelId, ChatChannelMeta> {
const entries = new Map<ChatChannelId, ChatChannelMeta>();
for (const entry of listBundledChannelCatalogEntries()) {
const rawId = normalizeOptionalString(entry.id);
if (!rawId || !CHAT_CHANNEL_ID_SET.has(rawId)) {
continue;
}
const id = rawId;
entries.set(
id,
toChatChannelMeta({
id,
channel: entry.channel,
}),
);
}
return Object.freeze(Object.fromEntries(entries)) as Record<ChatChannelId, ChatChannelMeta>;
}