Skip to content

fix(config): Fail fast on plugin build config#409

Draft
dcramer wants to merge 9 commits into
mainfrom
dcramer/fix/plugin-config-fail-fast
Draft

fix(config): Fail fast on plugin build config#409
dcramer wants to merge 9 commits into
mainfrom
dcramer/fix/plugin-config-fail-fast

Conversation

@dcramer
Copy link
Copy Markdown
Member

@dcramer dcramer commented May 23, 2026

Tighten plugin and build configuration loading so malformed, unresolved, or misspelled explicit config fails at startup/build instead of being silently ignored.

This keeps the build-time Nitro virtual config path as the primary source, but only falls back to JUNIOR_PLUGIN_PACKAGES when the virtual module is genuinely absent. Other import errors now propagate instead of being mistaken for missing config.

Configured plugins.packages entries now fail if the package list is malformed, the package name is malformed, the package cannot be resolved, or the package has no plugin content. A typo should break loudly, not produce a runtime that simply lacks the requested provider. App startup now forces catalog validation for explicit plugin package/config/defaults input and rolls both plugin config and install defaults back if validation fails, so a bad startup attempt cannot leak partial process-global state. Package discovery uses a shared package-root resolver that preserves visible and ancestor node_modules paths and can resolve content-only packages through package.json, so plugin packages do not need a JS entry point just to load plugin.yaml or skills. Resolver setup failures also return through the same explicit configured-package error path instead of leaking lower-level module setup errors.

The runtime now has one plugin configuration source. The old package-only plugin global is gone, so app startup, eval setup, diagnostics, and registry loading all read package configuration from the same PluginConfig state instead of keeping package names and manifest overrides in separate mutable slots.

Build copying uses the same resolver for includeFiles and rejects malformed package names before touching filesystem paths. includeFiles itself must be an array of package subpath patterns, and entries still fail if the package, source directory, file pattern, or matched source file cannot be resolved/copied. These entries are explicit build contracts for files the bundler cannot trace, so skipping them would produce a misleadingly successful build.

Install-wide config defaults now reject malformed shapes, deep-clone values on write and read, and only treat undefined as a clear operation. That keeps nested values from mutating process-global defaults outside the validation path.

This also removes the hidden JUNIOR_EXTRA_PLUGIN_ROOTS discovery path. Tests and evals now install fixture plugins through a temporary app/plugins root and exercise the same local plugin discovery path as production apps; the eval harness also cleans up partial plugin fixture setup if later setup validation fails, so cwd is restored for subsequent evals.

@vercel
Copy link
Copy Markdown

vercel Bot commented May 23, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
junior-docs Ready Ready Preview, Comment May 23, 2026 5:39am

Request Review

@dcramer dcramer force-pushed the dcramer/fix/plugin-config-fail-fast branch from e92f3e1 to 474eefd Compare May 23, 2026 01:58
@dcramer dcramer force-pushed the dcramer/fix/plugin-config-fail-fast branch from 474eefd to d85d6dd Compare May 23, 2026 02:04
@dcramer dcramer changed the title fix(plugins): Fail fast on plugin package env config fix(config): Fail fast on plugin build config May 23, 2026
@dcramer dcramer force-pushed the dcramer/fix/plugin-config-fail-fast branch from d85d6dd to d0a226c Compare May 23, 2026 02:08
Comment thread packages/junior/src/build/copy-build-content.ts
@dcramer dcramer force-pushed the dcramer/fix/plugin-config-fail-fast branch from d0a226c to b657633 Compare May 23, 2026 02:15
@dcramer dcramer force-pushed the dcramer/fix/plugin-config-fail-fast branch from b657633 to faa1e8b Compare May 23, 2026 02:17
Do not silently ignore malformed JUNIOR_PLUGIN_PACKAGES when createApp falls back from the missing Nitro virtual config module.

Fail configured plugin package discovery when a package is missing or contains no plugin content. A typo in plugins.packages should break startup or build, not quietly load without the requested provider.

Resolve configured plugin packages through the app cwd when direct node_modules lookup misses, and copy resolved package content into server node_modules even when the physical package lives in an ancestor workspace node_modules directory.

Fail configured includeFiles entries when the package, source directory, file pattern, or matched source file cannot be copied. Resolve those packages from the app cwd so user-provided build includes do not accidentally depend on Junior's own module graph.

Remove the hidden JUNIOR_EXTRA_PLUGIN_ROOTS discovery hook. Tests and evals now install plugin fixtures through temporary app/plugins roots so they exercise the normal local plugin path.

Co-Authored-By: GPT-5 Codex <codex@openai.com>
Share package-root resolution across plugin discovery and build copying so configured packages do not need a JS entry point to load or copy plugin content.

Validate configured package names before filesystem resolution so plugin package config and includeFiles cannot be interpreted as path-shaped package names.

Co-Authored-By: GPT-5 Codex <codex@openai.com>
Return a fresh defaults object so callers cannot mutate install-wide config defaults outside the validation path.

Co-Authored-By: GPT-5 Codex <codex@openai.com>
Comment thread packages/junior-evals/evals/behavior-harness.ts Outdated
Clean up partial plugin fixture setup when eval harness initialization fails so later evals do not inherit a changed working directory.

Co-Authored-By: GPT-5 Codex <codex@openai.com>
Remove the package-only plugin global and make PluginConfig the single source for package discovery. This avoids package/config drift between app startup, eval setup, diagnostics, and registry loading.

Co-Authored-By: GPT-5 Codex <codex@openai.com>
Restore the previous plugin config if createApp fails while validating install-wide defaults. This keeps failed startup attempts from leaving partial process-global plugin state behind.

Co-Authored-By: GPT-5 Codex <codex@openai.com>
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 2a20894. Configure here.

Comment thread packages/junior/src/package-resolution.ts
Return undefined when Node package resolution setup cannot be created from an app cwd. This keeps configured plugin package failures on the explicit resolver error path instead of leaking lower-level module setup errors.

Co-Authored-By: GPT-5 Codex <codex@openai.com>
Force configured plugin packages and manifest overrides through catalog loading during app startup. Roll back plugin config and install defaults when startup validation fails so a bad app creation attempt cannot leak partial process-global state.

Also validate array-valued plugin and build config at runtime so malformed JavaScript or virtual config fails clearly instead of being iterated as strings.

Co-Authored-By: GPT-5 Codex <codex@openai.com>
Clone install-wide config defaults on write and read so nested values cannot mutate process-global defaults outside the validation path. Reject null and array defaults instead of treating malformed config as a clear operation.

Co-Authored-By: GPT-5 Codex <codex@openai.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant