Skip to content

@docmd/plugin-ai: assistant: false does not disable the AI widget (getAssets ignores the disable flags) #209

Description

@adrianbaena

Summary

Setting plugins.ai.assistant to false in docmd.config.json does not remove the AI Assistant widget from the built site. The floating trigger still appears on every page.

Environment

  • @docmd/core: 0.9.3
  • @docmd/plugin-ai: 0.9.3 (bundled)
  • Build engine: js (default)
  • OS: Linux

Reproduction

docmd.config.json:

{
  "title": "My Docs",
  "src": "docs",
  "plugins": {
    "ai": {
      "assistant": false
    }
  }
}
  1. npx @docmd/core build
  2. Open any generated page, e.g. site/index.html

Expected: no AI Assistant assets or widget on the page.

Actual: the build log even prints [ DONE ] [ai] AI Assistant plugin ready for site., and the generated HTML still contains:

<link rel="stylesheet" href="./assets/css/docmd-ai.css" >
<script src="./assets/js/docmd-ai.js" ></script>

assets/js/docmd-ai.js and assets/css/docmd-ai.css are still emitted, and the widget still renders and self-mounts in the browser.

Root cause

In packages/plugin-ai/src/index.ts (compiled to dist/index.js), two separate hooks handle the AI plugin's output:

  1. generateScripts(config, _options)correctly checks the disable flags and returns empty HTML when disabled:

    export function generateScripts(config, _options) {
        const pluginOptions = config._aiConfig || (config.plugins && config.plugins.ai) || config.ai || {};
        if (pluginOptions.enabled === false || pluginOptions.assistant === false || pluginOptions.chat === false) {
            return { headScriptsHtml: '', bodyScriptsHtml: '' };
        }
        ...
    }
  2. getAssets(_config) — registers the docmd-ai.js / docmd-ai.css assets for injection into every page, but has no such check at all:

    export function getAssets(_config) {
        const distDir = path.resolve(__dirname, '..', 'dist', 'client');
        const jsPath = path.join(distDir, 'index.js');
        const cssPath = path.join(distDir, 'ai.css');
        const assets = [];
        if (nativeFs.existsSync(jsPath)) {
            assets.push({ src: jsPath, dest: 'assets/js/docmd-ai.js', type: 'js', location: 'body' });
        }
        ...
        return assets;
    }

    So the <script>/<link> tags are unconditionally injected regardless of config.

  3. Even if step 2 were fixed, the client bundle itself (dist/client/index.ts) has a second problem: it self-mounts unconditionally.

    var DocmdAIAssistantUI = class {
      constructor() {
        ...
        if (typeof document !== "undefined") {
          this.mount(); // <-- always runs, no check against cfg.assistant/enabled
        }
      }
    };
    document.addEventListener("DOMContentLoaded", () => new DocmdAIAssistantUI());

    Since generateScripts (correctly) omits window.__docmd_ai_config when disabled, the constructor reads window.__docmd_ai_config || {} and proceeds to mount the widget with an empty config anyway (rather than treating a missing/disabled config as "do not mount").

Suggested fix

  • getAssets() should apply the same pluginOptions.enabled === false || pluginOptions.assistant === false || pluginOptions.chat === false check that generateScripts() already uses, and return [] when disabled (note: getAssets receives the plugin's own resolved options object directly as its single argument — not the full site config — per the call site in @docmd/api's hooks.js: hooks.assets.push(async () => (await safeCall('getAssets', name, fn, options)) || [])).
  • Defensively, DocmdAIAssistantUI's constructor should also bail out early (skip this.mount()) when window.__docmd_ai_config is absent or explicitly disabled, instead of assuming an empty config means "enabled with defaults".

Workaround

We patched getAssets() locally with bun patch to add the missing check, mirroring generateScripts(). This fully removes the widget from the build. Happy to open a PR with this fix if useful — just let me know which of @docmd/plugin-ai / docmd-assistant should own the guard.

Verification

After patching, npx @docmd/core build no longer emits docmd-ai.js/docmd-ai.css, and npx @docmd/core validate still passes with no other regressions.

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions