From 5f89897df1a9562dcb03795223b407e665ef3f11 Mon Sep 17 00:00:00 2001 From: Val Alexander <68980965+BunsDev@users.noreply.github.com> Date: Wed, 18 Mar 2026 00:20:14 -0500 Subject: [PATCH] plugins: dist node_modules symlink + config raw-toggle UI fix (#49490) * plugins: symlink node_modules into dist plugin dir for bare-specifier resolution * UI: fix config raw-toggle button sizing and semantic markup * Update scripts/stage-bundled-plugin-runtime.mjs Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * Update ui/src/styles/config.css Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * fix: hoist dist node_modules cleanup before existsSync guard; drop !important from config toggle --------- Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> --- scripts/stage-bundled-plugin-runtime.mjs | 20 +++++++++++++++++++ .../stage-bundled-plugin-runtime.test.ts | 6 ++++++ ui/src/styles/config.css | 7 +++++++ ui/src/ui/views/config.ts | 7 +++---- 4 files changed, 36 insertions(+), 4 deletions(-) diff --git a/scripts/stage-bundled-plugin-runtime.mjs b/scripts/stage-bundled-plugin-runtime.mjs index d6585d3191a..07fd9e958f0 100644 --- a/scripts/stage-bundled-plugin-runtime.mjs +++ b/scripts/stage-bundled-plugin-runtime.mjs @@ -88,10 +88,29 @@ function stagePluginRuntimeOverlay(sourceDir, targetDir) { function linkPluginNodeModules(params) { const runtimeNodeModulesDir = path.join(params.runtimePluginDir, "node_modules"); removePathIfExists(runtimeNodeModulesDir); + if (params.distPluginDir) { + removePathIfExists(path.join(params.distPluginDir, "node_modules")); + } if (!fs.existsSync(params.sourcePluginNodeModulesDir)) { return; } fs.symlinkSync(params.sourcePluginNodeModulesDir, runtimeNodeModulesDir, symlinkType()); + + // Runtime wrappers re-export from dist/extensions//index.js, so Node + // resolves bare-specifier dependencies relative to the dist plugin directory. + // copy-bundled-plugin-metadata removes dist node_modules; restore the link here. + if (params.distPluginDir) { + removePathIfExists(path.join(params.distPluginDir, "node_modules")); + } + if (!fs.existsSync(params.sourcePluginNodeModulesDir)) { + return; + } + fs.symlinkSync(params.sourcePluginNodeModulesDir, runtimeNodeModulesDir, symlinkType()); + + if (params.distPluginDir) { + const distNodeModulesDir = path.join(params.distPluginDir, "node_modules"); + fs.symlinkSync(params.sourcePluginNodeModulesDir, distNodeModulesDir, symlinkType()); + } } export function stageBundledPluginRuntime(params = {}) { @@ -121,6 +140,7 @@ export function stageBundledPluginRuntime(params = {}) { stagePluginRuntimeOverlay(distPluginDir, runtimePluginDir); linkPluginNodeModules({ runtimePluginDir, + distPluginDir, sourcePluginNodeModulesDir, }); } diff --git a/src/plugins/stage-bundled-plugin-runtime.test.ts b/src/plugins/stage-bundled-plugin-runtime.test.ts index fe246e8fcfe..fef9a725799 100644 --- a/src/plugins/stage-bundled-plugin-runtime.test.ts +++ b/src/plugins/stage-bundled-plugin-runtime.test.ts @@ -49,6 +49,12 @@ describe("stageBundledPluginRuntime", () => { expect(fs.realpathSync(path.join(runtimePluginDir, "node_modules"))).toBe( fs.realpathSync(sourcePluginNodeModulesDir), ); + + // dist/ also gets a node_modules symlink so bare-specifier resolution works + // from the actual code location that the runtime wrapper re-exports into + const distNodeModules = path.join(distPluginDir, "node_modules"); + expect(fs.lstatSync(distNodeModules).isSymbolicLink()).toBe(true); + expect(fs.realpathSync(distNodeModules)).toBe(fs.realpathSync(sourcePluginNodeModulesDir)); }); it("writes wrappers that forward plugin entry imports into canonical dist files", async () => { diff --git a/ui/src/styles/config.css b/ui/src/styles/config.css index f3d76ab2e6e..b091b74d67c 100644 --- a/ui/src/styles/config.css +++ b/ui/src/styles/config.css @@ -715,6 +715,13 @@ line-height: 1.55; } +.config-raw-field .config-raw-toggle { + width: 32px; + height: 32px; + padding: 6px; + min-width: 32px; +} + /* Loading State */ .config-loading { display: flex; diff --git a/ui/src/ui/views/config.ts b/ui/src/ui/views/config.ts index 1ec032e352f..7c1121e6bb8 100644 --- a/ui/src/ui/views/config.ts +++ b/ui/src/ui/views/config.ts @@ -1060,7 +1060,7 @@ export function renderConfig(props: ConfigProps) { ` : nothing } -