diff --git a/plugin/index.ts b/plugin/index.ts index eb2748e..350fe85 100644 --- a/plugin/index.ts +++ b/plugin/index.ts @@ -508,7 +508,8 @@ export default { ensurePolicyStateLoaded(api, liveAtRegister); // Resolve plugin directory for locating sibling modules (no-reply-api/) - const pluginDir = path.dirname(new URL(import.meta.url).pathname); + // Use api.resolvePath to get the actual plugin directory in OpenClaw environment + const pluginDir = api.resolvePath("."); // Gateway lifecycle: start/stop no-reply API and moderator bot with the gateway api.on("gateway_start", () => { diff --git a/scripts/install-dirigent-openclaw.mjs b/scripts/install-dirigent-openclaw.mjs index 2623702..d5fb9c5 100755 --- a/scripts/install-dirigent-openclaw.mjs +++ b/scripts/install-dirigent-openclaw.mjs @@ -279,22 +279,25 @@ else { const delta = rec.delta || { added: {}, replaced: {}, removed: {} }; try { - // ── Handle ADDED entries: remove them ───────────────────────────────── - if (delta.added[PATH_PLUGIN_ENTRY] !== undefined) { - const plugins = getJson("plugins") || {}; - plugins.entries = plugins.entries || {}; - delete plugins.entries.dirigent; - setJson("plugins", plugins); + // ── IMPORTANT: Order matters for OpenClaw config validation ──────────── + // 1. First remove from allow (before deleting entry, otherwise validation fails) + if (delta.added[PATH_PLUGINS_ALLOW] !== undefined) { + const allowList = getJson(PATH_PLUGINS_ALLOW) || []; + const idx = allowList.indexOf("dirigent"); + if (idx !== -1) { + allowList.splice(idx, 1); + setJson(PATH_PLUGINS_ALLOW, allowList); + console.log("[dirigent] removed 'dirigent' from plugins.allow"); + } + } + + // 2. Then remove entry + if (delta.added[PATH_PLUGIN_ENTRY] !== undefined || delta.replaced[PATH_PLUGIN_ENTRY] !== undefined) { + unsetPath(PATH_PLUGIN_ENTRY); console.log("[dirigent] removed plugins.entries.dirigent"); } - if (delta.added[PATH_PROVIDER_ENTRY] !== undefined) { - const providers = getJson(PATH_PROVIDERS) || {}; - delete providers[NO_REPLY_PROVIDER_ID]; - setJson(PATH_PROVIDERS, providers); - console.log(`[dirigent] removed models.providers.${NO_REPLY_PROVIDER_ID}`); - } - + // 3. Then remove plugin path (after entry is gone) if (delta.added[PATH_PLUGINS_LOAD] !== undefined) { const plugins = getJson("plugins") || {}; const paths = plugins.load?.paths || []; @@ -307,26 +310,15 @@ else { } } - // ── Handle plugins.allow ────────────────────────────────────────────── - if (delta.added[PATH_PLUGINS_ALLOW] !== undefined) { - const allowList = getJson(PATH_PLUGINS_ALLOW) || []; - const idx = allowList.indexOf("dirigent"); - if (idx !== -1) { - allowList.splice(idx, 1); - setJson(PATH_PLUGINS_ALLOW, allowList); - console.log("[dirigent] removed 'dirigent' from plugins.allow"); - } - } - - // ── Handle REPLACED entries: restore old value ──────────────────────── - if (delta.replaced[PATH_PLUGIN_ENTRY] !== undefined) { - const plugins = getJson("plugins") || {}; - plugins.entries = plugins.entries || {}; - plugins.entries.dirigent = delta.replaced[PATH_PLUGIN_ENTRY]; - setJson("plugins", plugins); - console.log("[dirigent] restored previous plugins.entries.dirigent"); + // 4. Finally remove provider + if (delta.added[PATH_PROVIDER_ENTRY] !== undefined) { + const providers = getJson(PATH_PROVIDERS) || {}; + delete providers[NO_REPLY_PROVIDER_ID]; + setJson(PATH_PROVIDERS, providers); + console.log(`[dirigent] removed models.providers.${NO_REPLY_PROVIDER_ID}`); } + // ── Handle REPLACED provider: restore old value ─────────────────────── if (delta.replaced[PATH_PROVIDER_ENTRY] !== undefined) { const providers = getJson(PATH_PROVIDERS) || {}; providers[NO_REPLY_PROVIDER_ID] = delta.replaced[PATH_PROVIDER_ENTRY];