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>
This commit is contained in:
Val Alexander
2026-03-18 00:20:14 -05:00
committed by GitHub
parent 2c579b6ac1
commit 5f89897df1
4 changed files with 36 additions and 4 deletions

View File

@@ -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/<plugin>/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,
});
}

View File

@@ -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 () => {

View File

@@ -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;

View File

@@ -1060,7 +1060,7 @@ export function renderConfig(props: ConfigProps) {
`
: nothing
}
<label class="field config-raw-field">
<div class="field config-raw-field">
<span style="display:flex;align-items:center;gap:8px;">
Raw JSON5
${
@@ -1068,8 +1068,7 @@ export function renderConfig(props: ConfigProps) {
? html`
<span class="pill pill--sm">${sensitiveCount} secret${sensitiveCount === 1 ? "" : "s"} ${blurred ? "redacted" : "visible"}</span>
<button
class="btn btn--icon ${blurred ? "" : "active"}"
style="width:28px;height:28px;padding:0;"
class="btn btn--icon config-raw-toggle ${blurred ? "" : "active"}"
title=${
blurred ? "Reveal sensitive values" : "Hide sensitive values"
}
@@ -1098,7 +1097,7 @@ export function renderConfig(props: ConfigProps) {
props.onRawChange((e.target as HTMLTextAreaElement).value);
}}
></textarea>
</label>
</div>
`;
})()
}