feat(cli): repeatable --plugin <module[@prefix]> flag (#594)#595
Merged
Conversation
Mounts app plugins straight from the CLI, no config file needed:
jss start --root ./data --public --plugin ./chat/plugin.js@/chat
parsePluginFlag splits on the last '@' followed by '/', so scoped
package specifiers parse unambiguously ('@scope/pkg/plugin.js@/app').
A value with no such separator is all module — a malformed prefix
becomes a loud import failure, never a surprise mount.
CLI entries APPEND to the config file's plugins array instead of
following the CLI-replaces-file rule: replacing would make -c plus one
--plugin silently drop the file's declared apps. Per-plugin config
objects and explicit ids stay config-file territory; entries reach the
loader untouched, so its validation (prefix, duplicate ids,
fail-loudly) applies as-is.
Unit tests for the parser; verified end-to-end: flag-only mounts and
serves, and config-file + flag mount both apps side by side.
There was a problem hiding this comment.
Pull request overview
Adds a repeatable --plugin <module[@prefix]> CLI flag to mount app plugins without requiring a config file, while preserving existing plugin-loader validation semantics by parsing only { module, prefix } and appending CLI entries to any plugins defined in a config file.
Changes:
- Add
parsePluginFlag()to parsemodule[@prefix]by splitting on the last@/. - Add repeatable
--pluginsupport inbin/jss.js, appending parsed entries toconfig.plugins. - Document the new flag in
docs/configuration.mdand add unit tests for the parsing behavior.
Reviewed changes
Copilot reviewed 3 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
src/config.js |
Adds parsePluginFlag() helper for parsing --plugin flag values. |
bin/jss.js |
Introduces repeatable --plugin option and appends parsed plugin entries to config plugins. |
test/config.test.js |
Adds unit tests covering parsePluginFlag() parsing edge cases (scoped packages, multiple @, etc.). |
docs/configuration.md |
Documents CLI usage of repeatable --plugin flag with examples and merging behavior. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Unquoted leading @ is PowerShell splatting syntax (Copilot review).
Comment on lines
+325
to
+332
| export function parsePluginFlag(value) { | ||
| const str = String(value); | ||
| const at = str.lastIndexOf('@/'); | ||
| if (at > 0) { | ||
| return { module: str.slice(0, at), prefix: str.slice(at + 1) }; | ||
| } | ||
| return { module: str }; | ||
| } |
Contributor
Author
There was a problem hiding this comment.
Good catch — changed to >= 0 in 665e2ac; '@/app' now raises the loader's "each entry needs a module" error (verified via CLI), with a unit test for the case.
…s clear no-module error (Copilot review)
melvincarvalho
added a commit
that referenced
this pull request
Jul 11, 2026
The --plugin CLI flag (#594, #595): jss start --plugin 'module[@Prefix]' mounts app plugins with no config file — repeatable, split on the last '@' followed by '/' so scoped package specifiers parse unambiguously, and a malformed or missing module fails the boot through the loader's own validation. CLI entries append to the config file's plugins array rather than replacing it, so -c plus --plugin composes. With 0.0.216's config-file forwarding this completes the CLI half of #206: plugins now load from config.json, from flags, or both. Documented in docs/configuration.md App Plugins. Remaining: pluginDataDir override so served trees don't collect .plugins/ (#592), #583 raw-body mode, #564 feature migration.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #594. Builds on #593.
What
parsePluginFlaginsrc/config.js): split on the last@followed by/— scoped packages parse unambiguously; a value with no separator is all module, so a malformed prefix (./p.js@chat) becomes a loud import failure rather than a surprise mount.pluginsarray. The usual CLI-replaces-file rule would make-c+ one--pluginsilently drop the file's declared apps — the exact silent-missing-app mode the loader refuses.config/idstay config-file territory. Entries reachloadPluginsuntouched, so prefix validation, duplicate-id rejection, and fail-loud imports apply unchanged.docs/configuration.md.Tests
parsePluginFlag(plain, scoped, multiple@, missing-slash prefix); config + plugins suites: 32/32 pass.-c config.json+--pluginmounts both apps side by side (append verified).Sets up the servejss side of #592's plan: jsserve can now forward
--pluginverbatim and stay a pure flag translator.