| import fs from "node:fs"; |
| import path from "node:path"; |
| import { fileURLToPath } from "node:url"; |
| import { listChannelPluginCatalogEntries } from "../channels/plugins/catalog.js"; |
| import { listChannelPlugins } from "../channels/plugins/index.js"; |
| import { CHAT_CHANNEL_ORDER } from "../channels/registry.js"; |
| import { isTruthyEnvValue } from "../infra/env.js"; |
| import { ensurePluginRegistryLoaded } from "./plugin-registry.js"; |
|
|
| function dedupe(values: string[]): string[] { |
| const seen = new Set<string>(); |
| const resolved: string[] = []; |
| for (const value of values) { |
| if (!value || seen.has(value)) { |
| continue; |
| } |
| seen.add(value); |
| resolved.push(value); |
| } |
| return resolved; |
| } |
|
|
| let precomputedChannelOptions: string[] | null | undefined; |
|
|
| function loadPrecomputedChannelOptions(): string[] | null { |
| if (precomputedChannelOptions !== undefined) { |
| return precomputedChannelOptions; |
| } |
| try { |
| const metadataPath = path.resolve( |
| path.dirname(fileURLToPath(import.meta.url)), |
| "..", |
| "cli-startup-metadata.json", |
| ); |
| const raw = fs.readFileSync(metadataPath, "utf8"); |
| const parsed = JSON.parse(raw) as { channelOptions?: unknown }; |
| if (Array.isArray(parsed.channelOptions)) { |
| precomputedChannelOptions = dedupe( |
| parsed.channelOptions.filter((value): value is string => typeof value === "string"), |
| ); |
| return precomputedChannelOptions; |
| } |
| } catch { |
| |
| } |
| precomputedChannelOptions = null; |
| return null; |
| } |
|
|
| export function resolveCliChannelOptions(): string[] { |
| if (isTruthyEnvValue(process.env.OPENCLAW_EAGER_CHANNEL_OPTIONS)) { |
| const catalog = listChannelPluginCatalogEntries().map((entry) => entry.id); |
| const base = dedupe([...CHAT_CHANNEL_ORDER, ...catalog]); |
| ensurePluginRegistryLoaded(); |
| const pluginIds = listChannelPlugins().map((plugin) => plugin.id); |
| return dedupe([...base, ...pluginIds]); |
| } |
| const precomputed = loadPrecomputedChannelOptions(); |
| const catalog = listChannelPluginCatalogEntries().map((entry) => entry.id); |
| const base = precomputed |
| ? dedupe([...precomputed, ...catalog]) |
| : dedupe([...CHAT_CHANNEL_ORDER, ...catalog]); |
| return base; |
| } |
|
|
| export function formatCliChannelOptions(extra: string[] = []): string { |
| return [...extra, ...resolveCliChannelOptions()].join("|"); |
| } |
|
|