Files

36 lines
1.7 KiB
JavaScript
Raw Permalink Normal View History

import { parse as parseJsonc } from 'jsonc-parser';
const isJsonObject = (value) => value !== null && value !== undefined && Object.getPrototypeOf(value) === Object.prototype;
/**
* Append a managed OpenChamber plugin to the `plugin` list of an
* `OPENCODE_CONFIG_CONTENT` value.
*
* Existing entries are preserved; an earlier entry for the same URL is dropped
* so a restart never registers the same plugin twice. Every managed plugin
* (agent tools, system prompt optimizer, MCP reconnect) goes through this one
* merge so they compose in any order.
*
* @param {string | undefined} rawConfig the current `OPENCODE_CONFIG_CONTENT`, JSONC or unset
* @param {string} pluginUrl `file://` URL of the materialized plugin
* @param {string} purpose short noun phrase for the error message, e.g. "managed tool"
* @returns {string} the merged config as JSON
*/
export const appendManagedPlugin = (rawConfig, pluginUrl, purpose) => {
const errors = [];
const text = (rawConfig ?? '').trim();
const parsed = text ? parseJsonc(text, errors, { allowTrailingComma: true }) : {};
if (errors.length > 0 || !isJsonObject(parsed)) {
throw new Error(`OPENCODE_CONFIG_CONTENT must contain a valid JSON object before OpenChamber can inject its ${purpose}`);
}
if (parsed.plugin !== undefined && !Array.isArray(parsed.plugin)) {
throw new Error(`OPENCODE_CONFIG_CONTENT plugin must be an array before OpenChamber can inject its ${purpose}`);
}
const configured = Array.isArray(parsed.plugin) ? parsed.plugin : [];
parsed.plugin = [
...configured.filter((value) => value !== pluginUrl && (!Array.isArray(value) || value[0] !== pluginUrl)),
pluginUrl,
];
return JSON.stringify(parsed);
};